polen 0.11.0-next.17 → 0.11.0-next.19

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 (307) 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/errors.d.ts +278 -0
  18. package/build/api/errors.d.ts.map +1 -0
  19. package/build/api/errors.js +153 -0
  20. package/build/api/errors.js.map +1 -0
  21. package/build/api/examples/config.d.ts +366 -3
  22. package/build/api/examples/config.d.ts.map +1 -1
  23. package/build/api/examples/config.js +25 -3
  24. package/build/api/examples/config.js.map +1 -1
  25. package/build/api/examples/diagnostic/diagnostic.d.ts +1 -1
  26. package/build/api/examples/diagnostic/validation-error.d.ts +3 -2
  27. package/build/api/examples/diagnostic/validation-error.d.ts.map +1 -1
  28. package/build/api/examples/diagnostic/validation-error.js +9 -3
  29. package/build/api/examples/diagnostic/validation-error.js.map +1 -1
  30. package/build/api/examples/diagnostic/validator.d.ts.map +1 -1
  31. package/build/api/examples/diagnostic/validator.js +115 -68
  32. package/build/api/examples/diagnostic/validator.js.map +1 -1
  33. package/build/api/examples/filter.d.ts.map +1 -1
  34. package/build/api/examples/filter.js +9 -6
  35. package/build/api/examples/filter.js.map +1 -1
  36. package/build/api/examples/scanner.d.ts.map +1 -1
  37. package/build/api/examples/scanner.js +89 -103
  38. package/build/api/examples/scanner.js.map +1 -1
  39. package/build/api/examples/type-usage-indexer.d.ts.map +1 -1
  40. package/build/api/examples/type-usage-indexer.js +17 -30
  41. package/build/api/examples/type-usage-indexer.js.map +1 -1
  42. package/build/api/iso/schema/routing.d.ts.map +1 -1
  43. package/build/api/iso/schema/routing.js +8 -8
  44. package/build/api/iso/schema/routing.js.map +1 -1
  45. package/build/api/iso/schema/validation.d.ts.map +1 -1
  46. package/build/api/iso/schema/validation.js +3 -2
  47. package/build/api/iso/schema/validation.js.map +1 -1
  48. package/build/api/schema/input-source/$$.d.ts +1 -0
  49. package/build/api/schema/input-source/$$.d.ts.map +1 -1
  50. package/build/api/schema/input-source/$$.js +1 -0
  51. package/build/api/schema/input-source/$$.js.map +1 -1
  52. package/build/api/schema/input-source/errors.d.ts +36 -0
  53. package/build/api/schema/input-source/errors.d.ts.map +1 -0
  54. package/build/api/schema/input-source/errors.js +17 -0
  55. package/build/api/schema/input-source/errors.js.map +1 -0
  56. package/build/api/schema/input-source/input-source.d.ts +1 -7
  57. package/build/api/schema/input-source/input-source.d.ts.map +1 -1
  58. package/build/api/schema/input-source/input-source.js +0 -6
  59. package/build/api/schema/input-source/input-source.js.map +1 -1
  60. package/build/api/schema/input-sources/directory.d.ts.map +1 -1
  61. package/build/api/schema/input-sources/directory.js +19 -6
  62. package/build/api/schema/input-sources/directory.js.map +1 -1
  63. package/build/api/schema/input-sources/file.d.ts.map +1 -1
  64. package/build/api/schema/input-sources/file.js +15 -4
  65. package/build/api/schema/input-sources/file.js.map +1 -1
  66. package/build/api/schema/input-sources/introspection-file.d.ts.map +1 -1
  67. package/build/api/schema/input-sources/introspection-file.js +28 -6
  68. package/build/api/schema/input-sources/introspection-file.js.map +1 -1
  69. package/build/api/schema/input-sources/introspection.d.ts.map +1 -1
  70. package/build/api/schema/input-sources/introspection.js +35 -7
  71. package/build/api/schema/input-sources/introspection.js.map +1 -1
  72. package/build/api/schema/input-sources/memory.d.ts.map +1 -1
  73. package/build/api/schema/input-sources/memory.js +15 -3
  74. package/build/api/schema/input-sources/memory.js.map +1 -1
  75. package/build/api/schema/input-sources/versioned-directory.d.ts.map +1 -1
  76. package/build/api/schema/input-sources/versioned-directory.js +23 -7
  77. package/build/api/schema/input-sources/versioned-directory.js.map +1 -1
  78. package/build/api/schema/load.d.ts +1 -1
  79. package/build/api/schema/load.d.ts.map +1 -1
  80. package/build/api/schema/load.js.map +1 -1
  81. package/build/cli/commands/hero-image.d.ts +1 -2
  82. package/build/cli/commands/hero-image.d.ts.map +1 -1
  83. package/build/cli/index.d.ts +1 -1
  84. package/build/lib/catalog/catalog.d.ts +43 -3
  85. package/build/lib/catalog/catalog.d.ts.map +1 -1
  86. package/build/lib/catalog/catalog.js +67 -5
  87. package/build/lib/catalog/catalog.js.map +1 -1
  88. package/build/lib/catalog/versioned.d.ts +11 -1
  89. package/build/lib/catalog/versioned.d.ts.map +1 -1
  90. package/build/lib/catalog/versioned.js +23 -5
  91. package/build/lib/catalog/versioned.js.map +1 -1
  92. package/build/lib/document/document.d.ts +55 -5
  93. package/build/lib/document/document.d.ts.map +1 -1
  94. package/build/lib/document/document.js +96 -2
  95. package/build/lib/document/document.js.map +1 -1
  96. package/build/lib/document/versioned.d.ts +2 -2
  97. package/build/lib/document/versioned.d.ts.map +1 -1
  98. package/build/lib/document/versioned.js +7 -7
  99. package/build/lib/document/versioned.js.map +1 -1
  100. package/build/lib/lifecycles/lifecycles.d.ts +5 -4
  101. package/build/lib/lifecycles/lifecycles.d.ts.map +1 -1
  102. package/build/lib/lifecycles/lifecycles.js +14 -12
  103. package/build/lib/lifecycles/lifecycles.js.map +1 -1
  104. package/build/lib/version-coverage/$$.d.ts +2 -0
  105. package/build/lib/version-coverage/$$.d.ts.map +1 -0
  106. package/build/lib/version-coverage/$$.js +2 -0
  107. package/build/lib/version-coverage/$$.js.map +1 -0
  108. package/build/lib/version-coverage/$.d.ts.map +1 -0
  109. package/build/lib/version-coverage/$.js.map +1 -0
  110. package/build/lib/{version-selection/version-selection.d.ts → version-coverage/version-coverage.d.ts} +1 -1
  111. package/build/lib/version-coverage/version-coverage.d.ts.map +1 -0
  112. package/build/lib/{version-selection/version-selection.js → version-coverage/version-coverage.js} +2 -2
  113. package/build/lib/version-coverage/version-coverage.js.map +1 -0
  114. package/build/template/components/GraphQLDocument.d.ts +1 -1
  115. package/build/template/components/GraphQLDocument.d.ts.map +1 -1
  116. package/build/template/components/GraphQLDocument.js +10 -39
  117. package/build/template/components/GraphQLDocument.js.map +1 -1
  118. package/build/template/components/GraphQLInteractive/lib/parser.d.ts +28 -0
  119. package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -1
  120. package/build/template/components/GraphQLInteractive/lib/parser.js +60 -27
  121. package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -1
  122. package/build/template/components/ReferenceVersionPicker.d.ts +9 -0
  123. package/build/template/components/ReferenceVersionPicker.d.ts.map +1 -0
  124. package/build/template/components/ReferenceVersionPicker.js +79 -0
  125. package/build/template/components/ReferenceVersionPicker.js.map +1 -0
  126. package/build/template/components/VersionCoveragePicker.d.ts +1 -1
  127. package/build/template/components/VersionCoveragePicker.d.ts.map +1 -1
  128. package/build/template/components/VersionCoveragePicker.js +4 -6
  129. package/build/template/components/VersionCoveragePicker.js.map +1 -1
  130. package/build/template/components/VersionPicker.d.ts +8 -3
  131. package/build/template/components/VersionPicker.d.ts.map +1 -1
  132. package/build/template/components/VersionPicker.js +12 -77
  133. package/build/template/components/VersionPicker.js.map +1 -1
  134. package/build/template/components/home/QuickStart.d.ts.map +1 -1
  135. package/build/template/components/home/QuickStart.js +8 -4
  136. package/build/template/components/home/QuickStart.js.map +1 -1
  137. package/build/template/hooks/use-highlighted.d.ts.map +1 -1
  138. package/build/template/hooks/use-highlighted.js +19 -13
  139. package/build/template/hooks/use-highlighted.js.map +1 -1
  140. package/build/template/lib/fetch-text.d.ts +18 -0
  141. package/build/template/lib/fetch-text.d.ts.map +1 -1
  142. package/build/template/lib/fetch-text.js +32 -4
  143. package/build/template/lib/fetch-text.js.map +1 -1
  144. package/build/template/routes/changelog/ChangelogBody.d.ts +6 -0
  145. package/build/template/routes/changelog/ChangelogBody.d.ts.map +1 -0
  146. package/build/template/{components/Changelog/Changelog.js → routes/changelog/ChangelogBody.js} +8 -58
  147. package/build/template/routes/changelog/ChangelogBody.js.map +1 -0
  148. package/build/template/routes/changelog/ChangelogSidebar.d.ts +7 -0
  149. package/build/template/routes/changelog/ChangelogSidebar.d.ts.map +1 -0
  150. package/build/template/routes/changelog/ChangelogSidebar.js +46 -0
  151. package/build/template/routes/changelog/ChangelogSidebar.js.map +1 -0
  152. package/build/template/routes/changelog/ChangelogSidebarItem.d.ts +11 -0
  153. package/build/template/routes/changelog/ChangelogSidebarItem.d.ts.map +1 -0
  154. package/build/template/routes/changelog/ChangelogSidebarItem.js +35 -0
  155. package/build/template/routes/changelog/ChangelogSidebarItem.js.map +1 -0
  156. package/build/template/routes/changelog/_.d.ts +3264 -0
  157. package/build/template/routes/changelog/_.d.ts.map +1 -0
  158. package/build/template/routes/changelog/_.js +111 -0
  159. package/build/template/routes/changelog/_.js.map +1 -0
  160. package/build/template/routes/changelog/utils.d.ts +3 -0
  161. package/build/template/routes/changelog/utils.d.ts.map +1 -0
  162. package/build/template/routes/changelog/utils.js +11 -0
  163. package/build/template/routes/changelog/utils.js.map +1 -0
  164. package/build/template/routes/examples/name.d.ts.map +1 -1
  165. package/build/template/routes/examples/name.js +4 -2
  166. package/build/template/routes/examples/name.js.map +1 -1
  167. package/build/template/routes/reference.js +2 -2
  168. package/build/template/routes/reference.js.map +1 -1
  169. package/build/template/routes/root.js +1 -1
  170. package/build/template/routes/root.js.map +1 -1
  171. package/build/template/stores/toast.d.ts.map +1 -1
  172. package/build/template/stores/toast.js +5 -3
  173. package/build/template/stores/toast.js.map +1 -1
  174. package/build/template/theme/swiss-sharp.css +14 -14
  175. package/build/vite/plugins/schemas.d.ts +1 -2
  176. package/build/vite/plugins/schemas.d.ts.map +1 -1
  177. package/build/vite/plugins/schemas.js +0 -1
  178. package/build/vite/plugins/schemas.js.map +1 -1
  179. package/package.json +7 -7
  180. package/src/api/builder/ssg/generate.ts +10 -5
  181. package/src/api/builder/ssg/page-generator.worker.ts +18 -3
  182. package/src/api/config/normalized.ts +12 -3
  183. package/src/api/config-template/template.ts +2 -2
  184. package/src/api/content/sidebar.ts +3 -3
  185. package/src/api/errors.ts +227 -0
  186. package/src/api/examples/config.test.ts +10 -0
  187. package/src/api/examples/config.ts +33 -4
  188. package/src/api/examples/diagnostic/validation-error.ts +9 -3
  189. package/src/api/examples/diagnostic/validator.test.ts +30 -0
  190. package/src/api/examples/diagnostic/validator.ts +148 -103
  191. package/src/api/examples/filter.ts +9 -6
  192. package/src/api/examples/scanner.ts +136 -117
  193. package/src/api/examples/type-usage-indexer.ts +24 -36
  194. package/src/api/iso/schema/routing.ts +10 -10
  195. package/src/api/iso/schema/validation.ts +3 -2
  196. package/src/api/schema/input-source/$$.ts +1 -0
  197. package/src/api/schema/input-source/errors.ts +26 -0
  198. package/src/api/schema/input-source/input-source.ts +1 -22
  199. package/src/api/schema/input-sources/directory.ts +20 -15
  200. package/src/api/schema/input-sources/file.ts +17 -4
  201. package/src/api/schema/input-sources/introspection-file.ts +30 -15
  202. package/src/api/schema/input-sources/introspection.ts +38 -7
  203. package/src/api/schema/input-sources/memory.ts +19 -3
  204. package/src/api/schema/input-sources/versioned-directory.ts +25 -27
  205. package/src/api/schema/load.ts +2 -1
  206. package/src/lib/catalog/catalog.ts +89 -6
  207. package/src/lib/catalog/versioned.ts +26 -5
  208. package/src/lib/document/document.ts +135 -2
  209. package/src/lib/document/versioned.ts +8 -8
  210. package/src/lib/lifecycles/lifecycles.ts +32 -27
  211. package/src/lib/version-coverage/$$.ts +1 -0
  212. package/src/lib/{version-selection/version-selection.ts → version-coverage/version-coverage.ts} +1 -1
  213. package/src/template/components/GraphQLDocument.tsx +11 -69
  214. package/src/template/components/GraphQLInteractive/lib/parser.ts +81 -29
  215. package/src/template/components/ReferenceVersionPicker.tsx +107 -0
  216. package/src/template/components/VersionCoveragePicker.tsx +4 -5
  217. package/src/template/components/VersionPicker.tsx +32 -98
  218. package/src/template/components/home/QuickStart.tsx +16 -7
  219. package/src/template/hooks/use-highlighted.ts +31 -19
  220. package/src/template/lib/fetch-text.ts +45 -4
  221. package/src/template/{components/Changelog/Changelog.tsx → routes/changelog/ChangelogBody.tsx} +7 -64
  222. package/src/template/routes/changelog/ChangelogSidebar.tsx +80 -0
  223. package/src/template/routes/changelog/ChangelogSidebarItem.tsx +68 -0
  224. package/src/template/routes/changelog/_.tsx +129 -0
  225. package/src/template/routes/changelog/utils.ts +13 -0
  226. package/src/template/routes/examples/name.tsx +4 -2
  227. package/src/template/routes/reference.tsx +2 -2
  228. package/src/template/routes/root.tsx +1 -1
  229. package/src/template/stores/toast.ts +6 -3
  230. package/src/template/theme/swiss-sharp.css +14 -14
  231. package/src/vite/plugins/schemas.ts +0 -1
  232. package/build/lib/graph/$$.d.ts +0 -2
  233. package/build/lib/graph/$$.d.ts.map +0 -1
  234. package/build/lib/graph/$$.js +0 -2
  235. package/build/lib/graph/$$.js.map +0 -1
  236. package/build/lib/graph/$.d.ts +0 -2
  237. package/build/lib/graph/$.d.ts.map +0 -1
  238. package/build/lib/graph/$.js +0 -2
  239. package/build/lib/graph/$.js.map +0 -1
  240. package/build/lib/graph/graph.d.ts +0 -127
  241. package/build/lib/graph/graph.d.ts.map +0 -1
  242. package/build/lib/graph/graph.js +0 -152
  243. package/build/lib/graph/graph.js.map +0 -1
  244. package/build/lib/mask/$$.d.ts +0 -3
  245. package/build/lib/mask/$$.d.ts.map +0 -1
  246. package/build/lib/mask/$$.js +0 -3
  247. package/build/lib/mask/$$.js.map +0 -1
  248. package/build/lib/mask/$.d.ts +0 -2
  249. package/build/lib/mask/$.d.ts.map +0 -1
  250. package/build/lib/mask/$.js +0 -2
  251. package/build/lib/mask/$.js.map +0 -1
  252. package/build/lib/mask/apply.d.ts +0 -86
  253. package/build/lib/mask/apply.d.ts.map +0 -1
  254. package/build/lib/mask/apply.js +0 -86
  255. package/build/lib/mask/apply.js.map +0 -1
  256. package/build/lib/mask/mask.d.ts +0 -124
  257. package/build/lib/mask/mask.d.ts.map +0 -1
  258. package/build/lib/mask/mask.js +0 -137
  259. package/build/lib/mask/mask.js.map +0 -1
  260. package/build/lib/mask/mask.test-d.d.ts +0 -2
  261. package/build/lib/mask/mask.test-d.d.ts.map +0 -1
  262. package/build/lib/mask/mask.test-d.js +0 -102
  263. package/build/lib/mask/mask.test-d.js.map +0 -1
  264. package/build/lib/version-selection/$$.d.ts +0 -2
  265. package/build/lib/version-selection/$$.d.ts.map +0 -1
  266. package/build/lib/version-selection/$$.js +0 -2
  267. package/build/lib/version-selection/$$.js.map +0 -1
  268. package/build/lib/version-selection/$.d.ts.map +0 -1
  269. package/build/lib/version-selection/$.js.map +0 -1
  270. package/build/lib/version-selection/version-selection.d.ts.map +0 -1
  271. package/build/lib/version-selection/version-selection.js.map +0 -1
  272. package/build/sandbox.d.ts +0 -2
  273. package/build/sandbox.d.ts.map +0 -1
  274. package/build/sandbox.js +0 -17
  275. package/build/sandbox.js.map +0 -1
  276. package/build/template/components/Changelog/Changelog.d.ts +0 -8
  277. package/build/template/components/Changelog/Changelog.d.ts.map +0 -1
  278. package/build/template/components/Changelog/Changelog.js.map +0 -1
  279. package/build/template/components/Changelog/ChangelogVersionPicker.d.ts +0 -8
  280. package/build/template/components/Changelog/ChangelogVersionPicker.d.ts.map +0 -1
  281. package/build/template/components/Changelog/ChangelogVersionPicker.js +0 -16
  282. package/build/template/components/Changelog/ChangelogVersionPicker.js.map +0 -1
  283. package/build/template/components/SimpleVersionPicker.d.ts +0 -15
  284. package/build/template/components/SimpleVersionPicker.d.ts.map +0 -1
  285. package/build/template/components/SimpleVersionPicker.js +0 -15
  286. package/build/template/components/SimpleVersionPicker.js.map +0 -1
  287. package/build/template/routes/changelog.d.ts +0 -1635
  288. package/build/template/routes/changelog.d.ts.map +0 -1
  289. package/build/template/routes/changelog.js +0 -168
  290. package/build/template/routes/changelog.js.map +0 -1
  291. package/src/lib/graph/$$.ts +0 -1
  292. package/src/lib/graph/$.ts +0 -1
  293. package/src/lib/graph/graph.ts +0 -197
  294. package/src/lib/mask/$$.ts +0 -2
  295. package/src/lib/mask/$.test.ts +0 -226
  296. package/src/lib/mask/$.ts +0 -1
  297. package/src/lib/mask/apply.ts +0 -134
  298. package/src/lib/mask/mask.test-d.ts +0 -156
  299. package/src/lib/mask/mask.ts +0 -244
  300. package/src/lib/version-selection/$$.ts +0 -1
  301. package/src/sandbox.ts +0 -15
  302. package/src/template/components/Changelog/ChangelogVersionPicker.tsx +0 -36
  303. package/src/template/components/SimpleVersionPicker.tsx +0 -48
  304. package/src/template/routes/changelog.tsx +0 -267
  305. /package/build/lib/{version-selection → version-coverage}/$.d.ts +0 -0
  306. /package/build/lib/{version-selection → version-coverage}/$.js +0 -0
  307. /package/src/lib/{version-selection → version-coverage}/$.ts +0 -0
