@kensio/colophon 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/README.md +608 -34
  2. package/dist/cli/args.d.ts +14 -0
  3. package/dist/cli/args.d.ts.map +1 -0
  4. package/dist/cli/args.js +67 -0
  5. package/dist/cli/args.js.map +1 -0
  6. package/dist/cli/config.d.ts +12 -0
  7. package/dist/cli/config.d.ts.map +1 -0
  8. package/dist/cli/config.js +43 -0
  9. package/dist/cli/config.js.map +1 -0
  10. package/dist/cli/index.d.ts +3 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +35 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli.js +34 -6
  15. package/dist/cli.js.map +1 -1
  16. package/dist/config/defaults.d.ts +64 -0
  17. package/dist/config/defaults.d.ts.map +1 -0
  18. package/dist/config/defaults.js +64 -0
  19. package/dist/config/defaults.js.map +1 -0
  20. package/dist/config/index.d.ts +22 -0
  21. package/dist/config/index.d.ts.map +1 -0
  22. package/dist/config/index.js +52 -0
  23. package/dist/config/index.js.map +1 -0
  24. package/dist/config/resolve.d.ts +24 -0
  25. package/dist/config/resolve.d.ts.map +1 -0
  26. package/dist/config/resolve.js +66 -0
  27. package/dist/config/resolve.js.map +1 -0
  28. package/dist/config/size.d.ts +20 -0
  29. package/dist/config/size.d.ts.map +1 -0
  30. package/dist/config/size.js +46 -0
  31. package/dist/config/size.js.map +1 -0
  32. package/dist/config.d.ts +33 -2
  33. package/dist/config.d.ts.map +1 -1
  34. package/dist/config.js +94 -4
  35. package/dist/config.js.map +1 -1
  36. package/dist/content/index.d.ts +5 -51
  37. package/dist/content/index.d.ts.map +1 -1
  38. package/dist/content/index.js +3 -115
  39. package/dist/content/index.js.map +1 -1
  40. package/dist/content/props.d.ts +15 -0
  41. package/dist/content/props.d.ts.map +1 -0
  42. package/dist/content/props.js +71 -0
  43. package/dist/content/props.js.map +1 -0
  44. package/dist/content/slug.d.ts +23 -0
  45. package/dist/content/slug.d.ts.map +1 -0
  46. package/dist/content/slug.js +52 -0
  47. package/dist/content/slug.js.map +1 -0
  48. package/dist/content/walk.d.ts +17 -0
  49. package/dist/content/walk.d.ts.map +1 -0
  50. package/dist/content/walk.js +57 -0
  51. package/dist/content/walk.js.map +1 -0
  52. package/dist/fonts/index.d.ts +10 -0
  53. package/dist/fonts/index.d.ts.map +1 -0
  54. package/dist/fonts/index.js +11 -0
  55. package/dist/fonts/index.js.map +1 -0
  56. package/dist/fonts/materialise.d.ts +7 -0
  57. package/dist/fonts/materialise.d.ts.map +1 -0
  58. package/dist/fonts/materialise.js +47 -0
  59. package/dist/fonts/materialise.js.map +1 -0
  60. package/dist/fonts/resolve.d.ts +7 -0
  61. package/dist/fonts/resolve.d.ts.map +1 -0
  62. package/dist/fonts/resolve.js +50 -0
  63. package/dist/fonts/resolve.js.map +1 -0
  64. package/dist/fonts.d.ts +18 -0
  65. package/dist/fonts.d.ts.map +1 -0
  66. package/dist/fonts.js +102 -0
  67. package/dist/fonts.js.map +1 -0
  68. package/dist/generate/extra.d.ts +16 -0
  69. package/dist/generate/extra.d.ts.map +1 -0
  70. package/dist/generate/extra.js +60 -0
  71. package/dist/generate/extra.js.map +1 -0
  72. package/dist/generate/index.d.ts +19 -0
  73. package/dist/generate/index.d.ts.map +1 -0
  74. package/dist/generate/index.js +46 -0
  75. package/dist/generate/index.js.map +1 -0
  76. package/dist/generate/job.d.ts +35 -0
  77. package/dist/generate/job.d.ts.map +1 -0
  78. package/dist/generate/job.js +2 -0
  79. package/dist/generate/job.js.map +1 -0
  80. package/dist/generate/options.d.ts +56 -0
  81. package/dist/generate/options.d.ts.map +1 -0
  82. package/dist/generate/options.js +17 -0
  83. package/dist/generate/options.js.map +1 -0
  84. package/dist/generate/output-path.d.ts +12 -0
  85. package/dist/generate/output-path.d.ts.map +1 -0
  86. package/dist/generate/output-path.js +18 -0
  87. package/dist/generate/output-path.js.map +1 -0
  88. package/dist/generate/outputs.d.ts +28 -0
  89. package/dist/generate/outputs.d.ts.map +1 -0
  90. package/dist/generate/outputs.js +71 -0
  91. package/dist/generate/outputs.js.map +1 -0
  92. package/dist/generate/plan.d.ts +21 -0
  93. package/dist/generate/plan.d.ts.map +1 -0
  94. package/dist/generate/plan.js +72 -0
  95. package/dist/generate/plan.js.map +1 -0
  96. package/dist/generate/render-image.d.ts +11 -0
  97. package/dist/generate/render-image.d.ts.map +1 -0
  98. package/dist/generate/render-image.js +27 -0
  99. package/dist/generate/render-image.js.map +1 -0
  100. package/dist/generate.d.ts +27 -6
  101. package/dist/generate.d.ts.map +1 -1
  102. package/dist/generate.js +77 -15
  103. package/dist/generate.js.map +1 -1
  104. package/dist/highlight/color.d.ts +9 -0
  105. package/dist/highlight/color.d.ts.map +1 -0
  106. package/dist/highlight/color.js +15 -0
  107. package/dist/highlight/color.js.map +1 -0
  108. package/dist/highlight/grid.d.ts +14 -0
  109. package/dist/highlight/grid.d.ts.map +1 -0
  110. package/dist/highlight/grid.js +36 -0
  111. package/dist/highlight/grid.js.map +1 -0
  112. package/dist/highlight/index.d.ts +12 -0
  113. package/dist/highlight/index.d.ts.map +1 -0
  114. package/dist/highlight/index.js +31 -0
  115. package/dist/highlight/index.js.map +1 -0
  116. package/dist/highlight/language.d.ts +14 -0
  117. package/dist/highlight/language.d.ts.map +1 -0
  118. package/dist/highlight/language.js +42 -0
  119. package/dist/highlight/language.js.map +1 -0
  120. package/dist/highlight/normalise.d.ts +17 -0
  121. package/dist/highlight/normalise.d.ts.map +1 -0
  122. package/dist/highlight/normalise.js +37 -0
  123. package/dist/highlight/normalise.js.map +1 -0
  124. package/dist/highlight/types.d.ts +40 -0
  125. package/dist/highlight/types.d.ts.map +1 -0
  126. package/dist/highlight/types.js +2 -0
  127. package/dist/highlight/types.js.map +1 -0
  128. package/dist/highlight.d.ts +10 -0
  129. package/dist/highlight.d.ts.map +1 -1
  130. package/dist/highlight.js +25 -2
  131. package/dist/highlight.js.map +1 -1
  132. package/dist/index.d.ts +15 -9
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +9 -5
  135. package/dist/index.js.map +1 -1
  136. package/dist/manifest/build.d.ts +14 -0
  137. package/dist/manifest/build.d.ts.map +1 -0
  138. package/dist/manifest/build.js +43 -0
  139. package/dist/manifest/build.js.map +1 -0
  140. package/dist/manifest/index.d.ts +27 -0
  141. package/dist/manifest/index.d.ts.map +1 -0
  142. package/dist/manifest/index.js +31 -0
  143. package/dist/manifest/index.js.map +1 -0
  144. package/dist/manifest/order.d.ts +12 -0
  145. package/dist/manifest/order.d.ts.map +1 -0
  146. package/dist/manifest/order.js +17 -0
  147. package/dist/manifest/order.js.map +1 -0
  148. package/dist/manifest/page.d.ts +24 -0
  149. package/dist/manifest/page.d.ts.map +1 -0
  150. package/dist/manifest/page.js +55 -0
  151. package/dist/manifest/page.js.map +1 -0
  152. package/dist/meta/html.d.ts +14 -0
  153. package/dist/meta/html.d.ts.map +1 -0
  154. package/dist/meta/html.js +24 -0
  155. package/dist/meta/html.js.map +1 -0
  156. package/dist/meta/index.d.ts +11 -0
  157. package/dist/meta/index.d.ts.map +1 -0
  158. package/dist/meta/index.js +11 -0
  159. package/dist/meta/index.js.map +1 -0
  160. package/dist/meta/tags.d.ts +21 -0
  161. package/dist/meta/tags.d.ts.map +1 -0
  162. package/dist/meta/tags.js +72 -0
  163. package/dist/meta/tags.js.map +1 -0
  164. package/dist/meta/url.d.ts +15 -0
  165. package/dist/meta/url.d.ts.map +1 -0
  166. package/dist/meta/url.js +34 -0
  167. package/dist/meta/url.js.map +1 -0
  168. package/dist/placement/check.d.ts +16 -0
  169. package/dist/placement/check.d.ts.map +1 -0
  170. package/dist/placement/check.js +40 -0
  171. package/dist/placement/check.js.map +1 -0
  172. package/dist/placement/index.d.ts +29 -0
  173. package/dist/placement/index.d.ts.map +1 -0
  174. package/dist/placement/index.js +61 -0
  175. package/dist/placement/index.js.map +1 -0
  176. package/dist/placement/relative.d.ts +31 -0
  177. package/dist/placement/relative.d.ts.map +1 -0
  178. package/dist/placement/relative.js +53 -0
  179. package/dist/placement/relative.js.map +1 -0
  180. package/dist/pool.d.ts +18 -0
  181. package/dist/pool.d.ts.map +1 -0
  182. package/dist/pool.js +56 -0
  183. package/dist/pool.js.map +1 -0
  184. package/dist/render/index.d.ts +10 -0
  185. package/dist/render/index.d.ts.map +1 -0
  186. package/dist/render/index.js +27 -0
  187. package/dist/render/index.js.map +1 -0
  188. package/dist/render/png.d.ts +10 -0
  189. package/dist/render/png.d.ts.map +1 -0
  190. package/dist/render/png.js +30 -0
  191. package/dist/render/png.js.map +1 -0
  192. package/dist/render/svg.d.ts +10 -0
  193. package/dist/render/svg.d.ts.map +1 -0
  194. package/dist/render/svg.js +20 -0
  195. package/dist/render/svg.js.map +1 -0
  196. package/dist/render/template.d.ts +9 -0
  197. package/dist/render/template.d.ts.map +1 -0
  198. package/dist/render/template.js +17 -0
  199. package/dist/render/template.js.map +1 -0
  200. package/dist/render.d.ts +6 -2
  201. package/dist/render.d.ts.map +1 -1
  202. package/dist/render.js +31 -10
  203. package/dist/render.js.map +1 -1
  204. package/dist/stamp/chunk.d.ts +16 -0
  205. package/dist/stamp/chunk.d.ts.map +1 -0
  206. package/dist/stamp/chunk.js +46 -0
  207. package/dist/stamp/chunk.js.map +1 -0
  208. package/dist/stamp/config-digest.d.ts +11 -0
  209. package/dist/stamp/config-digest.d.ts.map +1 -0
  210. package/dist/stamp/config-digest.js +43 -0
  211. package/dist/stamp/config-digest.js.map +1 -0
  212. package/dist/stamp/digest.d.ts +8 -0
  213. package/dist/stamp/digest.d.ts.map +1 -0
  214. package/dist/stamp/digest.js +20 -0
  215. package/dist/stamp/digest.js.map +1 -0
  216. package/dist/stamp/index.d.ts +20 -0
  217. package/dist/stamp/index.d.ts.map +1 -0
  218. package/dist/stamp/index.js +40 -0
  219. package/dist/stamp/index.js.map +1 -0
  220. package/dist/stamp/read.d.ts +7 -0
  221. package/dist/stamp/read.d.ts.map +1 -0
  222. package/dist/stamp/read.js +62 -0
  223. package/dist/stamp/read.js.map +1 -0
  224. package/dist/stamp.d.ts +29 -0
  225. package/dist/stamp.d.ts.map +1 -0
  226. package/dist/stamp.js +198 -0
  227. package/dist/stamp.js.map +1 -0
  228. package/dist/templates/banner/badge.d.ts +7 -0
  229. package/dist/templates/banner/badge.d.ts.map +1 -0
  230. package/dist/templates/banner/badge.js +24 -0
  231. package/dist/templates/banner/badge.js.map +1 -0
  232. package/dist/templates/banner/index.d.ts +9 -0
  233. package/dist/templates/banner/index.d.ts.map +1 -0
  234. package/dist/templates/banner/index.js +66 -0
  235. package/dist/templates/banner/index.js.map +1 -0
  236. package/dist/templates/banner/lines.d.ts +27 -0
  237. package/dist/templates/banner/lines.d.ts.map +1 -0
  238. package/dist/templates/banner/lines.js +46 -0
  239. package/dist/templates/banner/lines.js.map +1 -0
  240. package/dist/templates/card/index.d.ts +7 -0
  241. package/dist/templates/card/index.d.ts.map +1 -0
  242. package/dist/templates/card/index.js +43 -0
  243. package/dist/templates/card/index.js.map +1 -0
  244. package/dist/templates/card/lines.d.ts +17 -0
  245. package/dist/templates/card/lines.d.ts.map +1 -0
  246. package/dist/templates/card/lines.js +32 -0
  247. package/dist/templates/card/lines.js.map +1 -0
  248. package/dist/templates/code/chrome.d.ts +9 -0
  249. package/dist/templates/code/chrome.d.ts.map +1 -0
  250. package/dist/templates/code/chrome.js +32 -0
  251. package/dist/templates/code/chrome.js.map +1 -0
  252. package/dist/templates/code/clip.d.ts +18 -0
  253. package/dist/templates/code/clip.d.ts.map +1 -0
  254. package/dist/templates/code/clip.js +44 -0
  255. package/dist/templates/code/clip.js.map +1 -0
  256. package/dist/templates/code/ellipsis.d.ts +3 -0
  257. package/dist/templates/code/ellipsis.d.ts.map +1 -0
  258. package/dist/templates/code/ellipsis.js +3 -0
  259. package/dist/templates/code/ellipsis.js.map +1 -0
  260. package/dist/templates/code/fit.d.ts +27 -0
  261. package/dist/templates/code/fit.d.ts.map +1 -0
  262. package/dist/templates/code/fit.js +59 -0
  263. package/dist/templates/code/fit.js.map +1 -0
  264. package/dist/templates/code/index.d.ts +12 -0
  265. package/dist/templates/code/index.d.ts.map +1 -0
  266. package/dist/templates/code/index.js +64 -0
  267. package/dist/templates/code/index.js.map +1 -0
  268. package/dist/templates/code/layout.d.ts +21 -0
  269. package/dist/templates/code/layout.d.ts.map +1 -0
  270. package/dist/templates/code/layout.js +21 -0
  271. package/dist/templates/code/layout.js.map +1 -0
  272. package/dist/templates/code/panel.d.ts +17 -0
  273. package/dist/templates/code/panel.d.ts.map +1 -0
  274. package/dist/templates/code/panel.js +20 -0
  275. package/dist/templates/code/panel.js.map +1 -0
  276. package/dist/templates/code/plate.d.ts +15 -0
  277. package/dist/templates/code/plate.d.ts.map +1 -0
  278. package/dist/templates/code/plate.js +32 -0
  279. package/dist/templates/code/plate.js.map +1 -0
  280. package/dist/templates/code/spans.d.ts +19 -0
  281. package/dist/templates/code/spans.d.ts.map +1 -0
  282. package/dist/templates/code/spans.js +36 -0
  283. package/dist/templates/code/spans.js.map +1 -0
  284. package/dist/templates/code/warn.d.ts +11 -0
  285. package/dist/templates/code/warn.d.ts.map +1 -0
  286. package/dist/templates/code/warn.js +24 -0
  287. package/dist/templates/code/warn.js.map +1 -0
  288. package/dist/templates/code.d.ts.map +1 -1
  289. package/dist/templates/code.js +101 -29
  290. package/dist/templates/code.js.map +1 -1
  291. package/dist/templates/footer.d.ts +21 -0
  292. package/dist/templates/footer.d.ts.map +1 -0
  293. package/dist/templates/footer.js +25 -0
  294. package/dist/templates/footer.js.map +1 -0
  295. package/dist/templates/index.d.ts +3 -3
  296. package/dist/templates/index.d.ts.map +1 -1
  297. package/dist/templates/index.js +6 -6
  298. package/dist/templates/index.js.map +1 -1
  299. package/dist/text/element.d.ts +18 -0
  300. package/dist/text/element.d.ts.map +1 -0
  301. package/dist/text/element.js +19 -0
  302. package/dist/text/element.js.map +1 -0
  303. package/dist/text/escape.d.ts +5 -0
  304. package/dist/text/escape.d.ts.map +1 -0
  305. package/dist/text/escape.js +12 -0
  306. package/dist/text/escape.js.map +1 -0
  307. package/dist/text/index.d.ts +7 -0
  308. package/dist/text/index.d.ts.map +1 -0
  309. package/dist/text/index.js +5 -0
  310. package/dist/text/index.js.map +1 -0
  311. package/dist/text/stack.d.ts +24 -0
  312. package/dist/text/stack.d.ts.map +1 -0
  313. package/dist/text/stack.js +18 -0
  314. package/dist/text/stack.js.map +1 -0
  315. package/dist/text/wrap.d.ts +12 -0
  316. package/dist/text/wrap.d.ts.map +1 -0
  317. package/dist/text/wrap.js +33 -0
  318. package/dist/text/wrap.js.map +1 -0
  319. package/dist/types.d.ts +345 -6
  320. package/dist/types.d.ts.map +1 -1
  321. package/dist/validate/check.d.ts +13 -0
  322. package/dist/validate/check.d.ts.map +1 -0
  323. package/dist/validate/check.js +34 -0
  324. package/dist/validate/check.js.map +1 -0
  325. package/dist/validate/index.d.ts +15 -0
  326. package/dist/validate/index.d.ts.map +1 -0
  327. package/dist/validate/index.js +41 -0
  328. package/dist/validate/index.js.map +1 -0
  329. package/dist/validate/keys.d.ts +58 -0
  330. package/dist/validate/keys.d.ts.map +1 -0
  331. package/dist/validate/keys.js +166 -0
  332. package/dist/validate/keys.js.map +1 -0
  333. package/dist/validate/overrides.d.ts +5 -0
  334. package/dist/validate/overrides.d.ts.map +1 -0
  335. package/dist/validate/overrides.js +43 -0
  336. package/dist/validate/overrides.js.map +1 -0
  337. package/dist/validate/placement.d.ts +10 -0
  338. package/dist/validate/placement.d.ts.map +1 -0
  339. package/dist/validate/placement.js +38 -0
  340. package/dist/validate/placement.js.map +1 -0
  341. package/dist/validate/sizes.d.ts +9 -0
  342. package/dist/validate/sizes.d.ts.map +1 -0
  343. package/dist/validate/sizes.js +27 -0
  344. package/dist/validate/sizes.js.map +1 -0
  345. package/dist/validate/suggest.d.ts +10 -0
  346. package/dist/validate/suggest.d.ts.map +1 -0
  347. package/dist/validate/suggest.js +55 -0
  348. package/dist/validate/suggest.js.map +1 -0
  349. package/dist/validate/values.d.ts +21 -0
  350. package/dist/validate/values.d.ts.map +1 -0
  351. package/dist/validate/values.js +57 -0
  352. package/dist/validate/values.js.map +1 -0
  353. package/dist/validate.d.ts +15 -0
  354. package/dist/validate.d.ts.map +1 -0
  355. package/dist/validate.js +300 -0
  356. package/dist/validate.js.map +1 -0
  357. package/package.json +14 -7
