polen 0.11.0-next.25 → 0.11.0-next.27

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 (230) hide show
  1. package/build/api/config/input.d.ts +183 -0
  2. package/build/api/config/input.d.ts.map +1 -1
  3. package/build/api/config/input.js +2 -0
  4. package/build/api/config/input.js.map +1 -1
  5. package/build/api/config/normalized.d.ts +297 -0
  6. package/build/api/config/normalized.d.ts.map +1 -1
  7. package/build/api/config/normalized.js +47 -0
  8. package/build/api/config/normalized.js.map +1 -1
  9. package/build/api/config-template/template.d.ts +81 -0
  10. package/build/api/config-template/template.d.ts.map +1 -1
  11. package/build/api/config-template/template.js +18 -1
  12. package/build/api/config-template/template.js.map +1 -1
  13. package/build/api/examples/scanner.d.ts.map +1 -1
  14. package/build/api/examples/scanner.js +11 -0
  15. package/build/api/examples/scanner.js.map +1 -1
  16. package/build/api/examples/schemas/catalog.d.ts +36 -0
  17. package/build/api/examples/schemas/catalog.d.ts.map +1 -1
  18. package/build/api/examples/schemas/example/example.d.ts +37 -0
  19. package/build/api/examples/schemas/example/example.d.ts.map +1 -1
  20. package/build/api/examples/schemas/example/example.js +5 -0
  21. package/build/api/examples/schemas/example/example.js.map +1 -1
  22. package/build/api/reference/$.d.ts +4 -0
  23. package/build/api/reference/$.d.ts.map +1 -0
  24. package/build/api/reference/$.js +4 -0
  25. package/build/api/reference/$.js.map +1 -0
  26. package/build/api/reference/catalog.d.ts +69 -0
  27. package/build/api/reference/catalog.d.ts.map +1 -0
  28. package/build/api/reference/catalog.js +44 -0
  29. package/build/api/reference/catalog.js.map +1 -0
  30. package/build/api/reference/config.d.ts +616 -0
  31. package/build/api/reference/config.d.ts.map +1 -0
  32. package/build/api/reference/config.js +162 -0
  33. package/build/api/reference/config.js.map +1 -0
  34. package/build/api/reference/scanner.d.ts +26 -0
  35. package/build/api/reference/scanner.d.ts.map +1 -0
  36. package/build/api/reference/scanner.js +27 -0
  37. package/build/api/reference/scanner.js.map +1 -0
  38. package/build/lib/grafaid/schema/format-default-value.d.ts +11 -0
  39. package/build/lib/grafaid/schema/format-default-value.d.ts.map +1 -0
  40. package/build/lib/grafaid/schema/format-default-value.js +20 -0
  41. package/build/lib/grafaid/schema/format-default-value.js.map +1 -0
  42. package/build/lib/grafaid/schema/schema.d.ts +1 -0
  43. package/build/lib/grafaid/schema/schema.d.ts.map +1 -1
  44. package/build/lib/grafaid/schema/schema.js +1 -0
  45. package/build/lib/grafaid/schema/schema.js.map +1 -1
  46. package/build/template/components/ArgumentAnnotation.d.ts +2 -1
  47. package/build/template/components/ArgumentAnnotation.d.ts.map +1 -1
  48. package/build/template/components/ArgumentAnnotation.js +14 -4
  49. package/build/template/components/ArgumentAnnotation.js.map +1 -1
  50. package/build/template/components/ArgumentListAnnotation.d.ts +1 -0
  51. package/build/template/components/ArgumentListAnnotation.d.ts.map +1 -1
  52. package/build/template/components/ArgumentListAnnotation.js +21 -8
  53. package/build/template/components/ArgumentListAnnotation.js.map +1 -1
  54. package/build/template/components/Changelog/groups/FieldArgument.d.ts.map +1 -1
  55. package/build/template/components/Changelog/groups/FieldArgument.js +0 -1
  56. package/build/template/components/Changelog/groups/FieldArgument.js.map +1 -1
  57. package/build/template/components/CodeBlock.d.ts.map +1 -1
  58. package/build/template/components/CodeBlock.js +1 -1
  59. package/build/template/components/CodeBlock.js.map +1 -1
  60. package/build/template/components/Description.js +1 -1
  61. package/build/template/components/Description.js.map +1 -1
  62. package/build/template/components/ExampleLink.d.ts.map +1 -1
  63. package/build/template/components/ExampleLink.js +2 -1
  64. package/build/template/components/ExampleLink.js.map +1 -1
  65. package/build/template/components/Field.d.ts +2 -0
  66. package/build/template/components/Field.d.ts.map +1 -1
  67. package/build/template/components/Field.js +42 -4
  68. package/build/template/components/Field.js.map +1 -1
  69. package/build/template/components/FieldList.d.ts +2 -1
  70. package/build/template/components/FieldList.d.ts.map +1 -1
  71. package/build/template/components/FieldList.js +14 -3
  72. package/build/template/components/FieldList.js.map +1 -1
  73. package/build/template/components/FieldListSection.d.ts.map +1 -1
  74. package/build/template/components/FieldListSection.js +6 -1
  75. package/build/template/components/FieldListSection.js.map +1 -1
  76. package/build/template/components/GraphQLDocument.d.ts.map +1 -1
  77. package/build/template/components/GraphQLDocument.js +2 -1
  78. package/build/template/components/GraphQLDocument.js.map +1 -1
  79. package/build/template/components/GraphQLInteractive/GraphQLInteractive.d.ts +2 -0
  80. package/build/template/components/GraphQLInteractive/GraphQLInteractive.d.ts.map +1 -1
  81. package/build/template/components/GraphQLInteractive/GraphQLInteractive.js +4 -3
  82. package/build/template/components/GraphQLInteractive/GraphQLInteractive.js.map +1 -1
  83. package/build/template/components/GraphQLInteractive/lib/parser.d.ts +2 -2
  84. package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -1
  85. package/build/template/components/GraphQLInteractive/lib/parser.js +17 -12
  86. package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -1
  87. package/build/template/components/IAPIndicator.d.ts +12 -0
  88. package/build/template/components/IAPIndicator.d.ts.map +1 -0
  89. package/build/template/components/IAPIndicator.js +21 -0
  90. package/build/template/components/IAPIndicator.js.map +1 -0
  91. package/build/template/components/Link.d.ts +1 -2
  92. package/build/template/components/Link.d.ts.map +1 -1
  93. package/build/template/components/Link.js +5 -2
  94. package/build/template/components/Link.js.map +1 -1
  95. package/build/template/components/NamedType.d.ts.map +1 -1
  96. package/build/template/components/NamedType.js +9 -5
  97. package/build/template/components/NamedType.js.map +1 -1
  98. package/build/template/components/ReferenceLink.d.ts +3 -2
  99. package/build/template/components/ReferenceLink.d.ts.map +1 -1
  100. package/build/template/components/ReferenceLink.js +5 -3
  101. package/build/template/components/ReferenceLink.js.map +1 -1
  102. package/build/template/components/TypeAnnotation.d.ts +2 -0
  103. package/build/template/components/TypeAnnotation.d.ts.map +1 -1
  104. package/build/template/components/TypeAnnotation.js +4 -4
  105. package/build/template/components/TypeAnnotation.js.map +1 -1
  106. package/build/template/components/ViewModeToggle.d.ts +3 -0
  107. package/build/template/components/ViewModeToggle.d.ts.map +1 -0
  108. package/build/template/components/ViewModeToggle.js +9 -0
  109. package/build/template/components/ViewModeToggle.js.map +1 -0
  110. package/build/template/components/graphql/type-link.d.ts +2 -0
  111. package/build/template/components/graphql/type-link.d.ts.map +1 -1
  112. package/build/template/components/graphql/type-link.js +17 -4
  113. package/build/template/components/graphql/type-link.js.map +1 -1
  114. package/build/template/components/home/PlaygroundPreview.d.ts.map +1 -1
  115. package/build/template/components/home/PlaygroundPreview.js +3 -2
  116. package/build/template/components/home/PlaygroundPreview.js.map +1 -1
  117. package/build/template/components/sidebar/SidebarItem.d.ts.map +1 -1
  118. package/build/template/components/sidebar/SidebarItem.js +18 -5
  119. package/build/template/components/sidebar/SidebarItem.js.map +1 -1
  120. package/build/template/contexts/ReferenceConfigContext.d.ts +16 -0
  121. package/build/template/contexts/ReferenceConfigContext.d.ts.map +1 -0
  122. package/build/template/contexts/ReferenceConfigContext.js +14 -0
  123. package/build/template/contexts/ReferenceConfigContext.js.map +1 -0
  124. package/build/template/contexts/ViewModeContext.d.ts +14 -0
  125. package/build/template/contexts/ViewModeContext.d.ts.map +1 -0
  126. package/build/template/contexts/ViewModeContext.js +40 -0
  127. package/build/template/contexts/ViewModeContext.js.map +1 -0
  128. package/build/template/hooks/use-examples.d.ts +3 -0
  129. package/build/template/hooks/use-examples.d.ts.map +1 -1
  130. package/build/template/hooks/useAlignedColumns.d.ts +10 -0
  131. package/build/template/hooks/useAlignedColumns.d.ts.map +1 -0
  132. package/build/template/hooks/useAlignedColumns.js +17 -0
  133. package/build/template/hooks/useAlignedColumns.js.map +1 -0
  134. package/build/template/routes/examples/_.d.ts +9 -0
  135. package/build/template/routes/examples/_.d.ts.map +1 -1
  136. package/build/template/routes/examples/_index.d.ts +6 -0
  137. package/build/template/routes/examples/_index.d.ts.map +1 -1
  138. package/build/template/routes/examples/name.d.ts +9 -0
  139. package/build/template/routes/examples/name.d.ts.map +1 -1
  140. package/build/template/routes/examples/name.js +6 -2
  141. package/build/template/routes/examples/name.js.map +1 -1
  142. package/build/template/routes/reference.d.ts.map +1 -1
  143. package/build/template/routes/reference.js +37 -10
  144. package/build/template/routes/reference.js.map +1 -1
  145. package/build/vite/plugins/core.d.ts.map +1 -1
  146. package/build/vite/plugins/core.js +6 -0
  147. package/build/vite/plugins/core.js.map +1 -1
  148. package/build/vite/plugins/examples.d.ts.map +1 -1
  149. package/build/vite/plugins/examples.js +10 -1
  150. package/build/vite/plugins/examples.js.map +1 -1
  151. package/build/vite/plugins/index.d.ts +1 -0
  152. package/build/vite/plugins/index.d.ts.map +1 -1
  153. package/build/vite/plugins/index.js +1 -0
  154. package/build/vite/plugins/index.js.map +1 -1
  155. package/build/vite/plugins/navbar.d.ts.map +1 -1
  156. package/build/vite/plugins/navbar.js +3 -1
  157. package/build/vite/plugins/navbar.js.map +1 -1
  158. package/build/vite/plugins/reference.d.ts +19 -0
  159. package/build/vite/plugins/reference.d.ts.map +1 -0
  160. package/build/vite/plugins/reference.js +96 -0
  161. package/build/vite/plugins/reference.js.map +1 -0
  162. package/package.json +1 -7
  163. package/src/api/config/input.ts +2 -0
  164. package/src/api/config/normalized.ts +54 -0
  165. package/src/api/config-template/template.ts +18 -1
  166. package/src/api/examples/scanner.ts +14 -0
  167. package/src/api/examples/schemas/example/example.ts +6 -0
  168. package/src/api/reference/$.ts +3 -0
  169. package/src/api/reference/catalog.ts +55 -0
  170. package/src/api/reference/config.ts +193 -0
  171. package/src/api/reference/scanner.ts +53 -0
  172. package/src/lib/grafaid/schema/format-default-value.ts +22 -0
  173. package/src/lib/grafaid/schema/schema.ts +2 -0
  174. package/src/template/components/ArgumentAnnotation.tsx +58 -9
  175. package/src/template/components/ArgumentListAnnotation.tsx +50 -17
  176. package/src/template/components/Changelog/groups/FieldArgument.tsx +0 -1
  177. package/src/template/components/CodeBlock.tsx +1 -0
  178. package/src/template/components/Description.tsx +1 -1
  179. package/src/template/components/ExampleLink.tsx +2 -1
  180. package/src/template/components/Field.tsx +148 -20
  181. package/src/template/components/FieldList.tsx +28 -13
  182. package/src/template/components/FieldListSection.tsx +12 -2
  183. package/src/template/components/GraphQLDocument.tsx +2 -0
  184. package/src/template/components/GraphQLInteractive/GraphQLInteractive.tsx +6 -1
  185. package/src/template/components/GraphQLInteractive/lib/parser.ts +16 -3
  186. package/src/template/components/IAPIndicator.tsx +73 -0
  187. package/src/template/components/Link.tsx +9 -3
  188. package/src/template/components/NamedType.tsx +54 -28
  189. package/src/template/components/ReferenceLink.tsx +17 -10
  190. package/src/template/components/TypeAnnotation.tsx +17 -5
  191. package/src/template/components/ViewModeToggle.tsx +27 -0
  192. package/src/template/components/graphql/type-link.tsx +52 -9
  193. package/src/template/components/home/PlaygroundPreview.tsx +3 -0
  194. package/src/template/components/sidebar/SidebarItem.tsx +21 -5
  195. package/src/template/contexts/ReferenceConfigContext.tsx +37 -0
  196. package/src/template/contexts/ViewModeContext.tsx +64 -0
  197. package/src/template/hooks/useAlignedColumns.ts +19 -0
  198. package/src/template/routes/examples/name.tsx +13 -1
  199. package/src/template/routes/reference.tsx +67 -23
  200. package/src/types/virtual-modules.d.ts +5 -0
  201. package/src/vite/plugins/core.ts +6 -0
  202. package/src/vite/plugins/examples.ts +12 -0
  203. package/src/vite/plugins/index.ts +1 -0
  204. package/src/vite/plugins/navbar.ts +4 -1
  205. package/src/vite/plugins/reference.ts +130 -0
  206. package/build/lib/extensible-data/$.d.ts +0 -2
  207. package/build/lib/extensible-data/$.d.ts.map +0 -1
  208. package/build/lib/extensible-data/$.js +0 -2
  209. package/build/lib/extensible-data/$.js.map +0 -1
  210. package/build/lib/extensible-data/extensible-data.d.ts +0 -17
  211. package/build/lib/extensible-data/extensible-data.d.ts.map +0 -1
  212. package/build/lib/extensible-data/extensible-data.js +0 -24
  213. package/build/lib/extensible-data/extensible-data.js.map +0 -1
  214. package/build/lib/vite-plugin-reactive-data/$.d.ts +0 -2
  215. package/build/lib/vite-plugin-reactive-data/$.d.ts.map +0 -1
  216. package/build/lib/vite-plugin-reactive-data/$.js +0 -2
  217. package/build/lib/vite-plugin-reactive-data/$.js.map +0 -1
  218. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts +0 -32
  219. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts.map +0 -1
  220. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js +0 -85
  221. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js.map +0 -1
  222. package/build/template/components/ArgumentList.d.ts +0 -6
  223. package/build/template/components/ArgumentList.d.ts.map +0 -1
  224. package/build/template/components/ArgumentList.js +0 -9
  225. package/build/template/components/ArgumentList.js.map +0 -1
  226. package/src/lib/extensible-data/$.ts +0 -1
  227. package/src/lib/extensible-data/extensible-data.ts +0 -38
  228. package/src/lib/vite-plugin-reactive-data/$.ts +0 -1
  229. package/src/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.ts +0 -124
  230. package/src/template/components/ArgumentList.tsx +0 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polen",
