polen 0.11.0-next.16 → 0.11.0-next.18

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 (251) hide show
  1. package/build/api/builder/ssg/generate.d.ts.map +1 -1
  2. package/build/api/builder/ssg/generate.js +5 -5
  3. package/build/api/builder/ssg/generate.js.map +1 -1
  4. package/build/api/builder/ssg/page-generator.worker.js +13 -3
  5. package/build/api/builder/ssg/page-generator.worker.js.map +1 -1
  6. package/build/api/config/input.d.ts +88 -3
  7. package/build/api/config/input.d.ts.map +1 -1
  8. package/build/api/config/normalized.d.ts +92 -7
  9. package/build/api/config/normalized.d.ts.map +1 -1
  10. package/build/api/config/normalized.js +11 -3
  11. package/build/api/config/normalized.js.map +1 -1
  12. package/build/api/config-template/template.js +2 -2
  13. package/build/api/config-template/template.js.map +1 -1
  14. package/build/api/content/sidebar.d.ts.map +1 -1
  15. package/build/api/content/sidebar.js +2 -1
  16. package/build/api/content/sidebar.js.map +1 -1
  17. package/build/api/examples/config.d.ts +366 -3
  18. package/build/api/examples/config.d.ts.map +1 -1
  19. package/build/api/examples/config.js +25 -3
  20. package/build/api/examples/config.js.map +1 -1
  21. package/build/api/examples/diagnostic/diagnostic.d.ts +5 -5
  22. package/build/api/examples/diagnostic/missing-versions.d.ts +5 -4
  23. package/build/api/examples/diagnostic/missing-versions.d.ts.map +1 -1
  24. package/build/api/examples/diagnostic/missing-versions.js +3 -2
  25. package/build/api/examples/diagnostic/missing-versions.js.map +1 -1
  26. package/build/api/examples/diagnostic/unknown-version.d.ts +5 -4
  27. package/build/api/examples/diagnostic/unknown-version.d.ts.map +1 -1
  28. package/build/api/examples/diagnostic/unknown-version.js +3 -2
  29. package/build/api/examples/diagnostic/unknown-version.js.map +1 -1
  30. package/build/api/examples/diagnostic/validation-error.d.ts +3 -2
  31. package/build/api/examples/diagnostic/validation-error.d.ts.map +1 -1
  32. package/build/api/examples/diagnostic/validation-error.js +9 -3
  33. package/build/api/examples/diagnostic/validation-error.js.map +1 -1
  34. package/build/api/examples/diagnostic/validator.d.ts.map +1 -1
  35. package/build/api/examples/diagnostic/validator.js +115 -69
  36. package/build/api/examples/diagnostic/validator.js.map +1 -1
  37. package/build/api/examples/filter.d.ts.map +1 -1
  38. package/build/api/examples/filter.js +9 -6
  39. package/build/api/examples/filter.js.map +1 -1
  40. package/build/api/examples/scanner.d.ts.map +1 -1
  41. package/build/api/examples/scanner.js +93 -103
  42. package/build/api/examples/scanner.js.map +1 -1
  43. package/build/api/examples/type-usage-indexer.d.ts.map +1 -1
  44. package/build/api/examples/type-usage-indexer.js +18 -32
  45. package/build/api/examples/type-usage-indexer.js.map +1 -1
  46. package/build/api/iso/schema/routing.d.ts.map +1 -1
  47. package/build/api/iso/schema/routing.js +8 -8
  48. package/build/api/iso/schema/routing.js.map +1 -1
  49. package/build/api/iso/schema/validation.d.ts.map +1 -1
  50. package/build/api/iso/schema/validation.js +3 -2
  51. package/build/api/iso/schema/validation.js.map +1 -1
  52. package/build/api/schema/input-sources/directory.js +2 -2
  53. package/build/api/schema/input-sources/directory.js.map +1 -1
  54. package/build/api/schema/input-sources/versioned-directory.d.ts +3 -3
  55. package/build/api/schema/input-sources/versioned-directory.d.ts.map +1 -1
  56. package/build/api/schema/input-sources/versioned-directory.js +6 -4
  57. package/build/api/schema/input-sources/versioned-directory.js.map +1 -1
  58. package/build/api/schema/load.d.ts.map +1 -1
  59. package/build/api/schema/load.js +2 -2
  60. package/build/api/schema/load.js.map +1 -1
  61. package/build/cli/commands/hero-image.js +1 -1
  62. package/build/cli/commands/hero-image.js.map +1 -1
  63. package/build/lib/catalog/catalog.d.ts +65 -24
  64. package/build/lib/catalog/catalog.d.ts.map +1 -1
  65. package/build/lib/catalog/catalog.js +72 -16
  66. package/build/lib/catalog/catalog.js.map +1 -1
  67. package/build/lib/catalog/versioned.d.ts +46 -26
  68. package/build/lib/catalog/versioned.d.ts.map +1 -1
  69. package/build/lib/catalog/versioned.js +44 -7
  70. package/build/lib/catalog/versioned.js.map +1 -1
  71. package/build/lib/catalog-statistics/analyze-catalog.js +3 -3
  72. package/build/lib/catalog-statistics/analyze-catalog.js.map +1 -1
  73. package/build/lib/document/document.d.ts +55 -5
  74. package/build/lib/document/document.d.ts.map +1 -1
  75. package/build/lib/document/document.js +96 -2
  76. package/build/lib/document/document.js.map +1 -1
  77. package/build/lib/document/versioned.d.ts +2 -2
  78. package/build/lib/document/versioned.d.ts.map +1 -1
  79. package/build/lib/document/versioned.js +7 -7
  80. package/build/lib/document/versioned.js.map +1 -1
  81. package/build/lib/lifecycles/lifecycles.d.ts +5 -4
  82. package/build/lib/lifecycles/lifecycles.d.ts.map +1 -1
  83. package/build/lib/lifecycles/lifecycles.js +15 -13
  84. package/build/lib/lifecycles/lifecycles.js.map +1 -1
  85. package/build/lib/version-coverage/$$.d.ts +2 -0
  86. package/build/lib/version-coverage/$$.d.ts.map +1 -0
  87. package/build/lib/version-coverage/$$.js +2 -0
  88. package/build/lib/version-coverage/$$.js.map +1 -0
  89. package/build/lib/version-coverage/$.d.ts.map +1 -0
  90. package/build/lib/version-coverage/$.js.map +1 -0
  91. package/build/lib/{version-selection/version-selection.d.ts → version-coverage/version-coverage.d.ts} +1 -1
  92. package/build/lib/version-coverage/version-coverage.d.ts.map +1 -0
  93. package/build/lib/{version-selection/version-selection.js → version-coverage/version-coverage.js} +2 -2
  94. package/build/lib/version-coverage/version-coverage.js.map +1 -0
  95. package/build/template/components/Changelog/Changelog.d.ts.map +1 -1
  96. package/build/template/components/Changelog/Changelog.js +7 -7
  97. package/build/template/components/Changelog/Changelog.js.map +1 -1
  98. package/build/template/components/GraphQLDocument.d.ts +1 -1
  99. package/build/template/components/GraphQLDocument.d.ts.map +1 -1
  100. package/build/template/components/GraphQLDocument.js +10 -38
  101. package/build/template/components/GraphQLDocument.js.map +1 -1
  102. package/build/template/components/GraphQLInteractive/lib/parser.d.ts +28 -0
  103. package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -1
  104. package/build/template/components/GraphQLInteractive/lib/parser.js +60 -27
  105. package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -1
  106. package/build/template/components/VersionCoveragePicker.d.ts +1 -1
  107. package/build/template/components/VersionCoveragePicker.d.ts.map +1 -1
  108. package/build/template/components/VersionCoveragePicker.js +4 -6
  109. package/build/template/components/VersionCoveragePicker.js.map +1 -1
  110. package/build/template/components/VersionPicker.d.ts.map +1 -1
  111. package/build/template/components/VersionPicker.js +5 -2
  112. package/build/template/components/VersionPicker.js.map +1 -1
  113. package/build/template/components/home/FeaturesGrid.js +1 -1
  114. package/build/template/components/home/FeaturesGrid.js.map +1 -1
  115. package/build/template/components/home/HeroSection.js +1 -1
  116. package/build/template/components/home/HeroSection.js.map +1 -1
  117. package/build/template/components/home/QuickStart.d.ts.map +1 -1
  118. package/build/template/components/home/QuickStart.js +8 -4
  119. package/build/template/components/home/QuickStart.js.map +1 -1
  120. package/build/template/components/home/RecentChanges.d.ts.map +1 -1
  121. package/build/template/components/home/RecentChanges.js +2 -1
  122. package/build/template/components/home/RecentChanges.js.map +1 -1
  123. package/build/template/hooks/use-highlighted.d.ts.map +1 -1
  124. package/build/template/hooks/use-highlighted.js +19 -13
  125. package/build/template/hooks/use-highlighted.js.map +1 -1
  126. package/build/template/lib/fetch-text.d.ts +18 -0
  127. package/build/template/lib/fetch-text.d.ts.map +1 -1
  128. package/build/template/lib/fetch-text.js +32 -4
  129. package/build/template/lib/fetch-text.js.map +1 -1
  130. package/build/template/routes/changelog.d.ts +1 -1
  131. package/build/template/routes/changelog.d.ts.map +1 -1
  132. package/build/template/routes/changelog.js +7 -4
  133. package/build/template/routes/changelog.js.map +1 -1
  134. package/build/template/routes/examples/_index.js +1 -1
  135. package/build/template/routes/examples/_index.js.map +1 -1
  136. package/build/template/routes/examples/name.d.ts.map +1 -1
  137. package/build/template/routes/examples/name.js +4 -2
  138. package/build/template/routes/examples/name.js.map +1 -1
  139. package/build/template/routes/reference.js +6 -6
  140. package/build/template/routes/reference.js.map +1 -1
  141. package/build/template/stores/toast.d.ts.map +1 -1
  142. package/build/template/stores/toast.js +5 -3
  143. package/build/template/stores/toast.js.map +1 -1
  144. package/build/vite/plugins/navbar.js +1 -1
  145. package/build/vite/plugins/navbar.js.map +1 -1
  146. package/build/vite/plugins/routes-manifest.js +1 -1
  147. package/build/vite/plugins/routes-manifest.js.map +1 -1
  148. package/package.json +7 -7
  149. package/src/api/builder/ssg/generate.ts +10 -5
  150. package/src/api/builder/ssg/page-generator.worker.ts +18 -3
  151. package/src/api/config/normalized.ts +12 -3
  152. package/src/api/config-template/template.ts +2 -2
  153. package/src/api/content/sidebar.ts +3 -3
  154. package/src/api/examples/config.test.ts +10 -0
  155. package/src/api/examples/config.ts +33 -4
  156. package/src/api/examples/diagnostic/missing-versions.ts +3 -2
  157. package/src/api/examples/diagnostic/unknown-version.ts +3 -2
  158. package/src/api/examples/diagnostic/validation-error.ts +9 -3
  159. package/src/api/examples/diagnostic/validator.test.ts +100 -55
  160. package/src/api/examples/diagnostic/validator.ts +148 -105
  161. package/src/api/examples/filter.ts +9 -6
  162. package/src/api/examples/scanner.ts +144 -120
  163. package/src/api/examples/type-usage-indexer.test.ts +44 -33
  164. package/src/api/examples/type-usage-indexer.ts +25 -40
  165. package/src/api/iso/schema/routing.ts +10 -10
  166. package/src/api/iso/schema/validation.ts +3 -2
  167. package/src/api/schema/$.test.ts +2 -2
  168. package/src/api/schema/input-sources/directory.ts +2 -2
  169. package/src/api/schema/input-sources/versioned-directory.ts +11 -8
  170. package/src/api/schema/load.ts +2 -2
  171. package/src/cli/commands/hero-image.ts +1 -1
  172. package/src/lib/catalog/catalog.ts +93 -16
  173. package/src/lib/catalog/versioned.ts +57 -7
  174. package/src/lib/catalog-statistics/$.test.ts +22 -12
  175. package/src/lib/catalog-statistics/analyze-catalog.ts +3 -3
  176. package/src/lib/document/document.ts +135 -2
  177. package/src/lib/document/versioned.ts +8 -8
  178. package/src/lib/lifecycles/lifecycles.ts +33 -28
  179. package/src/lib/version-coverage/$$.ts +1 -0
  180. package/src/lib/{version-selection/version-selection.ts → version-coverage/version-coverage.ts} +1 -1
  181. package/src/template/components/Changelog/Changelog.tsx +10 -6
  182. package/src/template/components/GraphQLDocument.tsx +11 -68
  183. package/src/template/components/GraphQLInteractive/lib/parser.ts +81 -29
  184. package/src/template/components/VersionCoveragePicker.tsx +4 -5
  185. package/src/template/components/VersionPicker.tsx +9 -2
  186. package/src/template/components/home/FeaturesGrid.tsx +1 -1
  187. package/src/template/components/home/HeroSection.tsx +1 -1
  188. package/src/template/components/home/QuickStart.tsx +16 -7
  189. package/src/template/components/home/RecentChanges.tsx +3 -1
  190. package/src/template/hooks/use-highlighted.ts +31 -19
  191. package/src/template/lib/fetch-text.ts +45 -4
  192. package/src/template/routes/changelog.tsx +10 -4
  193. package/src/template/routes/examples/_index.tsx +1 -1
  194. package/src/template/routes/examples/name.tsx +4 -2
  195. package/src/template/routes/reference.tsx +6 -6
  196. package/src/template/stores/toast.ts +6 -3
  197. package/src/vite/plugins/navbar.ts +1 -1
  198. package/src/vite/plugins/routes-manifest.ts +1 -1
  199. package/build/lib/graph/$$.d.ts +0 -2
  200. package/build/lib/graph/$$.d.ts.map +0 -1
  201. package/build/lib/graph/$$.js +0 -2
  202. package/build/lib/graph/$$.js.map +0 -1
  203. package/build/lib/graph/$.d.ts +0 -2
  204. package/build/lib/graph/$.d.ts.map +0 -1
  205. package/build/lib/graph/$.js +0 -2
  206. package/build/lib/graph/$.js.map +0 -1
  207. package/build/lib/graph/graph.d.ts +0 -127
  208. package/build/lib/graph/graph.d.ts.map +0 -1
  209. package/build/lib/graph/graph.js +0 -152
  210. package/build/lib/graph/graph.js.map +0 -1
  211. package/build/lib/mask/$$.d.ts +0 -3
  212. package/build/lib/mask/$$.d.ts.map +0 -1
  213. package/build/lib/mask/$$.js +0 -3
  214. package/build/lib/mask/$$.js.map +0 -1
  215. package/build/lib/mask/$.d.ts +0 -2
  216. package/build/lib/mask/$.d.ts.map +0 -1
  217. package/build/lib/mask/$.js +0 -2
  218. package/build/lib/mask/$.js.map +0 -1
  219. package/build/lib/mask/apply.d.ts +0 -86
  220. package/build/lib/mask/apply.d.ts.map +0 -1
  221. package/build/lib/mask/apply.js +0 -86
  222. package/build/lib/mask/apply.js.map +0 -1
  223. package/build/lib/mask/mask.d.ts +0 -124
  224. package/build/lib/mask/mask.d.ts.map +0 -1
  225. package/build/lib/mask/mask.js +0 -137
  226. package/build/lib/mask/mask.js.map +0 -1
  227. package/build/lib/mask/mask.test-d.d.ts +0 -2
  228. package/build/lib/mask/mask.test-d.d.ts.map +0 -1
  229. package/build/lib/mask/mask.test-d.js +0 -102
  230. package/build/lib/mask/mask.test-d.js.map +0 -1
  231. package/build/lib/version-selection/$$.d.ts +0 -2
  232. package/build/lib/version-selection/$$.d.ts.map +0 -1
  233. package/build/lib/version-selection/$$.js +0 -2
  234. package/build/lib/version-selection/$$.js.map +0 -1
  235. package/build/lib/version-selection/$.d.ts.map +0 -1
  236. package/build/lib/version-selection/$.js.map +0 -1
  237. package/build/lib/version-selection/version-selection.d.ts.map +0 -1
  238. package/build/lib/version-selection/version-selection.js.map +0 -1
  239. package/src/lib/graph/$$.ts +0 -1
  240. package/src/lib/graph/$.ts +0 -1
  241. package/src/lib/graph/graph.ts +0 -197
  242. package/src/lib/mask/$$.ts +0 -2
  243. package/src/lib/mask/$.test.ts +0 -226
  244. package/src/lib/mask/$.ts +0 -1
  245. package/src/lib/mask/apply.ts +0 -134
  246. package/src/lib/mask/mask.test-d.ts +0 -156
  247. package/src/lib/mask/mask.ts +0 -244
  248. package/src/lib/version-selection/$$.ts +0 -1
  249. /package/build/lib/{version-selection → version-coverage}/$.d.ts +0 -0
  250. /package/build/lib/{version-selection → version-coverage}/$.js +0 -0
  251. /package/src/lib/{version-selection → version-coverage}/$.ts +0 -0