@@ -0,0 +1,20 @@
1
+ import type { ColophonConfig, OutputSize, ResolvedConfig } from "../types.js";
2
+ /**
3
+ * Apply a size's own overrides to a config and resolve the result: the config
4
+ * one image is actually rendered with.
5
+ *
6
+ * The overrides are folded into the user config and the whole thing resolved
7
+ * again, rather than patched onto an already-resolved config, so that anything
8
+ * derived stays consistent — a size that overrides `colors.brand` gets the
9
+ * default gradient rebuilt around its brand, exactly as a config setting the
10
+ * same colour at the top level would.
11
+ *
12
+ * `colors` and `code` merge over their config-level counterparts, because both
13
+ * are bags of independent settings and the point of the feature is to change
14
+ * one of them. The rest replace: a `background` is a union whose variants have
15
+ * different keys, so half of one over half of another is not a background at
16
+ * all, and `badge` carries a required `text` that a partial override could not
17
+ * supply.
18
+ */
19
+ export declare function resolveConfigForSize(config: ColophonConfig | undefined, size: OutputSize): ResolvedConfig;
20
+ //# sourceMappingURL=size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.d.ts","sourceRoot":"","sources":["../../src/config/size.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,UAAU,EACV,cAAc,EACf,MAAM,aAAa,CAAC;AAoBrB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,IAAI,EAAE,UAAU,GACf,cAAc,CAchB"}
@@ -0,0 +1,46 @@
1
+ import { DEFAULT_COLORS } from "./defaults.js";
2
+ import { resolveConfig } from "./index.js";
3
+ /**
4
+ * Merge a size's colour overrides onto the config's.
5
+ *
6
+ * A size may name any single shade, so the merge starts from the full default
7
+ * palette when the config sets no colours of its own. Starting from nothing
8
+ * instead would hand `resolveColors` a lone `foreground`, and its rule that a
9
+ * bare `brand` colours the whole gradient would then flatten the default
10
+ * gradient — a size asking only for darker text would silently lose it.
11
+ */
12
+ function mergeColors(base, overrides) {
13
+ return { ...(base ?? DEFAULT_COLORS), ...overrides };
14
+ }
15
+ /**
16
+ * Apply a size's own overrides to a config and resolve the result: the config
17
+ * one image is actually rendered with.
18
+ *
19
+ * The overrides are folded into the user config and the whole thing resolved
20
+ * again, rather than patched onto an already-resolved config, so that anything
21
+ * derived stays consistent — a size that overrides `colors.brand` gets the
22
+ * default gradient rebuilt around its brand, exactly as a config setting the
23
+ * same colour at the top level would.
24
+ *
25
+ * `colors` and `code` merge over their config-level counterparts, because both
26
+ * are bags of independent settings and the point of the feature is to change
27
+ * one of them. The rest replace: a `background` is a union whose variants have
28
+ * different keys, so half of one over half of another is not a background at
29
+ * all, and `badge` carries a required `text` that a partial override could not
30
+ * supply.
31
+ */
32
+ export function resolveConfigForSize(config, size) {
33
+ const base = config ?? {};
34
+ return resolveConfig({
35
+ ...base,
36
+ ...(size.colors !== undefined && {
37
+ colors: mergeColors(base.colors, size.colors),
38
+ }),
39
+ ...(size.code !== undefined && { code: { ...base.code, ...size.code } }),
40
+ ...(size.background !== undefined && { background: size.background }),
41
+ ...(size.fontFamily !== undefined && { fontFamily: size.fontFamily }),
42
+ ...(size.footer !== undefined && { footer: size.footer }),
43
+ ...(size.badge !== undefined && { badge: size.badge }),
44
+ });
45
+ }
46
+ //# sourceMappingURL=size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.js","sourceRoot":"","sources":["../../src/config/size.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;GAQG;AACH,SAAS,WAAW,CAClB,IAA6B,EAC7B,SAA+B;IAE/B,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,cAAc,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAkC,EAClC,IAAgB;IAEhB,MAAM,IAAI,GAAG,MAAM,IAAI,EAAE,CAAC;IAE1B,OAAO,aAAa,CAAC;QACnB,GAAG,IAAI;QACP,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI;YAC/B,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;SAC9C,CAAC;QACF,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACxE,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;QACrE,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;QACrE,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QACzD,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;KACvD,CAAC,CAAC;AACL,CAAC"}
package/dist/config.d.ts CHANGED
@@ -36,7 +36,11 @@ export declare const SIZE_PRESETS: {
36
36
  * they satisfy `og:image` and both `twitter:image` card types.
37
37
  */
38
38
  export declare const DEFAULT_SIZES: readonly OutputSize[];
39
- /** Default font stack. Override via `config.fontFamily` for branded fonts. */
39
+ /**
40
+ * Default font stack, used when no fonts are configured. It names families and
41
+ * hopes the machine has them, which is exactly what `config.fonts` exists to
42
+ * avoid: supply a font file and the output stops depending on the machine.
43
+ */
40
44
  export declare const DEFAULT_FONT_FAMILY = "Arial, Helvetica, sans-serif";
41
45
  /** Neutral default palette, used when no `colors.brand` is supplied. */
42
46
  export declare const DEFAULT_COLORS: Required<BrandColors>;
@@ -49,7 +53,12 @@ export declare const DEFAULT_CODE_FONT_FAMILY = "\"JetBrains Mono\", \"Source Co
49
53
  /**
50
54
  * Default `code` template styling. `charWidthRatio` and `lineHeight` drive the
51
55
  * monospace grid the snippet is laid out on; the font-size bounds are
52
- * fractions of the image height so they hold at every output size.
56
+ * fractions of the image width so they hold at every output size.
57
+ *
58
+ * `minFontScale` of `0.025` is roughly 30px on a 1200px-wide image, which
59
+ * still reads when a feed shows that image at half size. A snippet too long to
60
+ * fit at that size is truncated rather than shrunk, so a long sample loses
61
+ * lines on the shorter landscape formats.
53
62
  */
54
63
  export declare const DEFAULT_CODE_STYLE: Required<CodeStyle>;
55
64
  /**
@@ -59,6 +68,28 @@ export declare const DEFAULT_CODE_STYLE: Required<CodeStyle>;
59
68
  export declare function defineConfig(config: ColophonConfig): ColophonConfig;
60
69
  /**
61
70
  * Apply defaults to a user config. Safe to call with no argument.
71
+ *
72
+ * Unknown options are rejected before anything is resolved, so a config
73
+ * written against a different version of the package is a build error rather
74
+ * than a set of images quietly rendered with the defaults.
62
75
  */
63
76
  export declare function resolveConfig(config?: ColophonConfig): ResolvedConfig;
77
+ /**
78
+ * Apply a size's own overrides to a config and resolve the result: the config
79
+ * one image is actually rendered with.
80
+ *
81
+ * The overrides are folded into the user config and the whole thing resolved
82
+ * again, rather than patched onto an already-resolved config, so that anything
83
+ * derived stays consistent — a size that overrides `colors.brand` gets the
84
+ * default gradient rebuilt around its brand, exactly as a config setting the
85
+ * same colour at the top level would.
86
+ *
87
+ * `colors` and `code` merge over their config-level counterparts, because both
88
+ * are bags of independent settings and the point of the feature is to change
89
+ * one of them. The rest replace: a `background` is a union whose variants have
90
+ * different keys, so half of one over half of another is not a background at
91
+ * all, and `badge` carries a required `text` that a partial override could not
92
+ * supply.
93
+ */
94
+ export declare function resolveConfigForSize(config: ColophonConfig | undefined, size: OutputSize): ResolvedConfig;
64
95
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,WAAW,EACX,SAAS,EACT,cAAc,EACd,UAAU,EACV,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;;iBACjB,IAAI,EAAE,IAAI;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,GAAG;;;iBAChC,IAAI,EAAE,QAAQ;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,IAAI;;;iBACxC,IAAI,EAAE,SAAS;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,GAAG;;;iBACvC,IAAI,EAAE,WAAW;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,IAAI;;CACZ,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAG9C,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAElE,wEAAwE;AACxE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAKhD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,8FACkD,CAAC;AAExF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,SAAS,CASlD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAEnE;AAoDD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,cAAmB,GAAG,cAAc,CAazE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,WAAW,EACX,SAAS,EACT,cAAc,EAEd,UAAU,EACV,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY;;iBACjB,IAAI,EAAE,IAAI;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,GAAG;;;iBAChC,IAAI,EAAE,QAAQ;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,IAAI;;;iBACxC,IAAI,EAAE,SAAS;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,GAAG;;;iBACvC,IAAI,EAAE,WAAW;iBAAE,KAAK,EAAE,IAAI;iBAAE,MAAM,EAAE,IAAI;;CACZ,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAG9C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAElE,wEAAwE;AACxE,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,WAAW,CAKhD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,8FACkD,CAAC;AAExF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,SAAS,CASlD,CAAC;AAcF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAEnE;AA2ED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,cAAmB,GAAG,cAAc,CAoBzE;AAkBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,IAAI,EAAE,UAAU,GACf,cAAc,CAchB"}
package/dist/config.js CHANGED
@@ -1,4 +1,6 @@
1
+ import { resolveFonts } from "./fonts.js";
1
2
  import { builtinTemplates } from "./templates/index.js";
3
+ import { validateConfig } from "./validate.js";
2
4
  /**
3
5
  * Named output-size presets covering the common social-image standards. Each
4
6
  * `name` becomes the filename suffix (e.g. `my-post-og.png`).
@@ -23,7 +25,11 @@ export const DEFAULT_SIZES = [
23
25
  SIZE_PRESETS.og,
24
26
  SIZE_PRESETS.square,
25
27
  ];
26
- /** Default font stack. Override via `config.fontFamily` for branded fonts. */
28
+ /**
29
+ * Default font stack, used when no fonts are configured. It names families and
30
+ * hopes the machine has them, which is exactly what `config.fonts` exists to
31
+ * avoid: supply a font file and the output stops depending on the machine.
32
+ */
27
33
  export const DEFAULT_FONT_FAMILY = "Arial, Helvetica, sans-serif";
28
34
  /** Neutral default palette, used when no `colors.brand` is supplied. */
29
35
  export const DEFAULT_COLORS = {
@@ -41,7 +47,12 @@ export const DEFAULT_CODE_FONT_FAMILY = '"JetBrains Mono", "Source Code Pro", "D
41
47
  /**
42
48
  * Default `code` template styling. `charWidthRatio` and `lineHeight` drive the
43
49
  * monospace grid the snippet is laid out on; the font-size bounds are
44
- * fractions of the image height so they hold at every output size.
50
+ * fractions of the image width so they hold at every output size.
51
+ *
52
+ * `minFontScale` of `0.025` is roughly 30px on a 1200px-wide image, which
53
+ * still reads when a feed shows that image at half size. A snippet too long to
54
+ * fit at that size is truncated rather than shrunk, so a long sample loses
55
+ * lines on the shorter landscape formats.
45
56
  */
46
57
  export const DEFAULT_CODE_STYLE = {
47
58
  theme: "github-dark",
@@ -51,8 +62,19 @@ export const DEFAULT_CODE_STYLE = {
51
62
  tabSize: 2,
52
63
  cornerScale: 0.025,
53
64
  maxFontScale: 0.075,
54
- minFontScale: 0.018,
65
+ minFontScale: 0.025,
55
66
  };
67
+ /**
68
+ * Default warning handler. Colophon runs at build time, so a compromise the
69
+ * renderer had to make belongs in the build log by default — silence is opt-in
70
+ * via `config.onWarning`.
71
+ */
72
+ function warnToConsole(message) {
73
+ // The console is the point: this is the default sink, replaced wholesale by
74
+ // a caller-supplied `onWarning`.
75
+ // eslint-disable-next-line no-console
76
+ console.warn(`colophon: ${message}`);
77
+ }
56
78
  /**
57
79
  * Identity helper that returns its argument typed as {@link ColophonConfig}.
58
80
  * Use it in a config module to get editor completion and type-checking.
@@ -99,20 +121,88 @@ function resolveSizes(sizes) {
99
121
  }
100
122
  return sizes;
101
123
  }
124
+ /**
125
+ * Whether to load the machine's own fonts. Configured fonts are meant to make
126
+ * the output the same everywhere, so supplying any turns system fonts off
127
+ * unless the project asks for them back.
128
+ */
129
+ function shouldLoadSystemFonts(systemFonts, fonts) {
130
+ if (systemFonts === undefined) {
131
+ return fonts.length === 0;
132
+ }
133
+ if (!systemFonts && fonts.length === 0) {
134
+ throw new Error("systemFonts is false and no fonts are configured, so no text could be" +
135
+ " rendered. Add fonts, or leave systemFonts unset.");
136
+ }
137
+ return systemFonts;
138
+ }
102
139
  /**
103
140
  * Apply defaults to a user config. Safe to call with no argument.
141
+ *
142
+ * Unknown options are rejected before anything is resolved, so a config
143
+ * written against a different version of the package is a build error rather
144
+ * than a set of images quietly rendered with the defaults.
104
145
  */
105
146
  export function resolveConfig(config = {}) {
147
+ validateConfig(config);
106
148
  const colors = resolveColors(config.colors);
149
+ const fonts = resolveFonts(config.fonts);
107
150
  return {
108
151
  colors,
109
152
  background: config.background ?? defaultBackground(colors),
110
- fontFamily: config.fontFamily ?? DEFAULT_FONT_FAMILY,
153
+ fonts,
154
+ systemFonts: shouldLoadSystemFonts(config.systemFonts, fonts),
155
+ // A project that supplies one font should not have to name it twice.
156
+ fontFamily: config.fontFamily ?? fonts[0]?.family ?? DEFAULT_FONT_FAMILY,
111
157
  footer: config.footer,
112
158
  badge: config.badge,
113
159
  code: resolveCode(config.code),
160
+ onWarning: config.onWarning ?? warnToConsole,
114
161
  sizes: resolveSizes(config.sizes),
115
162
  templates: { ...builtinTemplates, ...config.templates },
116
163
  };
117
164
  }
165
+ /**
166
+ * Merge a size's colour overrides onto the config's.
167
+ *
168
+ * A size may name any single shade, so the merge starts from the full default
169
+ * palette when the config sets no colours of its own. Starting from nothing
170
+ * instead would hand `resolveColors` a lone `foreground`, and its rule that a
171
+ * bare `brand` colours the whole gradient would then flatten the default
172
+ * gradient — a size asking only for darker text would silently lose it.
173
+ */
174
+ function mergeColors(base, overrides) {
175
+ return { ...(base ?? DEFAULT_COLORS), ...overrides };
176
+ }
177
+ /**
178
+ * Apply a size's own overrides to a config and resolve the result: the config
179
+ * one image is actually rendered with.
180
+ *
181
+ * The overrides are folded into the user config and the whole thing resolved
182
+ * again, rather than patched onto an already-resolved config, so that anything
183
+ * derived stays consistent — a size that overrides `colors.brand` gets the
184
+ * default gradient rebuilt around its brand, exactly as a config setting the
185
+ * same colour at the top level would.
186
+ *
187
+ * `colors` and `code` merge over their config-level counterparts, because both
188
+ * are bags of independent settings and the point of the feature is to change
189
+ * one of them. The rest replace: a `background` is a union whose variants have
190
+ * different keys, so half of one over half of another is not a background at
191
+ * all, and `badge` carries a required `text` that a partial override could not
192
+ * supply.
193
+ */
194
+ export function resolveConfigForSize(config, size) {
195
+ const base = config ?? {};
196
+ return resolveConfig({
197
+ ...base,
198
+ ...(size.colors !== undefined && {
199
+ colors: mergeColors(base.colors, size.colors),
200
+ }),
201
+ ...(size.code !== undefined && { code: { ...base.code, ...size.code } }),
202
+ ...(size.background !== undefined && { background: size.background }),
203
+ ...(size.fontFamily !== undefined && { fontFamily: size.fontFamily }),
204
+ ...(size.footer !== undefined && { footer: size.footer }),
205
+ ...(size.badge !== undefined && { badge: size.badge }),
206
+ });
207
+ }
118
208
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1,52 +1,6 @@
1
- import type { MetaImageProps } from "../types.js";
2
- /**
3
- * Options for {@link walkContent}. Only `dir` is required.
4
- */
5
- export interface WalkOptions {
6
- /** Root directory to search recursively for content files. */
7
- readonly dir: string;
8
- /** Frontmatter key holding the image props object. Default `meta_img_props`. */
9
- readonly propsKey?: string;
10
- /** Field within the props object naming the template. Default `template`. */
11
- readonly templateField?: string;
12
- /** Template to use when the template field is absent. */
13
- readonly defaultTemplate?: string;
14
- /**
15
- * Top-level frontmatter field to read the post slug from (used as the base
16
- * filename). Default `slug`; falls back to the file/directory name.
17
- */
18
- readonly slugField?: string;
19
- /** File extensions to include. Default `.md` and `.markdown`. */
20
- readonly extensions?: readonly string[];
21
- }
22
- /**
23
- * A discovered content file with the image props read from its frontmatter.
24
- */
25
- export interface ContentFile {
26
- /** Path relative to the walk `dir`. */
27
- readonly contentPath: string;
28
- /** Absolute path on disk. */
29
- readonly absolutePath: string;
30
- /** Base filename for this post's images (frontmatter slug, or path-derived). */
31
- readonly slug: string;
32
- readonly props: MetaImageProps;
33
- }
34
- /**
35
- * Derive a slug from a file path: the filename without extension, or the
36
- * parent directory name when the file is `index.*` (the common page-bundle
37
- * convention).
38
- */
39
- export declare function slugFromPath(filePath: string): string;
40
- /**
41
- * Extract {@link MetaImageProps} from a parsed frontmatter object, or return
42
- * `undefined` if this file should be skipped (no props object, or no usable
43
- * template/title). Pure — no filesystem access.
44
- */
45
- export declare function extractProps(frontmatter: Record<string, unknown>, options?: Pick<WalkOptions, "propsKey" | "templateField" | "defaultTemplate">): MetaImageProps | undefined;
46
- /**
47
- * Walk a content tree, read each file's frontmatter with `gray-matter`, and
48
- * return the files that declare image props. This is the host-project concern
49
- * — finding content and reading frontmatter — kept separate from rendering.
50
- */
51
- export declare function walkContent(options: WalkOptions): Promise<ContentFile[]>;
1
+ export { extractProps } from "./props.js";
2
+ export { slugFromPath } from "./slug.js";
3
+ export { walkContent } from "./walk.js";
4
+ export type { WalkOptions } from "./walk.js";
5
+ export type { ContentFile } from "../types.js";
52
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAuBlD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,yDAAyD;IACzD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6BAA6B;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIrD;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,GAAE,IAAI,CACX,WAAW,EACX,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAC5C,GACL,cAAc,GAAG,SAAS,CA4C5B;AA8BD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,EAAE,CAAC,CAgCxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
@@ -1,116 +1,4 @@
1
- import { readdir, readFile } from "node:fs/promises";
2
- import path from "node:path";
3
- import matter from "gray-matter";
4
- const defaultPropsKey = "meta_img_props";
5
- const defaultTemplateField = "template";
6
- const defaultSlugField = "slug";
7
- const defaultExtensions = [".md", ".markdown"];
8
- function coerceString(value) {
9
- if (typeof value === "string") {
10
- return value;
11
- }
12
- if (typeof value === "number" ||
13
- typeof value === "boolean" ||
14
- typeof value === "bigint") {
15
- return String(value);
16
- }
17
- return undefined;
18
- }
19
- /**
20
- * Derive a slug from a file path: the filename without extension, or the
21
- * parent directory name when the file is `index.*` (the common page-bundle
22
- * convention).
23
- */
24
- export function slugFromPath(filePath) {
25
- const extension = path.extname(filePath);
26
- const base = path.basename(filePath, extension);
27
- return base === "index" ? path.basename(path.dirname(filePath)) : base;
28
- }
29
- function isRecord(value) {
30
- return typeof value === "object" && value !== null && !Array.isArray(value);
31
- }
32
- /**
33
- * Extract {@link MetaImageProps} from a parsed frontmatter object, or return
34
- * `undefined` if this file should be skipped (no props object, or no usable
35
- * template/title). Pure — no filesystem access.
36
- */
37
- export function extractProps(frontmatter, options = {}) {
38
- const propsKey = options.propsKey ?? defaultPropsKey;
39
- const templateField = options.templateField ?? defaultTemplateField;
40
- const record = frontmatter[propsKey];
41
- if (!isRecord(record)) {
42
- return undefined;
43
- }
44
- const templateRaw = record[templateField];
45
- const template = typeof templateRaw === "string" ? templateRaw : options.defaultTemplate;
46
- if (template === undefined) {
47
- return undefined;
48
- }
49
- // Title is optional: templates such as `code` describe the image entirely
50
- // from their own fields, and requiring a title would be pure boilerplate.
51
- const title = coerceString(record["title"]);
52
- const subtitle = coerceString(record["subtitle"]);
53
- const version = coerceString(record["version"]);
54
- const extras = {};
55
- for (const [key, value] of Object.entries(record)) {
56
- if (key !== templateField &&
57
- key !== "template" &&
58
- key !== "title" &&
59
- key !== "subtitle" &&
60
- key !== "version") {
61
- extras[key] = value;
62
- }
63
- }
64
- return {
65
- ...extras,
66
- template,
67
- ...(title !== undefined && { title }),
68
- ...(subtitle !== undefined && { subtitle }),
69
- ...(version !== undefined && { version }),
70
- };
71
- }
72
- async function collectContentFiles(dir, extensions) {
73
- const entries = await readdir(dir, { withFileTypes: true });
74
- const nested = await Promise.all(entries.map(async (entry) => {
75
- const entryPath = path.join(dir, entry.name);
76
- if (entry.isDirectory()) {
77
- return collectContentFiles(entryPath, extensions);
78
- }
79
- if (entry.isFile() &&
80
- extensions.some((extension) => entry.name.endsWith(extension))) {
81
- return [entryPath];
82
- }
83
- return [];
84
- }));
85
- return nested.flat();
86
- }
87
- /**
88
- * Walk a content tree, read each file's frontmatter with `gray-matter`, and
89
- * return the files that declare image props. This is the host-project concern
90
- * — finding content and reading frontmatter — kept separate from rendering.
91
- */
92
- export async function walkContent(options) {
93
- const extensions = options.extensions ?? defaultExtensions;
94
- const filePaths = await collectContentFiles(options.dir, extensions);
95
- const slugField = options.slugField ?? defaultSlugField;
96
- const files = await Promise.all(filePaths.map(async (filePath) => {
97
- const raw = await readFile(filePath, "utf8");
98
- const frontmatter = matter(raw).data;
99
- const props = extractProps(frontmatter, options);
100
- if (props === undefined) {
101
- return;
102
- }
103
- const declaredSlug = coerceString(frontmatter[slugField])?.trim();
104
- const slug = declaredSlug !== undefined && declaredSlug !== ""
105
- ? declaredSlug
106
- : slugFromPath(filePath);
107
- return {
108
- contentPath: path.relative(options.dir, filePath),
109
- absolutePath: filePath,
110
- slug,
111
- props,
112
- };
113
- }));
114
- return files.filter((file) => file !== undefined);
115
- }
1
+ export { extractProps } from "./props.js";
2
+ export { slugFromPath } from "./slug.js";
3
+ export { walkContent } from "./walk.js";
116
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { ContentOptions, MetaImageProps } from "../types.js";
2
+ /** Read a frontmatter scalar as a string, ignoring anything else. */
3
+ export declare function coerceString(value: unknown): string | undefined;
4
+ /**
5
+ * Extract {@link MetaImageProps} from a parsed frontmatter object, or return
6
+ * `undefined` if this file should be skipped (nothing to build props from, or
7
+ * no usable template). Pure — no filesystem access.
8
+ *
9
+ * Props can come from two places: the post's own props object, and a project's
10
+ * `props` mapper reading the frontmatter it already has. Where both speak the
11
+ * post wins, field by field — the mapper describes the site's usual shape, and
12
+ * a post that says otherwise is saying so on purpose.
13
+ */
14
+ export declare function extractProps(frontmatter: Record<string, unknown>, options?: Pick<ContentOptions, "propsKey" | "templateField" | "defaultTemplate" | "props">): MetaImageProps | undefined;
15
+ //# sourceMappingURL=props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/content/props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlE,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAc/D;AASD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,GAAE,IAAI,CACX,cAAc,EACd,UAAU,GAAG,eAAe,GAAG,iBAAiB,GAAG,OAAO,CACtD,GACL,cAAc,GAAG,SAAS,CAiD5B"}
@@ -0,0 +1,71 @@
1
+ const defaultPropsKey = "meta_img_props";
2
+ const defaultTemplateField = "template";
3
+ /** Read a frontmatter scalar as a string, ignoring anything else. */
4
+ export function coerceString(value) {
5
+ if (typeof value === "string") {
6
+ return value;
7
+ }
8
+ if (typeof value === "number" ||
9
+ typeof value === "boolean" ||
10
+ typeof value === "bigint") {
11
+ return String(value);
12
+ }
13
+ return undefined;
14
+ }
15
+ function isRecord(value) {
16
+ return typeof value === "object" && value !== null && !Array.isArray(value);
17
+ }
18
+ /** The fields the props shape names itself, which never become extras. */
19
+ const namedFields = new Set(["template", "title", "subtitle", "version"]);
20
+ /**
21
+ * Extract {@link MetaImageProps} from a parsed frontmatter object, or return
22
+ * `undefined` if this file should be skipped (nothing to build props from, or
23
+ * no usable template). Pure — no filesystem access.
24
+ *
25
+ * Props can come from two places: the post's own props object, and a project's
26
+ * `props` mapper reading the frontmatter it already has. Where both speak the
27
+ * post wins, field by field — the mapper describes the site's usual shape, and
28
+ * a post that says otherwise is saying so on purpose.
29
+ */
30
+ export function extractProps(frontmatter, options = {}) {
31
+ const propsKey = options.propsKey ?? defaultPropsKey;
32
+ const templateField = options.templateField ?? defaultTemplateField;
33
+ const declared = frontmatter[propsKey];
34
+ const hasDeclared = isRecord(declared);
35
+ const mapped = options.props?.(frontmatter);
36
+ // A mapper opting a post out cannot overrule a post that asked for an image
37
+ // outright, so the skip only applies where the post says nothing itself.
38
+ if (!hasDeclared && mapped === undefined) {
39
+ return undefined;
40
+ }
41
+ // Merged rather than replaced, so a post correcting one field does not have
42
+ // to restate everything the mapper already got right.
43
+ const record = {
44
+ ...mapped,
45
+ ...(hasDeclared && declared),
46
+ };
47
+ const templateRaw = record[templateField];
48
+ const template = typeof templateRaw === "string" ? templateRaw : options.defaultTemplate;
49
+ if (template === undefined) {
50
+ return undefined;
51
+ }
52
+ // Title is optional: templates such as `code` describe the image entirely
53
+ // from their own fields, and requiring a title would be pure boilerplate.
54
+ const title = coerceString(record["title"]);
55
+ const subtitle = coerceString(record["subtitle"]);
56
+ const version = coerceString(record["version"]);
57
+ const extras = {};
58
+ for (const [key, value] of Object.entries(record)) {
59
+ if (key !== templateField && !namedFields.has(key)) {
60
+ extras[key] = value;
61
+ }
62
+ }
63
+ return {
64
+ ...extras,
65
+ template,
66
+ ...(title !== undefined && { title }),
67
+ ...(subtitle !== undefined && { subtitle }),
68
+ ...(version !== undefined && { version }),
69
+ };
70
+ }
71
+ //# sourceMappingURL=props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.js","sourceRoot":"","sources":["../../src/content/props.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { SlugStrategy } from "../types.js";
2
+ /**
3
+ * Derive a slug from a content file's path, relative to the root of the walk.
4
+ *
5
+ * `basename` gives the filename without extension, or the parent directory for
6
+ * `index.*` — the page-bundle convention, where an image sits beside its post.
7
+ * `route` keeps the directories, so a site addressed by route gets a slug that
8
+ * matches the address rather than just its last segment.
9
+ *
10
+ * The path must be relative to the content root for `route` to mean anything;
11
+ * `basename` reads the same either way.
12
+ */
13
+ export declare function slugFromPath(contentPath: string, strategy?: SlugStrategy): string;
14
+ /**
15
+ * Reject a slug that would name a file outside the tree it came from.
16
+ *
17
+ * A slug is a filename, and may carry directories under the `route` strategy —
18
+ * but a declared one is written by hand, and `slug: ../../../tmp/x` would have
19
+ * `generate` create directories and write an image there. Nothing derived from
20
+ * a path can look like this, so the check only ever fires on frontmatter.
21
+ */
22
+ export declare function assertSlugStaysInside(slug: string, contentPath: string): void;
23
+ //# sourceMappingURL=slug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../src/content/slug.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE,YAAyB,GAClC,MAAM,CAqBR;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAe7E"}