3
- "version": "0.11.0-next.25",
3
+ "version": "0.11.0-next.27",
4
4
  "type": "module",
5
5
  "description": "A framework for delightful GraphQL developer portals",
6
6
  "author": {
@@ -217,9 +217,6 @@
217
217
  "#lib/vite-plugin-mdx": {
218
218
  "default": "./build/lib/vite-plugin-mdx/$.js"
219
219
  },
220
- "#lib/vite-plugin-reactive-data": {
221
- "default": "./build/lib/vite-plugin-reactive-data/$.js"
222
- },
223
220
  "#lib/vite-plugins": {
224
221
  "default": "./build/lib/vite-plugins/$.js"
225
222
  },
@@ -298,7 +295,6 @@
298
295
  "@vitejs/plugin-react": "^4.7.0",
299
296
  "@vitejs/plugin-react-oxc": "^0.3.0",
300
297
  "@vltpkg/semver": "0.0.0-18",
301
- "@vue/reactivity": "^3.5.17",
302
298
  "@wollybeard/kit": "^0.41.0",
303
299
  "@wollybeard/projector": "^0.3.0",
304
300
  "ansis": "^4.1.0",
@@ -366,7 +362,6 @@
366
362
  "@types/node": "^24.1.0",
367
363
  "@types/react": "^19.1.8",
368
364
  "@types/react-dom": "^19.1.6",
369
- "@types/semver": "^7.7.0",
370
365
  "dprint": "^0.50.1",
371
366
  "dripip": "^0.10.0",
372
367
  "fast-check": "^4.2.0",
@@ -376,7 +371,6 @@
376
371
  "jsdom": "^26.1.0",
377
372
  "playwright": "1.54.1",
378
373
  "publint": "^0.3.12",
379
- "semver": "^7.7.2",
380
374
  "strip-ansi": "^7.1.0",
381
375
  "typescript": "^5.8.3",
382
376
  "vite-tsconfig-paths": "^5.1.4",
@@ -1,4 +1,5 @@
1
1
  import { ExamplesConfig } from '#api/examples/config'
2
+ import { ReferenceConfig } from '#api/reference/config'
2
3
  import { ConfigSchema } from '#api/schema/config-schema'
3
4
  import { Vite } from '#dep/vite/index'
4
5
  import { spreadShallow } from '#lib/kit-temp'
@@ -306,6 +307,7 @@ export const ConfigInput = S.Struct({
306
307
  */
307
308
  description: S.optional(S.String),
308
309
  schema: S.optional(ConfigSchema),
310
+ reference: S.optional(ReferenceConfig),
309
311
  examples: S.optional(ExamplesConfig),
310
312
  templateVariables: S.optional(TemplateVariables),
311
313
  home: S.optional(HomeConfig),
@@ -1,4 +1,5 @@
1
1
  import { ExamplesConfig } from '#api/examples/config'
2
+ import { DescriptionsView, ReferenceConfigObject } from '#api/reference/config'
2
3
  import { ConfigSchema } from '#api/schema/config-schema'
3
4
  import { Typings } from '#api/typings/$'
4
5
  import { DirectedFilter } from '#lib/directed-filter/$'
@@ -11,6 +12,24 @@ import { Effect } from 'effect'
11
12
  import type { WritableDeep } from 'type-fest'
12
13
  import { BuildArchitecture, ConfigInput } from './input.js'
13
14
 
15
+ // ============================================================================
16
+ // Normalized Reference Config
17
+ // ============================================================================
18
+
19
+ /**
20
+ * Normalized reference configuration where all optional fields have defaults applied.
21
+ */
22
+ const NormalizedReferenceConfig = S.extend(
23
+ ReferenceConfigObject.pipe(S.omit('descriptionsView', 'nullabilityRendering')),
24
+ S.Struct({
25
+ descriptionsView: S.Struct({
26
+ defaultMode: S.Literal('compact', 'expanded'),
27
+ showControl: S.Boolean,
28
+ }),
29
+ nullabilityRendering: S.Literal('questionMark', 'bangMark'),
30
+ }),
31
+ )
32
+
14
33
  // ============================================================================
15
34
  // DirectedFilter for Strings
16
35
  // ============================================================================
@@ -320,6 +339,11 @@ export const Config = S.Struct({
320
339
  */
321
340
  schema: ConfigSchema,
322
341
 
342
+ /**
343
+ * Reference documentation configuration with resolved defaults.
344
+ */
345
+ reference: NormalizedReferenceConfig,
346
+
323
347
  /**
324
348
  * Examples configuration with resolved defaults.
325
349
  */
@@ -487,6 +511,13 @@ const getConfigInputDefaults = (baseRootDirPath: string): Config => ({
487
511
  },
488
512
  },
489
513
  schema: {},
514
+ reference: {
515
+ descriptionsView: {
516
+ defaultMode: 'expanded',
517
+ showControl: true,
518
+ },
519
+ nullabilityRendering: 'bangMark',
520
+ },
490
521
  examples: {
491
522
  display: 'all',
492
523
  },
@@ -658,6 +689,29 @@ export const normalizeInput = (
658
689
  configInput_as_writeable.warnings.interactiveWithoutSchema.enabled
659
690
  }
660
691
 
692
+ // Process reference configuration
693
+ if (configInput_as_writeable?.reference) {
694
+ const referenceInput = configInput_as_writeable.reference
695
+ // The schema transform handles boolean shorthand, so we always get an object here
696
+ if (referenceInput.enabled !== undefined) {
697
+ config.reference.enabled = referenceInput.enabled
698
+ }
699
+ if (referenceInput.descriptionsView) {
700
+ if (referenceInput.descriptionsView.defaultMode !== undefined) {
701
+ config.reference.descriptionsView.defaultMode = referenceInput.descriptionsView.defaultMode
702
+ }
703
+ if (referenceInput.descriptionsView.showControl !== undefined) {
704
+ config.reference.descriptionsView.showControl = referenceInput.descriptionsView.showControl
705
+ }
706
+ }
707
+ if (referenceInput.nullabilityRendering !== undefined) {
708
+ config.reference.nullabilityRendering = referenceInput.nullabilityRendering
709
+ }
710
+ if (referenceInput.diagnostics) {
711
+ config.reference.diagnostics = referenceInput.diagnostics
712
+ }
713
+ }
714
+
661
715
  // Process examples configuration
662
716
  if (configInput_as_writeable?.examples) {
663
717
  const examplesInput = configInput_as_writeable.examples
@@ -1,5 +1,6 @@
1
1
  import type { Api } from '#api/$'
2
2
  import { ExamplesConfigObject } from '#api/examples/config'
3
+ import { ReferenceConfigObject } from '#api/reference/config'
3
4
  import { ConfigSchema } from '#api/schema/config-schema'
4
5
  import type { Catalog } from '#lib/catalog/$'
5
6
  import { S } from '#lib/kit-temp/effect'
@@ -16,6 +17,13 @@ export const resolve = (config: Config, data: {
16
17
  ...config.schema,
17
18
  enabled: Boolean(config.schema.enabled ?? data.schemas),
18
19
  },
20
+ reference: {
21
+ ...config.reference,
22
+ // Reference is enabled if explicitly enabled OR if schemas exist (unless explicitly disabled)
23
+ enabled: Boolean(config.reference.enabled ?? data.schemas),
24
+ descriptionsView: config.reference.descriptionsView,
25
+ nullabilityRendering: config.reference.nullabilityRendering,
26
+ },
19
27
  examples: {
20
28
  ...config.examples,
21
29
  enabled: Boolean(config.examples.enabled ?? (data.examples && data.examples.examples.length > 0)),
@@ -33,7 +41,7 @@ export const resolve = (config: Config, data: {
33
41
  * that control feature enablement have been resolved to concrete values.
34
42
  */
35
43
  export const TemplateConfig = S.extend(
36
- Config.pipe(S.omit('_input', 'schema', 'examples')),
44
+ Config.pipe(S.omit('_input', 'schema', 'reference', 'examples')),
37
45
  S.Struct({
38
46
  schema: S.extend(
39
47
  ConfigSchema.pipe(S.omit('enabled')),
@@ -41,6 +49,15 @@ export const TemplateConfig = S.extend(
41
49
  enabled: S.Boolean,
42
50
  }),
43
51
  ),
52
+ reference: S.Struct({
53
+ enabled: S.Boolean,
54
+ descriptionsView: S.Struct({
55
+ defaultMode: S.Literal('compact', 'expanded'),
56
+ showControl: S.Boolean,
57
+ }),
58
+ nullabilityRendering: S.Literal('questionMark', 'bangMark'),
59
+ diagnostics: S.optional(S.Unknown), // From ReferenceConfigObject
60
+ }),
44
61
  examples: S.extend(
45
62
  ExamplesConfigObject.pipe(S.omit('enabled')),
46
63
  S.Struct({
@@ -330,6 +330,20 @@ export const scan = (
330
330
  }
331
331
 
332
332
  if (example) {
333
+ // Check for description.md or description.mdx file
334
+ const descriptionMdPath = Path.join(options.dir, `${name}.md`)
335
+ const descriptionMdxPath = Path.join(options.dir, `${name}.mdx`)
336
+
337
+ const descriptionPath = (yield* fs.exists(descriptionMdPath))
338
+ ? descriptionMdPath
339
+ : (yield* fs.exists(descriptionMdxPath))
340
+ ? descriptionMdxPath
341
+ : null
342
+
343
+ if (descriptionPath) {
344
+ example = { ...example, description: { path: descriptionPath } }
345
+ }
346
+
333
347
  examples.push(example)
334
348
  // Generate diagnostics for this example
335
349
  diagnostics.push(...lintFileLayout(example, options.schemaCatalog))
@@ -26,6 +26,12 @@ export const Example = S.Struct({
26
26
  * The document content, which can be unversioned, versioned, or partially versioned.
27
27
  */
28
28
  document: Document.Document,
29
+
30
+ /**
31
+ * Optional description file for this example.
32
+ * Points to a markdown/MDX file that describes the example.
33
+ */
34
+ description: S.optional(S.Struct({ path: S.String })),
29
35
  }).annotations({
30
36
  identifier: 'Example',
31
37
  description: 'A GraphQL example that contains a document with optional versioning support',
@@ -0,0 +1,3 @@
1
+ export * as Catalog from './catalog.js'
2
+ export * as Config from './config.js'
3
+ export * from './scanner.js'
@@ -0,0 +1,55 @@
1
+ import { S } from '#lib/kit-temp/effect'
2
+
3
+ // ============================================================================
4
+ // Schema and Type
5
+ // ============================================================================
6
+
7
+ export const Catalog = S.Struct({
8
+ /**
9
+ * Optional index file metadata for custom reference landing page.
10
+ * If not provided, the app will redirect to the Query type.
11
+ */
12
+ index: S.optional(S.Struct({
13
+ /**
14
+ * Path to the index.md or index.mdx file
15
+ */
16
+ path: S.String,
17
+ })),
18
+ }).annotations({
19
+ identifier: 'ReferenceCatalog',
20
+ description: 'A catalog of reference documentation metadata',
21
+ })
22
+
23
+ export type Catalog = S.Schema.Type<typeof Catalog>
24
+
25
+ // ============================================================================
26
+ // Constructors
27
+ // ============================================================================
28
+
29
+ export const make = Catalog.make
30
+
31
+ // ============================================================================
32
+ // Type Guards
33
+ // ============================================================================
34
+
35
+ export const is = S.is(Catalog)
36
+
37
+ // ============================================================================
38
+ // State Predicates
39
+ // ============================================================================
40
+
41
+ /**
42
+ * Check if the catalog has a custom index page
43
+ */
44
+ export const hasIndex = (catalog: Catalog): boolean => {
45
+ return catalog.index !== undefined
46
+ }
47
+
48
+ // ============================================================================
49
+ // Codec
50
+ // ============================================================================
51
+
52
+ export const decode = S.decode(Catalog)
53
+ export const decodeSync = S.decodeSync(Catalog)
54
+ export const encode = S.encode(Catalog)
55
+ export const encodeSync = S.encodeSync(Catalog)
@@ -0,0 +1,193 @@
1
+ import { Diagnostic } from '#lib/diagnostic/$'
2
+ import { S } from '#lib/kit-temp/effect'
3
+
4
+ // ============================================================================
5
+ // Schema - Reference Diagnostics
6
+ // ============================================================================
7
+
8
+ /**
9
+ * Diagnostic controls for reference documentation.
10
+ */
11
+ export const ReferenceDiagnostics = S.Struct({
12
+ /**
13
+ * Control diagnostics for missing or invalid reference content.
14
+ *
15
+ * @default true (info in dev, warning in build)
16
+ */
17
+ validation: S.optional(S.Union(S.Boolean, Diagnostic.Control)),
18
+ }).annotations({
19
+ identifier: 'ReferenceDiagnostics',
20
+ description: 'Diagnostic controls for reference documentation',
21
+ })
22
+
23
+ export type ReferenceDiagnostics = S.Schema.Type<typeof ReferenceDiagnostics>
24
+
25
+ // ============================================================================
26
+ // Schema - Descriptions View
27
+ // ============================================================================
28
+
29
+ /**
30
+ * Configuration for how descriptions are displayed in reference documentation.
31
+ */
32
+ export const DescriptionsView = S.Struct({
33
+ /**
34
+ * Default view mode for descriptions.
35
+ * - 'expanded': Show full descriptions (default)
36
+ * - 'compact': Show condensed view
37
+ *
38
+ * @default 'expanded'
39
+ */
40
+ defaultMode: S.optional(S.Literal('compact', 'expanded')),
41
+
42
+ /**
43
+ * Whether to show the view mode toggle control.
44
+ * Allows users to switch between compact and expanded views.
45
+ *
46
+ * @default true
47
+ */
48
+ showControl: S.optional(S.Boolean),
49
+ }).annotations({
50
+ identifier: 'DescriptionsView',
51
+ description: 'Configuration for descriptions display in reference documentation',
52
+ })
53
+
54
+ export type DescriptionsView = S.Schema.Type<typeof DescriptionsView>
55
+
56
+ // ============================================================================
57
+ // Schema - Reference Config
58
+ // ============================================================================
59
+
60
+ export const ReferenceConfigObject = S.Struct({
61
+ /**
62
+ * Control whether the reference documentation is enabled.
63
+ * - true: Always enabled (show in nav even if no schema exists)
64
+ * - false: Always disabled (hide even if schema exists)
65
+ * - undefined: Auto-detect based on schema presence (default behavior)
66
+ *
67
+ * @default undefined (auto-detect based on schema presence)
68
+ * @example
69
+ * // Always show reference section
70
+ * reference: { enabled: true }
71
+ *
72
+ * @example
73
+ * // Never show reference
74
+ * reference: { enabled: false }
75
+ *
76
+ * @example
77
+ * // Auto-detect based on schema (default)
78
+ * reference: { }
79
+ */
80
+ enabled: S.optional(S.Boolean),
81
+
82
+ /**
83
+ * Configuration for how descriptions are displayed.
84
+ *
85
+ * @example
86
+ * // Use compact mode by default
87
+ * descriptionsView: {
88
+ * defaultMode: 'compact'
89
+ * }
90
+ *
91
+ * @example
92
+ * // Hide the view mode toggle
93
+ * descriptionsView: {
94
+ * showControl: false
95
+ * }
96
+ */
97
+ descriptionsView: S.optional(DescriptionsView),
98
+
99
+ /**
100
+ * Configuration for how field nullability is rendered.
101
+ * - 'bangMark': Show '!' after non-nullable types (GraphQL style)
102
+ * - 'questionMark': Show '?' after nullable field names (TypeScript style)
103
+ *
104
+ * @default 'bangMark'
105
+ * @example
106
+ * // Use TypeScript-style nullability rendering
107
+ * nullabilityRendering: 'questionMark'
108
+ */
109
+ nullabilityRendering: S.optional(S.Literal('questionMark', 'bangMark')),
110
+
111
+ /**
112
+ * Diagnostic controls for reference documentation.
113
+ *
114
+ * @example
115
+ * // Enable all diagnostics with defaults
116
+ * diagnostics: {
117
+ * validation: true
118
+ * }
119
+ *
120
+ * @example
121
+ * // Fine-grained control
122
+ * diagnostics: {
123
+ * validation: {
124
+ * enabled: true,
125
+ * dev: { severity: 'error' },
126
+ * build: { severity: 'warning' }
127
+ * }
128
+ * }
129
+ */
130
+ diagnostics: S.optional(ReferenceDiagnostics),
131
+ }).annotations({
132
+ identifier: 'ReferenceConfigObject',
133
+ title: 'Reference Configuration',
134
+ description: 'Configuration for reference documentation feature',
135
+ })
136
+
137
+ export type ReferenceConfigObject = S.Schema.Type<typeof ReferenceConfigObject>
138
+
139
+ /**
140
+ * Reference configuration with boolean shorthand support.
141
+ * - true: Enable with defaults
142
+ * - false: Disable completely
143
+ * - object: Fine-grained control
144
+ */
145
+ export const ReferenceConfig = S.transform(
146
+ S.Union(
147
+ S.Boolean,
148
+ ReferenceConfigObject,
149
+ ),
150
+ ReferenceConfigObject,
151
+ {
152
+ strict: false,
153
+ decode: (input) => {
154
+ if (typeof input === 'boolean') {
155
+ return {
156
+ enabled: input,
157
+ descriptionsView: {},
158
+ nullabilityRendering: undefined,
159
+ diagnostics: {},
160
+ }
161
+ }
162
+ return input
163
+ },
164
+ encode: (config) => config,
165
+ },
166
+ ).annotations({
167
+ identifier: 'ReferenceConfig',
168
+ title: 'Reference Configuration',
169
+ description: 'Reference documentation configuration with boolean shortcuts',
170
+ })
171
+
172
+ export type ReferenceConfig = S.Schema.Type<typeof ReferenceConfig>
173
+
174
+ // ============================================================================
175
+ // Constructors
176
+ // ============================================================================
177
+
178
+ export const make = ReferenceConfigObject.make
179
+
180
+ // ============================================================================
181
+ // Type Guards
182
+ // ============================================================================
183
+
184
+ export const is = S.is(ReferenceConfig)
185
+
186
+ // ============================================================================
187
+ // Codecs
188
+ // ============================================================================
189
+
190
+ export const decode = S.decode(ReferenceConfig)
191
+ export const decodeSync = S.decodeSync(ReferenceConfig)
192
+ export const encode = S.encode(ReferenceConfig)
193
+ export const encodeSync = S.encodeSync(ReferenceConfig)
@@ -0,0 +1,53 @@
1
+ import { Diagnostic } from '#lib/diagnostic/$'
2
+ import { FileSystem } from '@effect/platform'
3
+ import { Effect } from 'effect'
4
+ import * as Path from 'node:path'
5
+ import * as Catalog from './catalog.js'
6
+
7
+ export interface ScanOptions {
8
+ /**
9
+ * The directory to scan for reference content
10
+ */
11
+ dir: string
12
+ }
13
+
14
+ export interface ScanResult {
15
+ /**
16
+ * The reference catalog with index metadata
17
+ */
18
+ catalog: Catalog.Catalog
19
+ /**
20
+ * Any diagnostics generated during scanning
21
+ */
22
+ diagnostics: Diagnostic.Diagnostic[]
23
+ }
24
+
25
+ /**
26
+ * Scan for reference documentation content.
27
+ * Currently looks for index.md or index.mdx files for custom landing pages.
28
+ */
29
+ export const scan = (
30
+ options: ScanOptions,
31
+ ): Effect.Effect<ScanResult, Error, FileSystem.FileSystem> =>
32
+ Effect.gen(function*() {
33
+ const fs = yield* FileSystem.FileSystem
34
+
35
+ const diagnostics: Diagnostic.Diagnostic[] = []
36
+
37
+ // Check for index.md or index.mdx file
38
+ const indexMdPath = Path.join(options.dir, 'reference', 'index.md')
39
+ const indexMdxPath = Path.join(options.dir, 'reference', 'index.mdx')
40
+
41
+ // Try index.md first, then index.mdx
42
+ const indexPath = (yield* fs.exists(indexMdPath))
43
+ ? indexMdPath
44
+ : (yield* fs.exists(indexMdxPath))
45
+ ? indexMdxPath
46
+ : null
47
+
48
+ const catalog = Catalog.make({
49
+ index: indexPath ? { path: indexPath } : undefined,
50
+ })
51
+
52
+ return { catalog, diagnostics }
53
+ })
@@ -0,0 +1,22 @@
1
+ import { astFromValue, print } from 'graphql'
2
+ import type { GraphQLInputType } from 'graphql'
3
+
4
+ /**
5
+ * Formats a GraphQL default value into a string representation.
6
+ * Returns just the value part (e.g., "20", "true", '"hello"')
7
+ *
8
+ * @param value - The default value from a GraphQL argument or input field
9
+ * @param type - The GraphQL input type of the field
10
+ * @returns The formatted value string, or null if value is undefined
11
+ */
12
+ export const formatDefaultValue = (value: unknown, type: GraphQLInputType): string | null => {
13
+ if (value === undefined) return null
14
+
15
+ const ast = astFromValue(value, type)
16
+ if (!ast) {
17
+ // Fallback for edge cases where astFromValue fails
18
+ return JSON.stringify(value)
19
+ }
20
+
21
+ return print(ast)
22
+ }
@@ -51,6 +51,8 @@ export * as NodesLike from './nodes-like.js'
51
51
 
52
52
  export * from './read.js'
53
53
 
54
+ export * from './format-default-value.js'
55
+
54
56
  import * as AST from './ast.js'
55
57
 
56
58
  export const empty: GraphQLSchema = buildASTSchema(AST.empty)
@@ -1,24 +1,73 @@
1
- import { Box, Flex, Text } from '@radix-ui/themes'
1
+ import { Grafaid } from '#lib/grafaid'
2
+ import { Box, Flex, HoverCard, Text } from '@radix-ui/themes'
2
3
  import type { GraphQLArgument } from 'graphql'
3
4
  import type { FC } from 'react'
5
+ import { useViewMode } from '../contexts/ViewModeContext.js'
6
+ import { Description } from './Description.js'
4
7
  import { TypeAnnotation } from './TypeAnnotation.js'
5
8
 
6
9
  export interface Props {
7
10
  data: GraphQLArgument
11
+ nameWidth?: number
8
12
  }
9
13
 
10
14
  /**
11
- * Renders a single GraphQL argument in SDL syntax
15
+ * Renders a single GraphQL argument with aligned columns
12
16
  */
13
- export const ArgumentAnnotation: FC<Props> = ({ data }) => {
14
- return (
15
- <Box as='div'>
16
- <Flex>
17
- <Text>{data.name}</Text>
18
- <Text>:&nbsp;</Text>
17
+ export const ArgumentAnnotation: FC<Props> = ({ data, nameWidth }) => {
18
+ const { viewMode } = useViewMode()
19
+
20
+ const nameElement = (
21
+ <Text size='2' weight='bold' color='gray'>
22
+ {data.name}
23
+ </Text>
24
+ )
19
25
 
20
- <TypeAnnotation type={data.type} />
26
+ return (
27
+ <Box>
28
+ <Flex align='baseline' gap='2'>
29
+ <Box
30
+ style={{
31
+ minWidth: nameWidth ? `${nameWidth}ch` : 'auto',
32
+ flexShrink: 0,
33
+ }}
34
+ >
35
+ {viewMode === 'compact' && data.description
36
+ ? (
37
+ <HoverCard.Root>
38
+ <HoverCard.Trigger>
39
+ {nameElement}
40
+ </HoverCard.Trigger>
41
+ <HoverCard.Content
42
+ size='2'
43
+ maxWidth='400px'
44
+ side='top'
45
+ align='center'
46
+ >
47
+ <Text size='2' color='gray'>
48
+ <Description data={data} />
49
+ </Text>
50
+ </HoverCard.Content>
51
+ </HoverCard.Root>
52
+ )
53
+ : nameElement}
54
+ </Box>
55
+ <TypeAnnotation type={data.type} showDescription={true} />
56
+ {data.defaultValue !== undefined && (
57
+ <Text size='2' color='gray'>
58
+ {' = '}
59
+ {Grafaid.Schema.formatDefaultValue(data.defaultValue, data.type)}
60
+ </Text>
61
+ )}
21
62
  </Flex>
63
+ {/* Argument description below name/type (only in expanded mode) */}
64
+ {data.description && viewMode === 'expanded' && (
65
+ <Box mt='2'>
66
+ <Text size='2' color='gray' style={{ lineHeight: '1.5' }}>
67
+ <Description data={data} />
68
+ </Text>
69
+ </Box>
70
+ )}
22
71
  </Box>
23
72
  )
24
73
  }