@@ -1,9 +1,9 @@
1
1
  import { Catalog as SchemaCatalog } from '#lib/catalog/$'
2
2
  import { Document } from '#lib/document/$'
3
+ import { Schema } from '#lib/schema/$'
3
4
  import { Version } from '#lib/version/$'
4
- import { HashMap, Match, Option } from 'effect'
5
- import { Array } from 'effect'
6
- import type { GraphQLError, GraphQLSchema } from 'graphql'
5
+ import { Array, Either, Match, Schema as S } from 'effect'
6
+ import type { DocumentNode, GraphQLError } from 'graphql'
7
7
  import { parse, specifiedRules, validate } from 'graphql'
8
8
  import { Example } from '../schemas/example/$.js'
9
9
  import type { DiagnosticValidationError } from './diagnostic.js'
@@ -15,6 +15,35 @@ import { makeDiagnosticValidationError } from './diagnostic.js'
15
15
 
16
16
  export type ValidationDiagnostic = DiagnosticValidationError
17
17
 
18
+ // ============================================================================
19
+ // Schemas
20
+ // ============================================================================
21
+
22
+ const GraphQLErrorData = S.Struct({
23
+ message: S.String,
24
+ locations: S.optional(S.Array(S.Struct({
25
+ line: S.Number,
26
+ column: S.Number,
27
+ }))),
28
+ })
29
+
30
+ type GraphQLErrorData = S.Schema.Type<typeof GraphQLErrorData>
31
+
32
+ // ============================================================================
33
+ // Safe Parsing
34
+ // ============================================================================
35
+
36
+ /**
37
+ * Safely parse a GraphQL document without throwing.
38
+ * Returns an Either with the document on success or error on failure.
39
+ */
40
+ const parseDocumentSafe = (content: string): Either.Either<DocumentNode, GraphQLError> => {
41
+ return Either.try({
42
+ try: () => parse(content),
43
+ catch: (error) => error as GraphQLError,
44
+ })
45
+ }
46
+
18
47
  // ============================================================================