@@ -1,134 +0,0 @@
1
- import { type ExtendsExact, objPolicyFilter } from '#lib/kit-temp'
2
- import { Obj } from '@wollybeard/kit'
3
- import { never } from '@wollybeard/kit/language'
4
- import type { GetDataType, Mask } from './mask.js'
5
-
6
- /**
7
- * Type-level function that applies a mask to data.
8
- *
9
- * @template Data - The data type
10
- * @template M - The mask type
11
- *
12
- * Binary masks:
13
- * - show=true returns the data unchanged
14
- * - show=false returns undefined
15
- *
16
- * Properties masks:
17
- * - 'allow' mode returns Pick<Data, keys>
18
- * - 'deny' mode returns Omit<Data, keys>
19
- * - Non-objects throw an error at runtime
20
- */
21
- // dprint-ignore
22
- export type Apply<$Data, $M extends Mask> =
23
- $M extends { type: `binary`, show: boolean }
24
- ? $M[`show`] extends true
25
- ? $Data
26
- : undefined
27
- : $M extends { type: `properties`, mode: string, properties: any[] }
28
- ? $Data extends object
29
- ? $M[`mode`] extends `allow`
30
- ? Pick<$Data, Extract<$M[`properties`][number], keyof $Data>>
31
- : Omit<$Data, Extract<$M[`properties`][number], keyof $Data>>
32
- : never // Non-objects not allowed with property masks
33
- : never
34
-
35
- /**
36
- * Apply mask to data with standard covariance.
37
- *
38
- * Data must be assignable to the mask's expected type (may have excess properties).
39
- *
40
- * @param data - The data to mask
41
- * @param mask - The mask to apply
42
- * @returns The masked data
43
- *
44
- * @example
45
- * ```ts
46
- * const user = { name: 'John', email: 'john@example.com', password: 'secret' }
47
- * const mask = Mask.pick<User>(['name', 'email'])
48
- * const safeUser = apply(user, mask) // { name: 'John', email: 'john@example.com' }
49
- * ```
50
- */
51
- export const apply = <
52
- data extends GetDataType<mask>,
53
- mask extends Mask,
54
- >(data: data, mask: mask): Apply<data, mask> => {
55
- return applyInternal(data, mask) as Apply<data, mask>
56
- }
57
-
58
- /**
59
- * Apply mask to partial data.
60
- *
61
- * Data may have only a subset of the mask's expected properties.
62
- * Useful when working with incomplete data or optional fields.
63
- *
64
- * @param data - The partial data to mask
65
- * @param mask - The mask to apply
66
- * @returns The masked data
67
- *
68
- * @example
69
- * ```ts
70
- * const partialUser = { name: 'John' } // missing email
71
- * const mask = Mask.pick<User>(['name', 'email'])
72
- * const result = applyPartial(partialUser, mask) // { name: 'John' }
73
- * ```
74
- */
75
- export const applyPartial = <
76
- data extends Partial<GetDataType<mask>>,
77
- mask extends Mask,
78
- >(data: data, mask: mask): Apply<data, mask> => {
79
- return applyInternal(data, mask) as Apply<data, mask>
80
- }
81
-
82
- /**
83
- * Apply mask to data with exact type matching.
84
- *
85
- * Data must exactly match the mask's expected type - no missing or excess properties.
86
- * Provides the strictest type checking.
87
- *
88
- * @param data - The data to mask (must exactly match expected type)
89
- * @param mask - The mask to apply
90
- * @returns The masked data
91
- *
92
- * @example
93
- * ```ts
94
- * type User = { name: string; email: string }
95
- * const mask = Mask.pick<User>(['name'])
96
- *
97
- * // This works - exact match
98
- * const user: User = { name: 'John', email: 'john@example.com' }
99
- * const result = applyExact(user, mask)
100
- *
101
- * // This fails - has extra property
102
- * const userWithExtra = { name: 'John', email: 'john@example.com', age: 30 }
103
- * const result2 = applyExact(userWithExtra, mask) // Type error!
104
- * ```
105
- */
106
- export const applyExact = <
107
- data,
108
- mask extends Mask,
109
- >(
110
- data: ExtendsExact<data, GetDataType<mask>>,
111
- mask: mask,
112
- ): Apply<data, mask> => {
113
- return applyInternal(data, mask) as Apply<data, mask>
114
- }
115
-
116
- // Internal implementation
117
- const applyInternal = (data: any, mask: Mask): any => {
118
- // ━ Handle binary mask
119
- if (mask.type === `binary`) {
120
- return mask.show ? data : undefined
121
- }
122
-
123
- // ━ Handle properties mask
124
- if (mask.type === `properties`) {
125
- // Properties mask requires object data
126
- if (!Obj.is(data)) {
127
- throw new Error(`Cannot apply properties mask to non-object data`)
128
- }
129
-
130
- return objPolicyFilter(mask.mode, data, mask.properties)
131
- }
132
-
133
- never()
134
- }
@@ -1,156 +0,0 @@
1
- import { Ts } from '@wollybeard/kit'
2
- import { Mask } from './$.js'
3
- import type { InferOptions, Mask as MaskType, PropertiesMask } from './mask.js'
4
-
5
- // Test 1: InferOptions with unknown should accept all option types
6
- {
7
- type Options = InferOptions<unknown>
8
-
9
- // This is a type-level assertion - we need to use a different pattern
10
- type _Test = Ts.AssertExact<Options, boolean | string[] | Record<string, boolean>>
11
-
12
- // All of these should be valid options
13
- const option1: Options = true
14
- const option2: Options = false
15
- const option3: Options = [`name`, `age`]
16
- const option4: Options = []
17
- const option5: Options = { name: true, age: false }
18
- const option6: Options = {}
19
- }
20
-
21
- // Test 2: Mask.create with unknown data type should accept all option types
22
- {
23
- // Boolean options
24
- const mask1 = Mask.create(true)
25
- const mask2 = Mask.create(false)
26
- // Without explicit type parameter, returns union type
27
- Ts.assertEqual<MaskType<unknown>>()(mask1)
28
- Ts.assertEqual<MaskType<unknown>>()(mask2)
29
-
30
- // Array options (no type parameter needed)
31
- const mask3 = Mask.create([`name`, `age`])
32
- const mask4 = Mask.create([])
33
- const mask5 = Mask.create([`a`, `b`, `c`])
34
- // Returns union type with inferred properties
35
- Ts.assertEqual<MaskType<{ name: any; age: any }>>()(mask3)
36
- Ts.assertEqual<MaskType<unknown>>()(mask4)
37
- Ts.assertEqual<MaskType<{ a: any; b: any; c: any }>>()(mask5)
38
-
39
- // Object options
40
- const mask6 = Mask.create({ name: true, age: false })
41
- const mask7 = Mask.create({})
42
- const mask8 = Mask.create({ foo: true, bar: true, baz: false })
43
- // Returns union type with inferred properties
44
- Ts.assertEqual<MaskType<unknown>>()(mask6)
45
- Ts.assertEqual<MaskType<unknown>>()(mask7)
46
- Ts.assertEqual<MaskType<unknown>>()(mask8)
47
- }
48
-
49
- // Test 3: With specific data type, options are constrained
50
- {
51
- interface User {
52
- name: string
53
- age: number
54
- email: string
55
- }
56
-
57
- // Valid options
58
- const mask1 = Mask.create<User>(true)
59
- const mask2 = Mask.create<User>([`name`, `age`])
60
- const mask3 = Mask.create<User>({ name: true, age: false, email: true })
61
-
62
- // With explicit type parameter, still returns union type
63
- Ts.assertEqual<MaskType<User>>()(mask1)
64
- Ts.assertEqual<MaskType<User>>()(mask2)
65
- Ts.assertEqual<MaskType<User>>()(mask3)
66
-
67
- // Invalid cases would be compile errors
68
- // const mask4 = Mask.create<User>(['invalid']) // Error: 'invalid' is not a key of User
69
- // const mask5 = Mask.create<User>({ invalid: true }) // Error: 'invalid' is not a property of User
70
- }
71
-
72
- // Test 4: Non-object types only accept boolean
73
- {
74
- const mask1 = Mask.create<string>(true)
75
- const mask2 = Mask.create<string>(false)
76
-
77
- Ts.assertEqual<MaskType<string>>()(mask1)
78
- Ts.assertEqual<MaskType<string>>()(mask2)
79
-
80
- // Invalid cases would be compile errors
81
- // const mask3 = Mask.create<string>(['prop']) // Error: string is not an object
82
- // const mask4 = Mask.create<string>({ prop: true }) // Error: string is not an object
83
- }
84
-
85
- // Test 5: Test inference in practical scenarios
86
- {
87
- // Should infer PropertiesMask with object data type
88
- const userMask = Mask.create([`name`, `email`, `password`])
89
- Ts.assertEqual<MaskType<{ name: any; email: any; password: any }>>()(userMask)
90
-
91
- // When mask is a union type, apply returns a union of possible results
92
- const user1 = { name: `John`, email: `john@example.com`, password: `secret`, extra: `data` }
93
- const maskedUser1 = Mask.apply(user1, userMask)
94
- // Result is a union type that includes the properties mask result
95
- type MaskedUser1 = typeof maskedUser1
96
- // Can't use assertSub with union types
97
-
98
- // For partial data, use applyPartial
99
- const user2 = { name: `Jane`, email: `jane@example.com` }
100
- const maskedUser2 = Mask.applyPartial(user2, userMask)
101
- // Result is a union type
102
- type MaskedUser2 = typeof maskedUser2
103
- }
104
-
105
- // Test 6: Pick and omit helpers
106
- {
107
- const pick1 = Mask.pick([`name`, `email`])
108
- const omit1 = Mask.omit([`password`, `secret`])
109
-
110
- // Infers specific property types
111
- Ts.assertEqual<PropertiesMask<{ name: any; email: any }>>()(pick1)
112
- Ts.assertEqual<PropertiesMask<{ password: any; secret: any }>>()(omit1)
113
-
114
- interface User {
115
- name: string
116
- email: string
117
- password: string
118
- }
119
- const pick2 = Mask.pick<User>([`name`, `email`])
120
- const omit2 = Mask.omit<User>([`password`])
121
-
122
- Ts.assertEqual<PropertiesMask<User>>()(pick2)
123
- Ts.assertEqual<PropertiesMask<User>>()(omit2)
124
- }
125
-
126
- // Test 7: Apply type transformations
127
- {
128
- interface User {
129
- name: string
130
- email: string
131
- password: string
132
- }
133
- const user: User = { name: `John`, email: `john@example.com`, password: `secret` }
134
-
135
- // Binary mask
136
- const showMask = Mask.create<User>(true)
137
- const hideMask = Mask.create<User>(false)
138
- const shown = Mask.apply(user, showMask)
139
- const hidden = Mask.apply(user, hideMask)
140
-
141
- // showMask and hideMask are MaskType<User> (union types), so results are unions
142
- type ShownType = typeof shown // Omit<User, keyof User> | undefined
143
- type HiddenType = typeof hidden // Omit<User, keyof User> | undefined
144
-
145
- // Properties mask - allow mode
146
- const allowMask = Mask.create<User>([`name`, `email`])
147
- const allowed = Mask.apply(user, allowMask)
148
- // Result is a union due to mask being a union type
149
- type AllowedType = typeof allowed
150
-
151
- // Properties mask - deny mode
152
- const denyMask = Mask.create<User>({ password: false })
153
- const denied = Mask.apply(user, denyMask)
154
- // Result is a union due to mask being a union type
155
- type DeniedType = typeof denied
156
- }
@@ -1,244 +0,0 @@
1
- //
2
- //
3
- //
4
- //
5
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Mask
6
- //
7
- //
8
-
9
- /**
10
- * A mask that can either hide/show data entirely (BinaryMask) or
11
- * selectively hide/show object properties (PropertiesMask).
12
- *
13
- * @template $Data - The data type being masked
14
- */
15
- export type Mask<$Data = any> = BinaryMask<$Data> | PropertiesMask<$Data extends object ? $Data : object>
16
-
17
- /**
18
- * Create a mask based on the provided options.
19
- *
20
- * @param options - Mask configuration:
21
- * - `boolean`: Creates a binary mask (true = show, false = hide)
22
- * - `string[]`: Creates a properties mask that allows only the specified keys
23
- * - `object`: Creates a properties mask based on true/false values per key
24
- *
25
- * @returns A mask that can be applied to data
26
- *
27
- * @example
28
- * ```ts
29
- * // Binary mask
30
- * const showAll = create(true)
31
- * const hideAll = create(false)
32
- *
33
- * // Properties mask with array
34
- * const allowMask = create<User>(['name', 'email'])
35
- *
36
- * // Properties mask with object
37
- * const objectMask = create<User>({
38
- * name: true,
39
- * email: true,
40
- * password: false
41
- * })
42
- * ```
43
- */
44
- export const create = <$Data = unknown>(
45
- options: InferOptions<$Data>,
46
- ): Mask<$Data> => {
47
- if (typeof options === `boolean`) {
48
- return createBinary(options) as any
49
- }
50
-
51
- // Array input -> PropertiesMask with 'allow' mode
52
- if (Array.isArray(options)) {
53
- return createProperties(`allow`, options as any) as any
54
- }
55
-
56
- // Object input -> PropertiesMask based on true/false values
57
- const entries = Object.entries(options)
58
-
59
- const allowedKeys = entries
60
- .filter(([_, include]) => include === true)
61
- .map(([key]) => key)
62
-
63
- const deniedKeys = entries
64
- .filter(([_, include]) => include === false)
65
- .map(([key]) => key)
66
-
67
- // If we have denied keys, use deny mode
68
- if (deniedKeys.length > 0 && allowedKeys.length === 0) {
69
- return createProperties(`deny`, deniedKeys) as any
70
- }
71
-
72
- // Default to allow mode with allowed keys
73
- return createProperties(`allow`, allowedKeys) as any
74
- }
75
-
76
- /**
77
- * Valid options for creating a mask for the given data type.
78
- *
79
- * @template $Data - The data type to be masked
80
- */
81
- export type InferOptions<$Data> = unknown extends $Data ? boolean | string[] | Record<string, boolean>
82
- : $Data extends object ? (
83
- | boolean
84
- | (keyof $Data)[]
85
- | Partial<
86
- {
87
- [K in keyof $Data]: boolean
88
- }
89
- >
90
- )
91
- : boolean
92
-
93
- //
94
- //
95
- //
96
- //
97
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • PropertiesMask
98
- //
99
- //
100
-
101
- /**
102
- * A mask that selectively shows or hides object properties.
103
- *
104
- * @template $Data - The object type being masked
105
- */
106
- export interface PropertiesMask<$Data extends object = object> {
107
- type: `properties`
108
- /** Whether to allow only specified properties or deny them */
109
- mode: `allow` | `deny`
110
- /** The list of property keys to allow or deny */
111
- properties: (keyof $Data)[]
112
- }
113
-
114
- /**
115
- * Create a properties mask.
116
- *
117
- * @param mode - 'allow' to show only specified properties, 'deny' to hide them
118
- * @param properties - Array of property keys to allow or deny
119
- * @returns A PropertiesMask
120
- */
121
- export const createProperties = <$Data extends object = object>(
122
- mode: `allow` | `deny`,
123
- properties: (keyof $Data)[],
124
- ): PropertiesMask<$Data> => ({
125
- type: `properties`,
126
- mode,
127
- properties,
128
- })
129
-
130
- //
131
- //
132
- //
133
- //
134
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • BinaryMask
135
- //
136
- //
137
-
138
- /**
139
- * A mask that either shows or hides data entirely.
140
- *
141
- * @template _$Data - The data type being masked (used for type inference)
142
- */
143
- export interface BinaryMask<_$Data = any> {
144
- type: `binary`
145
- /** Whether to show (true) or hide (false) the data */
146
- show: boolean
147
- }
148
-
149
- /**
150
- * Create a binary mask.
151
- *
152
- * @param show - Whether to show (true) or hide (false) the data
153
- * @returns A BinaryMask
154
- */
155
- export const createBinary = <$Data = any>(show: boolean): BinaryMask<$Data> => ({
156
- type: `binary`,
157
- show,
158
- })
159
-
160
- //
161
- //
162
- //
163
- //
164
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Convenience Constructors with Semantic Names
165
- //
166
- //
167
-
168
- /**
169
- * Create a mask that shows all data.
170
- * @returns A BinaryMask with show=true
171
- */
172
- export const show = (): BinaryMask => ({
173
- type: `binary`,
174
- show: true,
175
- })
176
-
177
- /**
178
- * Create a mask that hides all data.
179
- * @returns A BinaryMask with show=false
180
- */
181
- export const hide = (): BinaryMask => ({
182
- type: `binary`,
183
- show: false,
184
- })
185
-
186
- /**
187
- * Create a mask that shows only the specified properties.
188
- *
189
- * @param properties - Array of property keys to show
190
- * @returns A PropertiesMask in 'allow' mode
191
- *
192
- * @example
193
- * ```ts
194
- * const userMask = pick<User>(['name', 'email'])
195
- * // Only 'name' and 'email' will be shown
196
- * ```
197
- */
198
- export const pick = <$Data extends object = object>(
199
- properties: (keyof $Data)[],
200
- ): PropertiesMask<$Data> => ({
201
- type: `properties`,
202
- mode: `allow`,
203
- properties,
204
- })
205
-
206
- /**
207
- * Create a mask that hides the specified properties.
208
- *
209
- * @param properties - Array of property keys to hide
210
- * @returns A PropertiesMask in 'deny' mode
211
- *
212
- * @example
213
- * ```ts
214
- * const userMask = omit<User>(['password', 'ssn'])
215
- * // Everything except 'password' and 'ssn' will be shown
216
- * ```
217
- */
218
- export const omit = <$Data extends object = object>(
219
- properties: (keyof $Data)[],
220
- ): PropertiesMask<$Data> => ({
221
- type: `properties`,
222
- mode: `deny`,
223
- properties,
224
- })
225
-
226
- //
227
- //
228
- //
229
- //
230
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Utilities
231
- //
232
- //
233
-
234
- /**
235
- * Extract the data type from a mask.
236
- *
237
- * @template $Mask - The mask type
238
- * @returns The data type the mask is designed for
239
- */
240
- // dprint-ignore
241
- export type GetDataType<$Mask extends Mask> =
242
- $Mask extends BinaryMask<infer $Data> ? $Data :
243
- $Mask extends PropertiesMask<infer $Data> ? $Data
244
- : never
@@ -1 +0,0 @@
1
- export * from './version-selection.js'
package/src/sandbox.ts DELETED
@@ -1,15 +0,0 @@
1
- //
2
- //
3
- //
4
- //
5
- //
6
- // Temporary Work File
7
- //
8
- // ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
9
- //
10
- // – Use freely
11
- // – Try to remember to not commit changes
12
- // – Included by development TypeScript configuration
13
- // – Excluded by build TypeScript configuration
14
- //
15
- //
@@ -1,36 +0,0 @@
1
- import { Select } from '@radix-ui/themes'
2
- import React from 'react'
3
- import { useNavigate } from 'react-router'
4
-
5
- interface Props {
6
- versions: string[]
7
- currentVersion: string
8
- }
9
-
10
- export const ChangelogVersionPicker: React.FC<Props> = ({ versions, currentVersion }) => {
11
- const navigate = useNavigate()
12
-
13
- // Don't show selector if only one version
14
- if (versions.length <= 1) {
15
- return null
16
- }
17
-
18
- const handleVersionChange = (newVersion: string) => {
19
- navigate(`/changelog/version/${newVersion}`)
20
- }
21
-
22
- return (
23
- <Select.Root value={currentVersion} onValueChange={handleVersionChange}>
24
- <Select.Trigger>
25
- Version {currentVersion}
26
- </Select.Trigger>
27
- <Select.Content>
28
- {versions.map(version => (
29
- <Select.Item key={version} value={version}>
30
- Version {version}
31
- </Select.Item>
32
- ))}
33
- </Select.Content>
34
- </Select.Root>
35
- )
36
- }
@@ -1,48 +0,0 @@
1
- import { Version } from '#lib/version/$'
2
- import { Select } from '@radix-ui/themes'
3
- import type * as React from 'react'
4
-
5
- interface Props {
6
- versions: readonly Version.Version[]
7
- currentVersion: Version.Version
8
- onVersionChange: (version: Version.Version) => void
9
- label?: string
10
- }
11
-
12
- /**
13
- * A generic version picker component that can be used for any versioned content.
14
- * This is a controlled component - parent manages the state.
15
- */
16
- export const SimpleVersionPicker: React.FC<Props> = ({
17
- versions,
18
- currentVersion,
19
- onVersionChange,
20
- label = '',
21
- }) => {
22
- // Don't show selector if only one version
23
- if (versions.length <= 1) {
24
- return null
25
- }
26
-
27
- return (
28
- <Select.Root
29
- value={Version.encodeSync(currentVersion)}
30
- onValueChange={(versionEncoded) => onVersionChange(Version.fromString(versionEncoded))}
31
- >
32
- <Select.Trigger style={{ minWidth: '120px' }}>
33
- {label}
34
- {label ? ' ' : ''}
35
- {Version.encodeSync(currentVersion)}
36
- </Select.Trigger>
37
- <Select.Content position='popper' sideOffset={5}>
38
- {versions.map(version => (
39
- <Select.Item key={Version.encodeSync(version)} value={Version.encodeSync(version)}>
40
- {label}
41
- {label ? ' ' : ''}
42
- {Version.encodeSync(version)}
43
- </Select.Item>
44
- ))}
45
- </Select.Content>
46
- </Select.Root>
47
- )
48
- }