19
48
  // Validation
20
49
  // ============================================================================
@@ -32,71 +61,76 @@ export const validateExamples = (
32
61
  ): ValidationDiagnostic[] => {
33
62
  const diagnostics: ValidationDiagnostic[] = []
34
63
 
35
- return Match.value(catalog).pipe(
36
- Match.tagsExhaustive({
37
- CatalogVersioned: (versioned) => {
38
- const schemaVersions = versioned.entries.map(e => e.version)
39
-
40
- for (const example of examples) {
41
- Match.value(example.document).pipe(
42
- Match.tagsExhaustive({
43
- DocumentVersioned: (doc) => {
44
- // Validate each version against its corresponding schema
45
- for (const entry of versioned.entries) {
46
- const content = Document.Versioned.getContentForVersion(doc, entry.version)
47
- if (content) {
48
- const versionStr = Version.encodeSync(entry.version)
49
- validateDocument(
50
- example.name,
51
- example.path,
52
- versionStr,
53
- content,
54
- entry.definition,
55
- diagnostics,
56
- )
57
- }
58
- }
59
- return undefined
60
- },
61
- DocumentUnversioned: (doc) => {
62
- const latestEntry = versioned.entries[0]!
63
- validateDocument(
64
- example.name,
65
- example.path,
66
- 'default',
67
- doc.document,
68
- latestEntry.definition,
69
- diagnostics,
70
- )
71
- return undefined
72
- },
73
- }),
74
- )
75
- }
76
-
77
- return diagnostics
78
- },
79
- CatalogUnversioned: (unversioned) => {
80
- // For unversioned catalog, only unversioned documents make sense
81
- for (const example of examples) {
82
- if (example.document._tag === 'DocumentUnversioned') {
83
- validateDocument(
84
- example.name,
85
- example.path,
86
- 'default',
87
- example.document.document,
88
- unversioned.schema.definition,
89
- diagnostics,
64
+ Array.forEach(examples, (example) => {
65
+ if (example.document._tag === 'DocumentVersioned') {
66
+ // Versioned document: iterate all versions and let utility handle compatibility
67
+ const documentVersions = Document.Versioned.getAllVersions(example.document)
68
+ let versionMismatchDetected = false
69
+
70
+ Array.forEach(documentVersions, (version) => {
71
+ // Skip remaining versions if we already detected a version mismatch
72
+ if (versionMismatchDetected) return
73
+
74
+ const result = Document.resolveDocumentAndSchema(
75
+ example.document,
76
+ catalog,
77
+ version, // Pass each version as VersionCoverage
78
+ )
79
+
80
+ Either.match(result, {
81
+ onLeft: (error) => {
82
+ // Pattern match on error types - all errors are now tagged
83
+ Match.value(error).pipe(
84
+ Match.when({ _tag: 'VersionCoverageMismatchError' }, (err) => {
85
+ diagnostics.push(makeDiagnosticValidationError({
86
+ message: `Example "${example.name}" has versioned content but catalog is unversioned`,
87
+ example: { name: example.name, path: example.path },
88
+ version: undefined,
89
+ errors: [{ message: err.reason }],
90
+ }))
91
+ // Set flag to skip remaining versions - all will have same error
92
+ versionMismatchDetected = true
93
+ }),
94
+ Match.when({ _tag: 'VersionNotFoundInDocumentError' }, () => {
95
+ // Skip silently - version not found in document
96
+ }),
97
+ Match.when({ _tag: 'VersionNotFoundInCatalogError' }, () => {
98
+ // Skip silently - version not found in catalog
99
+ }),
100
+ Match.when({ _tag: 'EmptyCatalogError' }, () => {
101
+ // Skip silently - catalog has no entries
102
+ }),
103
+ Match.exhaustive,
90
104
  )
105
+ },
106
+ onRight: ({ content, schema }) => {
107
+ if (schema) {
108
+ validateDocument(example, schema, content, diagnostics)
109
+ }
110
+ },
111
+ })
112
+ })
113
+ } else {
114
+ // Unversioned document: call without version coverage
115
+ const result = Document.resolveDocumentAndSchema(
116
+ example.document,
117
+ catalog,
118
+ )
119
+
120
+ Either.match(result, {
121
+ onLeft: () => {
122
+ // Resolution failed - skip silently
123
+ },
124
+ onRight: ({ content, schema }) => {
125
+ if (schema) {
126
+ validateDocument(example, schema, content, diagnostics)
91
127
  }
92
- // Versioned/PartiallyVersioned documents with unversioned catalog don't make sense
93
- // These should be caught by other diagnostics
94
- }
128
+ },
129
+ })
130
+ }
131
+ })
95
132
 
96
- return diagnostics
97
- },
98
- }),
99
- )
133
+ return diagnostics
100
134
  }
101
135
 
102
136
  // ============================================================================
@@ -107,54 +141,67 @@ export const validateExamples = (
107
141
  * Validate a single document and add diagnostics if needed.
108
142
  */
109
143
  const validateDocument = (
110
- exampleName: string,
111
- examplePath: string,
112
- version: string,
144
+ example: Example.Example,
145
+ schema: Schema.Schema,
113
146
  content: string,
114
- schema: GraphQLSchema,
115
147
  diagnostics: ValidationDiagnostic[],
116
148
  ): void => {
117
- try {
118
- // Parse the GraphQL document
119
- const document = parse(content)
120
-
121
- // Validate against the schema
122
- const errors = validate(schema, document, specifiedRules)
123
-
124
- if (errors.length > 0) {
125
- diagnostics.push(makeDiagnosticValidationError({
126
- message: formatValidationMessage(exampleName, version, errors),
127
- example: { name: exampleName, path: examplePath },
128
- version,
129
- errors: errors.map(formatGraphQLError),
130
- }))
131
- }
132
- } catch (parseError) {
133
- // Parse errors are also validation errors
149
+ // Extract version from schema (undefined for unversioned)
150
+ const version = Schema.getVersion(schema)
151
+
152
+ // Parse the document safely
153
+ const parseResult = parseDocumentSafe(content)
154
+
155
+ if (Either.isLeft(parseResult)) {
156
+ // Handle parse errors
157
+ diagnostics.push(makeDiagnosticValidationError({
158
+ message: formatParseError(example.name, version),
159
+ example: { name: example.name, path: example.path },
160
+ version,
161
+ errors: [{ message: parseResult.left.message }],
162
+ }))
163
+ return
164
+ }
165
+
166
+ // Validate the parsed document against the schema
167
+ const errors = validate(schema.definition, parseResult.right, specifiedRules)
168
+
169
+ if (Array.isNonEmptyReadonlyArray(errors)) {
134
170
  diagnostics.push(makeDiagnosticValidationError({
135
- message: `Example "${exampleName}" (${version}) has invalid GraphQL syntax`,
136
- example: { name: exampleName, path: examplePath },
171
+ message: formatValidationMessage(example.name, version, errors),
172
+ example: { name: example.name, path: example.path },
137
173
  version,
138
- errors: [{ message: String(parseError) }],
174
+ errors: errors.map(formatGraphQLError),
139
175
  }))
140
176
  }
141
177
  }
142
178
 
179
+ /**
180
+ * Format a parse error message for an example.
181
+ */
182
+ const formatParseError = (
183
+ exampleId: string,
184
+ version: Version.Version | undefined,
185
+ ): string => {
186
+ const versionStr = version ? ` (${Version.encodeSync(version)})` : ''
187
+ return `Example "${exampleId}"${versionStr} has invalid GraphQL syntax`
188
+ }
189
+
143
190
  /**
144
191
  * Format a validation message for an example.
145
192
  */
146
193
  const formatValidationMessage = (
147
194
  exampleId: string,
148
- version: string,
149
- errors: readonly GraphQLError[],
195
+ version: Version.Version | undefined,
196
+ errors: Array.NonEmptyReadonlyArray<GraphQLError>,
150
197
  ): string => {
151
- const versionStr = version === 'default' ? '' : ` (${version})`
198
+ const versionStr = version ? ` (${Version.encodeSync(version)})` : ''
152
199
  const errorCount = errors.length
153
200
  const errorWord = errorCount === 1 ? 'error' : 'errors'
154
201
 
155
- // Include the first error message for context
156
- const firstError = errors[0]
157
- const preview = firstError ? `: ${firstError.message}` : ''
202
+ // Include the first error message for context - always safe with NonEmptyArray
203
+ const firstError = Array.headNonEmpty(errors)
204
+ const preview = `: ${firstError.message}`
158
205
 
159
206
  return `Example "${exampleId}"${versionStr} has ${errorCount} validation ${errorWord}${preview}`
160
207
  }
@@ -162,17 +209,13 @@ const formatValidationMessage = (
162
209
  /**
163
210
  * Format a GraphQL error for diagnostic reporting.
164
211
  */
165
- const formatGraphQLError = (error: GraphQLError): {
166
- message: string
167
- locations?: Array<{ line: number; column: number }>
168
- } => ({
169
- message: error.message,
170
- ...(error.locations
171
- ? {
212
+ const formatGraphQLError = (error: GraphQLError): GraphQLErrorData =>
213
+ GraphQLErrorData.make({
214
+ message: error.message,
215
+ ...(error.locations && {
172
216
  locations: error.locations.map(loc => ({
173
217
  line: loc.line,
174
218
  column: loc.column,
175
219
  })),
176
- }
177
- : {}),
178
- })
220
+ }),
221
+ })
@@ -1,3 +1,4 @@
1
+ import { HashSet } from 'effect'
1
2
  import type { ExampleName, ExampleSelection } from './config.js'
2
3
  import { Example } from './schemas/example/$.js'
3
4
 
@@ -28,14 +29,14 @@ export const filterExamplesBySelection = (
28
29
 
29
30
  // Handle include pattern
30
31
  if ('include' in selection) {
31
- const includeSet = new Set<ExampleName>(selection.include)
32
- return examples.filter(example => includeSet.has(example.name as ExampleName))
32
+ const includeSet = HashSet.fromIterable(selection.include)
33
+ return examples.filter(example => HashSet.has(includeSet, example.name as ExampleName))
33
34
  }
34
35
 
35
36
  // Handle exclude pattern
36
37
  if ('exclude' in selection) {
37
- const excludeSet = new Set<ExampleName>(selection.exclude)
38
- return examples.filter(example => !excludeSet.has(example.name as ExampleName))
38
+ const excludeSet = HashSet.fromIterable(selection.exclude)
39
+ return examples.filter(example => !HashSet.has(excludeSet, example.name as ExampleName))
39
40
  }
40
41
 
41
42
  // Fallback to all examples if selection pattern is not recognized
@@ -69,12 +70,14 @@ export const shouldDisplayExample = (
69
70
 
70
71
  // Handle include pattern
71
72
  if ('include' in selection) {
72
- return selection.include.includes(exampleName)
73
+ const includeSet = HashSet.fromIterable(selection.include)
74
+ return HashSet.has(includeSet, exampleName)
73
75
  }
74
76
 
75
77
  // Handle exclude pattern
76
78
  if ('exclude' in selection) {
77
- return !selection.exclude.includes(exampleName)
79
+ const excludeSet = HashSet.fromIterable(selection.exclude)
80
+ return !HashSet.has(excludeSet, exampleName)
78
81
  }
79
82
 
80
83
  // Fallback to show if selection pattern is not recognized