gazetta 0.6.0 → 0.7.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 (340) hide show
  1. package/admin-dist/assets/index-BO9-CXmW.css +1 -0
  2. package/admin-dist/assets/index-Ufu8zZH_.js +668 -0
  3. package/admin-dist/index.html +2 -2
  4. package/dist/admin-api/error-response.d.ts +21 -0
  5. package/dist/admin-api/error-response.d.ts.map +1 -0
  6. package/dist/admin-api/error-response.js +12 -0
  7. package/dist/admin-api/error-response.js.map +1 -0
  8. package/dist/admin-api/index.d.ts +0 -2
  9. package/dist/admin-api/index.d.ts.map +1 -1
  10. package/dist/admin-api/index.js +4 -24
  11. package/dist/admin-api/index.js.map +1 -1
  12. package/dist/admin-api/routes/assets.d.ts +16 -0
  13. package/dist/admin-api/routes/assets.d.ts.map +1 -0
  14. package/dist/admin-api/routes/assets.js +433 -0
  15. package/dist/admin-api/routes/assets.js.map +1 -0
  16. package/dist/admin-api/routes/fragments.d.ts.map +1 -1
  17. package/dist/admin-api/routes/fragments.js +30 -4
  18. package/dist/admin-api/routes/fragments.js.map +1 -1
  19. package/dist/admin-api/routes/pages.d.ts.map +1 -1
  20. package/dist/admin-api/routes/pages.js +37 -4
  21. package/dist/admin-api/routes/pages.js.map +1 -1
  22. package/dist/admin-api/routes/publish.d.ts.map +1 -1
  23. package/dist/admin-api/routes/publish.js +68 -35
  24. package/dist/admin-api/routes/publish.js.map +1 -1
  25. package/dist/admin-api/schemas/assets.d.ts +48 -0
  26. package/dist/admin-api/schemas/assets.d.ts.map +1 -0
  27. package/dist/admin-api/schemas/assets.js +44 -0
  28. package/dist/admin-api/schemas/assets.js.map +1 -0
  29. package/dist/admin-api/schemas/index.d.ts +2 -0
  30. package/dist/admin-api/schemas/index.d.ts.map +1 -1
  31. package/dist/admin-api/schemas/index.js +2 -0
  32. package/dist/admin-api/schemas/index.js.map +1 -1
  33. package/dist/admin-api/source-context.d.ts +0 -7
  34. package/dist/admin-api/source-context.d.ts.map +1 -1
  35. package/dist/admin-api/source-context.js +0 -3
  36. package/dist/admin-api/source-context.js.map +1 -1
  37. package/dist/assets/analyze-audio.d.ts +3 -0
  38. package/dist/assets/analyze-audio.d.ts.map +1 -0
  39. package/dist/assets/analyze-audio.js +80 -0
  40. package/dist/assets/analyze-audio.js.map +1 -0
  41. package/dist/assets/analyze-image.d.ts +19 -0
  42. package/dist/assets/analyze-image.d.ts.map +1 -0
  43. package/dist/assets/analyze-image.js +123 -0
  44. package/dist/assets/analyze-image.js.map +1 -0
  45. package/dist/assets/analyze.d.ts +94 -0
  46. package/dist/assets/analyze.d.ts.map +1 -0
  47. package/dist/assets/analyze.js +45 -0
  48. package/dist/assets/analyze.js.map +1 -0
  49. package/dist/assets/asset-deps.d.ts +30 -0
  50. package/dist/assets/asset-deps.d.ts.map +1 -0
  51. package/dist/assets/asset-deps.js +42 -0
  52. package/dist/assets/asset-deps.js.map +1 -0
  53. package/dist/assets/asset-paths.d.ts +155 -0
  54. package/dist/assets/asset-paths.d.ts.map +1 -0
  55. package/dist/assets/asset-paths.js +197 -0
  56. package/dist/assets/asset-paths.js.map +1 -0
  57. package/dist/assets/delete.d.ts +75 -0
  58. package/dist/assets/delete.d.ts.map +1 -0
  59. package/dist/assets/delete.js +82 -0
  60. package/dist/assets/delete.js.map +1 -0
  61. package/dist/assets/errors.d.ts +241 -0
  62. package/dist/assets/errors.d.ts.map +1 -0
  63. package/dist/assets/errors.js +300 -0
  64. package/dist/assets/errors.js.map +1 -0
  65. package/dist/assets/find-refs.d.ts +37 -0
  66. package/dist/assets/find-refs.d.ts.map +1 -0
  67. package/dist/assets/find-refs.js +35 -0
  68. package/dist/assets/find-refs.js.map +1 -0
  69. package/dist/assets/hash.d.ts +13 -0
  70. package/dist/assets/hash.d.ts.map +1 -0
  71. package/dist/assets/hash.js +43 -0
  72. package/dist/assets/hash.js.map +1 -0
  73. package/dist/assets/image-metadata.d.ts +11 -0
  74. package/dist/assets/image-metadata.d.ts.map +1 -0
  75. package/dist/assets/image-metadata.js +31 -0
  76. package/dist/assets/image-metadata.js.map +1 -0
  77. package/dist/assets/ingest-locale.d.ts +86 -0
  78. package/dist/assets/ingest-locale.d.ts.map +1 -0
  79. package/dist/assets/ingest-locale.js +209 -0
  80. package/dist/assets/ingest-locale.js.map +1 -0
  81. package/dist/assets/ingest.d.ts +96 -0
  82. package/dist/assets/ingest.d.ts.map +1 -0
  83. package/dist/assets/ingest.js +308 -0
  84. package/dist/assets/ingest.js.map +1 -0
  85. package/dist/assets/kind-compat.d.ts +34 -0
  86. package/dist/assets/kind-compat.d.ts.map +1 -0
  87. package/dist/assets/kind-compat.js +33 -0
  88. package/dist/assets/kind-compat.js.map +1 -0
  89. package/dist/assets/list.d.ts +46 -0
  90. package/dist/assets/list.d.ts.map +1 -0
  91. package/dist/assets/list.js +102 -0
  92. package/dist/assets/list.js.map +1 -0
  93. package/dist/assets/manifest-default.d.ts +56 -0
  94. package/dist/assets/manifest-default.d.ts.map +1 -0
  95. package/dist/assets/manifest-default.js +120 -0
  96. package/dist/assets/manifest-default.js.map +1 -0
  97. package/dist/assets/manifest-filename.d.ts +52 -0
  98. package/dist/assets/manifest-filename.d.ts.map +1 -0
  99. package/dist/assets/manifest-filename.js +104 -0
  100. package/dist/assets/manifest-filename.js.map +1 -0
  101. package/dist/assets/manifest-locale.d.ts +60 -0
  102. package/dist/assets/manifest-locale.d.ts.map +1 -0
  103. package/dist/assets/manifest-locale.js +206 -0
  104. package/dist/assets/manifest-locale.js.map +1 -0
  105. package/dist/assets/manifest-merge.d.ts +66 -0
  106. package/dist/assets/manifest-merge.d.ts.map +1 -0
  107. package/dist/assets/manifest-merge.js +82 -0
  108. package/dist/assets/manifest-merge.js.map +1 -0
  109. package/dist/assets/manifest.d.ts +83 -0
  110. package/dist/assets/manifest.d.ts.map +1 -0
  111. package/dist/assets/manifest.js +93 -0
  112. package/dist/assets/manifest.js.map +1 -0
  113. package/dist/assets/mime-sniff.d.ts +18 -0
  114. package/dist/assets/mime-sniff.d.ts.map +1 -0
  115. package/dist/assets/mime-sniff.js +84 -0
  116. package/dist/assets/mime-sniff.js.map +1 -0
  117. package/dist/assets/preprocess-svg.d.ts +3 -0
  118. package/dist/assets/preprocess-svg.d.ts.map +1 -0
  119. package/dist/assets/preprocess-svg.js +49 -0
  120. package/dist/assets/preprocess-svg.js.map +1 -0
  121. package/dist/assets/preprocess.d.ts +62 -0
  122. package/dist/assets/preprocess.d.ts.map +1 -0
  123. package/dist/assets/preprocess.js +86 -0
  124. package/dist/assets/preprocess.js.map +1 -0
  125. package/dist/assets/publish-plan.d.ts +41 -0
  126. package/dist/assets/publish-plan.d.ts.map +1 -0
  127. package/dist/assets/publish-plan.js +49 -0
  128. package/dist/assets/publish-plan.js.map +1 -0
  129. package/dist/assets/publish.d.ts +33 -0
  130. package/dist/assets/publish.d.ts.map +1 -0
  131. package/dist/assets/publish.js +81 -0
  132. package/dist/assets/publish.js.map +1 -0
  133. package/dist/assets/refs.d.ts +37 -0
  134. package/dist/assets/refs.d.ts.map +1 -0
  135. package/dist/assets/refs.js +33 -0
  136. package/dist/assets/refs.js.map +1 -0
  137. package/dist/assets/remove-override.d.ts +42 -0
  138. package/dist/assets/remove-override.d.ts.map +1 -0
  139. package/dist/assets/remove-override.js +53 -0
  140. package/dist/assets/remove-override.js.map +1 -0
  141. package/dist/assets/rename.d.ts +43 -0
  142. package/dist/assets/rename.d.ts.map +1 -0
  143. package/dist/assets/rename.js +271 -0
  144. package/dist/assets/rename.js.map +1 -0
  145. package/dist/assets/replace.d.ts +37 -0
  146. package/dist/assets/replace.d.ts.map +1 -0
  147. package/dist/assets/replace.js +195 -0
  148. package/dist/assets/replace.js.map +1 -0
  149. package/dist/assets/resolve.d.ts +141 -0
  150. package/dist/assets/resolve.d.ts.map +1 -0
  151. package/dist/assets/resolve.js +381 -0
  152. package/dist/assets/resolve.js.map +1 -0
  153. package/dist/assets/rewrite-manifest-asset-ref.d.ts +44 -0
  154. package/dist/assets/rewrite-manifest-asset-ref.d.ts.map +1 -0
  155. package/dist/assets/rewrite-manifest-asset-ref.js +51 -0
  156. package/dist/assets/rewrite-manifest-asset-ref.js.map +1 -0
  157. package/dist/assets/scan-manifest-for-asset.d.ts +63 -0
  158. package/dist/assets/scan-manifest-for-asset.d.ts.map +1 -0
  159. package/dist/assets/scan-manifest-for-asset.js +105 -0
  160. package/dist/assets/scan-manifest-for-asset.js.map +1 -0
  161. package/dist/assets/serve-route.d.ts +45 -0
  162. package/dist/assets/serve-route.d.ts.map +1 -0
  163. package/dist/assets/serve-route.js +123 -0
  164. package/dist/assets/serve-route.js.map +1 -0
  165. package/dist/assets/svg-sanitize.d.ts +38 -0
  166. package/dist/assets/svg-sanitize.d.ts.map +1 -0
  167. package/dist/assets/svg-sanitize.js +209 -0
  168. package/dist/assets/svg-sanitize.js.map +1 -0
  169. package/dist/assets/update-metadata.d.ts +61 -0
  170. package/dist/assets/update-metadata.d.ts.map +1 -0
  171. package/dist/assets/update-metadata.js +82 -0
  172. package/dist/assets/update-metadata.js.map +1 -0
  173. package/dist/assets/url.d.ts +82 -0
  174. package/dist/assets/url.d.ts.map +1 -0
  175. package/dist/assets/url.js +103 -0
  176. package/dist/assets/url.js.map +1 -0
  177. package/dist/assets/validate.d.ts +74 -0
  178. package/dist/assets/validate.d.ts.map +1 -0
  179. package/dist/assets/validate.js +136 -0
  180. package/dist/assets/validate.js.map +1 -0
  181. package/dist/assets/variants.d.ts +23 -0
  182. package/dist/assets/variants.d.ts.map +1 -0
  183. package/dist/assets/variants.js +74 -0
  184. package/dist/assets/variants.js.map +1 -0
  185. package/dist/cli/assets-cli.d.ts +58 -0
  186. package/dist/cli/assets-cli.d.ts.map +1 -0
  187. package/dist/cli/assets-cli.js +233 -0
  188. package/dist/cli/assets-cli.js.map +1 -0
  189. package/dist/cli/assets-display.d.ts +112 -0
  190. package/dist/cli/assets-display.d.ts.map +1 -0
  191. package/dist/cli/assets-display.js +106 -0
  192. package/dist/cli/assets-display.js.map +1 -0
  193. package/dist/cli/bootstrap.d.ts +0 -2
  194. package/dist/cli/bootstrap.d.ts.map +1 -1
  195. package/dist/cli/bootstrap.js +0 -1
  196. package/dist/cli/bootstrap.js.map +1 -1
  197. package/dist/cli/index.js +64 -18
  198. package/dist/cli/index.js.map +1 -1
  199. package/dist/compare.d.ts.map +1 -1
  200. package/dist/compare.js +15 -12
  201. package/dist/compare.js.map +1 -1
  202. package/dist/dep-sidecars.d.ts +127 -0
  203. package/dist/dep-sidecars.d.ts.map +1 -0
  204. package/dist/dep-sidecars.js +122 -0
  205. package/dist/dep-sidecars.js.map +1 -0
  206. package/dist/editor/AssetEmbeddedWidget.d.ts +3 -0
  207. package/dist/editor/AssetEmbeddedWidget.d.ts.map +1 -0
  208. package/dist/editor/AssetEmbeddedWidget.js +146 -0
  209. package/dist/editor/AssetEmbeddedWidget.js.map +1 -0
  210. package/dist/editor/mount.d.ts +12 -1
  211. package/dist/editor/mount.d.ts.map +1 -1
  212. package/dist/editor/mount.js +36 -5
  213. package/dist/editor/mount.js.map +1 -1
  214. package/dist/format.d.ts +44 -0
  215. package/dist/format.d.ts.map +1 -0
  216. package/dist/format.js +65 -0
  217. package/dist/format.js.map +1 -0
  218. package/dist/fragment-deps.d.ts +24 -0
  219. package/dist/fragment-deps.d.ts.map +1 -0
  220. package/dist/fragment-deps.js +20 -0
  221. package/dist/fragment-deps.js.map +1 -0
  222. package/dist/hash.d.ts +0 -6
  223. package/dist/hash.d.ts.map +1 -1
  224. package/dist/hash.js +0 -18
  225. package/dist/hash.js.map +1 -1
  226. package/dist/history-provider.d.ts.map +1 -1
  227. package/dist/history-provider.js +30 -8
  228. package/dist/history-provider.js.map +1 -1
  229. package/dist/history-recorder.d.ts +7 -3
  230. package/dist/history-recorder.d.ts.map +1 -1
  231. package/dist/history-recorder.js +9 -1
  232. package/dist/history-recorder.js.map +1 -1
  233. package/dist/history-restorer.d.ts.map +1 -1
  234. package/dist/history-restorer.js +34 -2
  235. package/dist/history-restorer.js.map +1 -1
  236. package/dist/history.d.ts +26 -8
  237. package/dist/history.d.ts.map +1 -1
  238. package/dist/index.d.ts +2 -4
  239. package/dist/index.d.ts.map +1 -1
  240. package/dist/index.js +1 -2
  241. package/dist/index.js.map +1 -1
  242. package/dist/locale.d.ts +20 -0
  243. package/dist/locale.d.ts.map +1 -1
  244. package/dist/locale.js +38 -0
  245. package/dist/locale.js.map +1 -1
  246. package/dist/providers/_atomic-write.d.ts +9 -0
  247. package/dist/providers/_atomic-write.d.ts.map +1 -0
  248. package/dist/providers/_atomic-write.js +72 -0
  249. package/dist/providers/_atomic-write.js.map +1 -0
  250. package/dist/providers/_rm-ignore-missing.d.ts +31 -0
  251. package/dist/providers/_rm-ignore-missing.d.ts.map +1 -0
  252. package/dist/providers/_rm-ignore-missing.js +12 -0
  253. package/dist/providers/_rm-ignore-missing.js.map +1 -0
  254. package/dist/providers/_stream-interop.d.ts +23 -0
  255. package/dist/providers/_stream-interop.d.ts.map +1 -0
  256. package/dist/providers/_stream-interop.js +21 -0
  257. package/dist/providers/_stream-interop.js.map +1 -0
  258. package/dist/providers/azure-blob.d.ts.map +1 -1
  259. package/dist/providers/azure-blob.js +60 -0
  260. package/dist/providers/azure-blob.js.map +1 -1
  261. package/dist/providers/filesystem.d.ts +4 -0
  262. package/dist/providers/filesystem.d.ts.map +1 -1
  263. package/dist/providers/filesystem.js +63 -2
  264. package/dist/providers/filesystem.js.map +1 -1
  265. package/dist/providers/s3.d.ts.map +1 -1
  266. package/dist/providers/s3.js +84 -1
  267. package/dist/providers/s3.js.map +1 -1
  268. package/dist/publish-rendered.d.ts +37 -17
  269. package/dist/publish-rendered.d.ts.map +1 -1
  270. package/dist/publish-rendered.js +71 -67
  271. package/dist/publish-rendered.js.map +1 -1
  272. package/dist/publish.d.ts +13 -12
  273. package/dist/publish.d.ts.map +1 -1
  274. package/dist/publish.js +23 -47
  275. package/dist/publish.js.map +1 -1
  276. package/dist/resolver.d.ts +12 -2
  277. package/dist/resolver.d.ts.map +1 -1
  278. package/dist/resolver.js +54 -9
  279. package/dist/resolver.js.map +1 -1
  280. package/dist/schema/dimensions.d.ts +78 -0
  281. package/dist/schema/dimensions.d.ts.map +1 -0
  282. package/dist/schema/dimensions.js +97 -0
  283. package/dist/schema/dimensions.js.map +1 -0
  284. package/dist/schema/helpers.d.ts +108 -0
  285. package/dist/schema/helpers.d.ts.map +1 -0
  286. package/dist/schema/helpers.js +133 -0
  287. package/dist/schema/helpers.js.map +1 -0
  288. package/dist/schema/index.d.ts +27 -0
  289. package/dist/schema/index.d.ts.map +1 -0
  290. package/dist/schema/index.js +25 -0
  291. package/dist/schema/index.js.map +1 -0
  292. package/dist/schema/types.d.ts +390 -0
  293. package/dist/schema/types.d.ts.map +1 -0
  294. package/dist/schema/types.js +25 -0
  295. package/dist/schema/types.js.map +1 -0
  296. package/dist/selector-chain.d.ts +63 -0
  297. package/dist/selector-chain.d.ts.map +1 -0
  298. package/dist/selector-chain.js +58 -0
  299. package/dist/selector-chain.js.map +1 -0
  300. package/dist/sidecars.d.ts +19 -18
  301. package/dist/sidecars.d.ts.map +1 -1
  302. package/dist/sidecars.js +70 -62
  303. package/dist/sidecars.js.map +1 -1
  304. package/dist/targets.d.ts.map +1 -1
  305. package/dist/targets.js +15 -37
  306. package/dist/targets.js.map +1 -1
  307. package/dist/themes.d.ts +69 -0
  308. package/dist/themes.d.ts.map +1 -0
  309. package/dist/themes.js +85 -0
  310. package/dist/themes.js.map +1 -0
  311. package/dist/transforms/adapter.d.ts +115 -0
  312. package/dist/transforms/adapter.d.ts.map +1 -0
  313. package/dist/transforms/adapter.js +2 -0
  314. package/dist/transforms/adapter.js.map +1 -0
  315. package/dist/transforms/cloudflare.d.ts +17 -0
  316. package/dist/transforms/cloudflare.d.ts.map +1 -0
  317. package/dist/transforms/cloudflare.js +110 -0
  318. package/dist/transforms/cloudflare.js.map +1 -0
  319. package/dist/transforms/index.d.ts +24 -0
  320. package/dist/transforms/index.d.ts.map +1 -0
  321. package/dist/transforms/index.js +30 -0
  322. package/dist/transforms/index.js.map +1 -0
  323. package/dist/transforms/sharp.d.ts +3 -0
  324. package/dist/transforms/sharp.d.ts.map +1 -0
  325. package/dist/transforms/sharp.js +43 -0
  326. package/dist/transforms/sharp.js.map +1 -0
  327. package/dist/types.d.ts +125 -1
  328. package/dist/types.d.ts.map +1 -1
  329. package/dist/types.js.map +1 -1
  330. package/package.json +20 -1
  331. package/admin-dist/assets/index-B6pVot0Y.css +0 -1
  332. package/admin-dist/assets/index-DniLwxJA.js +0 -609
  333. package/dist/providers/r2.d.ts +0 -8
  334. package/dist/providers/r2.d.ts.map +0 -1
  335. package/dist/providers/r2.js +0 -86
  336. package/dist/providers/r2.js.map +0 -1
  337. package/dist/source-sidecars.d.ts +0 -32
  338. package/dist/source-sidecars.d.ts.map +0 -1
  339. package/dist/source-sidecars.js +0 -98
  340. package/dist/source-sidecars.js.map +0 -1
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Typed errors for the asset domain.
3
+ *
4
+ * Every asset-domain failure is one of these classes — never a plain
5
+ * `new Error('not implemented')`. Callers pattern-match on the class to
6
+ * decide what to do (HTTP status, CLI exit code, retry policy, user
7
+ * message). Subclassing keeps the public error taxonomy small and stable.
8
+ *
9
+ * The `code` property is the machine-readable identifier. Messages are
10
+ * human-readable and may include path/name details; tests should match
11
+ * on `code`, not on message text.
12
+ */
13
+ export type AssetErrorCode = 'ASSET_VALIDATION_FAILED' | 'ASSET_MIME_MISMATCH' | 'ASSET_SIZE_EXCEEDED' | 'ASSET_NAME_INVALID' | 'ASSET_NAME_RESERVED' | 'ASSET_PATH_TRAVERSAL' | 'ASSET_STORAGE_FAILURE' | 'ASSET_MANIFEST_CORRUPT' | 'ASSET_MANIFEST_NOT_FOUND' | 'ASSET_IN_USE' | 'ASSET_MIME_UNSUPPORTED' | 'ASSET_KIND_MISMATCH' | 'ASSET_NAME_COLLISION' | 'ASSET_VARIANT_GENERATION_FAILED' | 'ASSET_PREPROCESS_FAILED';
14
+ /**
15
+ * `AssetRef` is owned by `./refs.ts` (single source of truth, Zod
16
+ * schema + inferred type). Re-exported here for the error class that
17
+ * carries refs as structured data. Other consumers import from `./refs`
18
+ * directly.
19
+ */
20
+ export type { AssetRef } from './refs.js';
21
+ import type { AssetRef } from './refs.js';
22
+ /**
23
+ * Every asset error maps to exactly one HTTP status. Declaring it on the
24
+ * class — not in every route handler — means adding a new error subclass
25
+ * requires no route-handler changes (OCP). Kept as a type union rather
26
+ * than `number` so that a typo at the class level fails to compile.
27
+ */
28
+ export type AssetErrorHttpStatus = 400 | 404 | 409 | 500;
29
+ /**
30
+ * JSON body shape for `AssetError.toResponseBody()`. Every response body
31
+ * has at least `{ code, message }`; structured subclasses (AssetInUseError,
32
+ * AssetValidationError) override `toResponseBody()` to attach extra fields.
33
+ *
34
+ * The admin client's Zod schemas (`admin-api/schemas/assets.ts`) parse the
35
+ * body into typed responses; drift between server serialization and client
36
+ * parsing is a compile-time error.
37
+ */
38
+ export interface AssetErrorResponseBody {
39
+ readonly code: AssetErrorCode;
40
+ readonly message: string;
41
+ readonly [extra: string]: unknown;
42
+ }
43
+ export declare abstract class AssetError extends Error {
44
+ abstract readonly code: AssetErrorCode;
45
+ /** HTTP status this error maps to at the transport boundary. */
46
+ abstract readonly httpStatus: AssetErrorHttpStatus;
47
+ constructor(message: string);
48
+ /**
49
+ * Serialize this error to a JSON response body. Default shape is
50
+ * `{ code, message }`; subclasses override to add structured data.
51
+ * Transport-boundary polymorphism — no `instanceof` chain needed at
52
+ * the route mapper.
53
+ */
54
+ toResponseBody(): AssetErrorResponseBody;
55
+ }
56
+ /**
57
+ * Upload-validation failure hierarchy.
58
+ *
59
+ * Each concrete reason a candidate can be rejected is its own class. No
60
+ * god-class taking a polymorphic `code` argument — the class itself is
61
+ * the reason. Benefits (SOLID):
62
+ *
63
+ * - SRP: each class has one reason to change.
64
+ * - OCP: adding a new validation reason = new class, no edits to
65
+ * existing ones; the httpStatus (400) is inherited.
66
+ * - LSP: every subclass fully honors `AssetValidationError` — an
67
+ * `instanceof AssetValidationError` check still groups them.
68
+ * - ISP: callers that only care about "was this input-invalid?" match
69
+ * the base class; callers that branch on specific reasons use the
70
+ * concrete subclass.
71
+ *
72
+ * The `AssetValidationError` base stays as the umbrella for callers that
73
+ * treat all input-validation failures uniformly (HTTP always maps to 400).
74
+ */
75
+ export declare abstract class AssetValidationError extends AssetError {
76
+ readonly httpStatus: 400;
77
+ }
78
+ /** Asset name failed character / length rules. */
79
+ export declare class AssetNameInvalidError extends AssetValidationError {
80
+ readonly name: string;
81
+ readonly code: "ASSET_NAME_INVALID";
82
+ constructor(name: string, message: string);
83
+ }
84
+ /** Asset name attempted path traversal (`..`, leading `/`, backslash). */
85
+ export declare class AssetPathTraversalError extends AssetValidationError {
86
+ readonly name: string;
87
+ readonly code: "ASSET_PATH_TRAVERSAL";
88
+ constructor(name: string);
89
+ }
90
+ /** Asset name collides with a reserved prefix or suffix. */
91
+ export declare class AssetNameReservedError extends AssetValidationError {
92
+ readonly name: string;
93
+ readonly reservedToken: string;
94
+ readonly position: 'prefix' | 'suffix';
95
+ readonly code: "ASSET_NAME_RESERVED";
96
+ constructor(name: string, reservedToken: string, position: 'prefix' | 'suffix');
97
+ }
98
+ /** Asset bytes exceed the configured size limit, or claimed size is zero. */
99
+ export declare class AssetSizeExceededError extends AssetValidationError {
100
+ readonly claimedSize: number;
101
+ readonly maxBytes: number;
102
+ readonly code: "ASSET_SIZE_EXCEEDED";
103
+ constructor(claimedSize: number, maxBytes: number);
104
+ }
105
+ /**
106
+ * Sniffed MIME is absent or not in the allowlist. The class owns its own
107
+ * message construction — no caller passes a pre-baked string. Two distinct
108
+ * failure reasons share the same `code` because they're the same error
109
+ * semantically ("the MIME isn't usable"): distinguishable by inspecting
110
+ * `sniffedMime === null` vs set.
111
+ */
112
+ export declare class AssetMimeMismatchError extends AssetValidationError {
113
+ readonly sniffedMime: string | null;
114
+ readonly allowedMimes: readonly string[];
115
+ readonly code: "ASSET_MIME_MISMATCH";
116
+ constructor(sniffedMime: string | null, allowedMimes: readonly string[]);
117
+ }
118
+ /** Wraps an underlying storage-layer failure during an asset operation. */
119
+ export declare class AssetStorageError extends AssetError {
120
+ readonly operation: 'read' | 'write' | 'delete' | 'stat';
121
+ readonly path: string;
122
+ readonly code: "ASSET_STORAGE_FAILURE";
123
+ readonly httpStatus: 500;
124
+ constructor(operation: 'read' | 'write' | 'delete' | 'stat', path: string, cause: unknown);
125
+ }
126
+ /** Manifest JSON couldn't be parsed. */
127
+ export declare class AssetManifestCorruptError extends AssetError {
128
+ readonly code: "ASSET_MANIFEST_CORRUPT";
129
+ readonly httpStatus: 500;
130
+ constructor(path: string, cause: unknown);
131
+ }
132
+ /** Manifest file missing — asset name doesn't exist on this target. */
133
+ export declare class AssetManifestNotFoundError extends AssetError {
134
+ readonly code: "ASSET_MANIFEST_NOT_FOUND";
135
+ readonly httpStatus: 404;
136
+ constructor(name: string);
137
+ }
138
+ /**
139
+ * Delete was attempted on an asset that pages or fragments still reference.
140
+ * The design doc's delete-blocked contract: surface the usage list so the
141
+ * author can rewrite refs or pick a replacement. `refs` is attached as
142
+ * structured data — HTTP layer serializes it into the 409 response body.
143
+ */
144
+ export declare class AssetInUseError extends AssetError {
145
+ readonly assetName: string;
146
+ readonly refs: readonly AssetRef[];
147
+ readonly code: "ASSET_IN_USE";
148
+ readonly httpStatus: 409;
149
+ constructor(assetName: string, refs: readonly AssetRef[]);
150
+ toResponseBody(): AssetErrorResponseBody;
151
+ }
152
+ /**
153
+ * Manifest MIME has no known extension mapping, so path enumeration
154
+ * can't be completed. Operations that need the full path set (delete,
155
+ * rename, GC) can't proceed. Distinct from validation failure (the
156
+ * manifest is fine — we just don't know how to lay out bytes for this
157
+ * MIME) and from storage failure (nothing failed I/O).
158
+ *
159
+ * In practice, reaching this means a new kind was added without
160
+ * extending `url.ts#extFromMime` — the type points at exactly what
161
+ * needs a fix.
162
+ */
163
+ export declare class AssetMimeUnsupportedError extends AssetError {
164
+ readonly mime: string;
165
+ readonly assetName: string;
166
+ readonly code: "ASSET_MIME_UNSUPPORTED";
167
+ readonly httpStatus: 500;
168
+ constructor(mime: string, assetName: string);
169
+ }
170
+ /**
171
+ * Responsive-variant generation failed during upload ingest. The original
172
+ * bytes passed MIME sniffing and dimension extraction but sharp could not
173
+ * resize them — usually means truncation, corruption, or a decompression-
174
+ * bomb that sharp declined to decode. The ingest pipeline rolls back the
175
+ * main-bytes write on this error so the upload fails atomically. HTTP
176
+ * 400 (client-correctable: re-upload a non-broken image).
177
+ *
178
+ * Distinct from `AssetMimeMismatchError` (MIME-sniff rejection) because
179
+ * the file may be a legitimate JPEG/PNG on paper — we only discovered
180
+ * the problem once sharp tried to do real work with the pixels.
181
+ */
182
+ export declare class AssetVariantGenerationError extends AssetError {
183
+ readonly assetName: string;
184
+ readonly code: "ASSET_VARIANT_GENERATION_FAILED";
185
+ readonly httpStatus: 400;
186
+ constructor(assetName: string, cause: unknown);
187
+ }
188
+ /**
189
+ * Format-specific preprocessing failed during ingest. Today: SVG
190
+ * sanitization (DOMPurify rejected the input as malformed XML or it
191
+ * carried oversized embedded base64). Future: HEIC→JPEG transcode,
192
+ * EXIF-orientation flatten, animated-GIF frame extraction.
193
+ *
194
+ * 400 because the input is the problem (client-correctable). The
195
+ * specific reason is on `reason` so route handlers / clients can
196
+ * branch on it. `format` (the MIME) lets clients show the right
197
+ * remediation copy.
198
+ */
199
+ export declare class AssetPreprocessError extends AssetError {
200
+ readonly format: string;
201
+ readonly reason: string;
202
+ readonly code: "ASSET_PREPROCESS_FAILED";
203
+ readonly httpStatus: 400;
204
+ constructor(format: string, reason: string, cause?: unknown);
205
+ toResponseBody(): AssetErrorResponseBody;
206
+ }
207
+ /**
208
+ * Rename was attempted to a name that's already taken by another asset.
209
+ * Per design-media.md → Rename: copying onto an existing asset would
210
+ * silently merge two distinct assets into one — the operation refuses
211
+ * instead. Authors who genuinely want to merge use replace-and-delete
212
+ * (different verb, explicit kind-compat check). HTTP 409.
213
+ */
214
+ export declare class AssetNameCollisionError extends AssetError {
215
+ readonly newName: string;
216
+ readonly code: "ASSET_NAME_COLLISION";
217
+ readonly httpStatus: 409;
218
+ constructor(newName: string);
219
+ toResponseBody(): AssetErrorResponseBody;
220
+ }
221
+ /**
222
+ * Replace was attempted between two assets whose kinds (or within
223
+ * `embedded`, MIME categories) don't match. Per design-media.md →
224
+ * Delete semantics: "same kind (embedded ↔ embedded, downloadable ↔
225
+ * downloadable). Within embedded, cross-subtype is blocked
226
+ * (image ≠ video)."
227
+ *
228
+ * Carries structured fields so the UI can render a specific message
229
+ * ("image → video not allowed") without parsing the human message.
230
+ */
231
+ export declare class AssetKindMismatchError extends AssetError {
232
+ readonly oldKind: string;
233
+ readonly oldMimeCategory: string;
234
+ readonly newKind: string;
235
+ readonly newMimeCategory: string;
236
+ readonly code: "ASSET_KIND_MISMATCH";
237
+ readonly httpStatus: 409;
238
+ constructor(oldKind: string, oldMimeCategory: string, newKind: string, newMimeCategory: string);
239
+ toResponseBody(): AssetErrorResponseBody;
240
+ }
241
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/assets/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Typed errors for the asset domain.
3
+ *
4
+ * Every asset-domain failure is one of these classes — never a plain
5
+ * `new Error('not implemented')`. Callers pattern-match on the class to
6
+ * decide what to do (HTTP status, CLI exit code, retry policy, user
7
+ * message). Subclassing keeps the public error taxonomy small and stable.
8
+ *
9
+ * The `code` property is the machine-readable identifier. Messages are
10
+ * human-readable and may include path/name details; tests should match
11
+ * on `code`, not on message text.
12
+ */
13
+ export class AssetError extends Error {
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = this.constructor.name;
17
+ }
18
+ /**
19
+ * Serialize this error to a JSON response body. Default shape is
20
+ * `{ code, message }`; subclasses override to add structured data.
21
+ * Transport-boundary polymorphism — no `instanceof` chain needed at
22
+ * the route mapper.
23
+ */
24
+ toResponseBody() {
25
+ return { code: this.code, message: this.message };
26
+ }
27
+ }
28
+ /**
29
+ * Upload-validation failure hierarchy.
30
+ *
31
+ * Each concrete reason a candidate can be rejected is its own class. No
32
+ * god-class taking a polymorphic `code` argument — the class itself is
33
+ * the reason. Benefits (SOLID):
34
+ *
35
+ * - SRP: each class has one reason to change.
36
+ * - OCP: adding a new validation reason = new class, no edits to
37
+ * existing ones; the httpStatus (400) is inherited.
38
+ * - LSP: every subclass fully honors `AssetValidationError` — an
39
+ * `instanceof AssetValidationError` check still groups them.
40
+ * - ISP: callers that only care about "was this input-invalid?" match
41
+ * the base class; callers that branch on specific reasons use the
42
+ * concrete subclass.
43
+ *
44
+ * The `AssetValidationError` base stays as the umbrella for callers that
45
+ * treat all input-validation failures uniformly (HTTP always maps to 400).
46
+ */
47
+ export class AssetValidationError extends AssetError {
48
+ httpStatus = 400;
49
+ }
50
+ /** Asset name failed character / length rules. */
51
+ export class AssetNameInvalidError extends AssetValidationError {
52
+ name;
53
+ code = 'ASSET_NAME_INVALID';
54
+ constructor(name, message) {
55
+ super(message);
56
+ this.name = name;
57
+ }
58
+ }
59
+ /** Asset name attempted path traversal (`..`, leading `/`, backslash). */
60
+ export class AssetPathTraversalError extends AssetValidationError {
61
+ name;
62
+ code = 'ASSET_PATH_TRAVERSAL';
63
+ constructor(name) {
64
+ super(`Asset name contains path traversal: ${name}`);
65
+ this.name = name;
66
+ }
67
+ }
68
+ /** Asset name collides with a reserved prefix or suffix. */
69
+ export class AssetNameReservedError extends AssetValidationError {
70
+ name;
71
+ reservedToken;
72
+ position;
73
+ code = 'ASSET_NAME_RESERVED';
74
+ constructor(name, reservedToken, position) {
75
+ super(`Asset name reserved (${position} "${reservedToken}"): ${name}`);
76
+ this.name = name;
77
+ this.reservedToken = reservedToken;
78
+ this.position = position;
79
+ }
80
+ }
81
+ /** Asset bytes exceed the configured size limit, or claimed size is zero. */
82
+ export class AssetSizeExceededError extends AssetValidationError {
83
+ claimedSize;
84
+ maxBytes;
85
+ code = 'ASSET_SIZE_EXCEEDED';
86
+ constructor(claimedSize, maxBytes) {
87
+ super(claimedSize <= 0
88
+ ? 'Asset size must be greater than 0'
89
+ : `Asset exceeds size limit (${claimedSize} bytes > ${maxBytes} bytes)`);
90
+ this.claimedSize = claimedSize;
91
+ this.maxBytes = maxBytes;
92
+ }
93
+ }
94
+ /**
95
+ * Sniffed MIME is absent or not in the allowlist. The class owns its own
96
+ * message construction — no caller passes a pre-baked string. Two distinct
97
+ * failure reasons share the same `code` because they're the same error
98
+ * semantically ("the MIME isn't usable"): distinguishable by inspecting
99
+ * `sniffedMime === null` vs set.
100
+ */
101
+ export class AssetMimeMismatchError extends AssetValidationError {
102
+ sniffedMime;
103
+ allowedMimes;
104
+ code = 'ASSET_MIME_MISMATCH';
105
+ constructor(sniffedMime, allowedMimes) {
106
+ super(buildMimeMismatchMessage(sniffedMime, allowedMimes));
107
+ this.sniffedMime = sniffedMime;
108
+ this.allowedMimes = allowedMimes;
109
+ }
110
+ }
111
+ function buildMimeMismatchMessage(sniffedMime, allowedMimes) {
112
+ const allowed = allowedMimes.length > 0 ? ` (allowed: ${allowedMimes.join(', ')})` : '';
113
+ if (sniffedMime === null)
114
+ return `Could not detect MIME type from bytes${allowed}`;
115
+ return `MIME "${sniffedMime}" not allowed${allowed}`;
116
+ }
117
+ /** Wraps an underlying storage-layer failure during an asset operation. */
118
+ export class AssetStorageError extends AssetError {
119
+ operation;
120
+ path;
121
+ code = 'ASSET_STORAGE_FAILURE';
122
+ httpStatus = 500;
123
+ constructor(operation, path, cause) {
124
+ super(`Storage ${operation} failed for ${path}: ${cause?.message ?? cause}`);
125
+ this.operation = operation;
126
+ this.path = path;
127
+ }
128
+ }
129
+ /** Manifest JSON couldn't be parsed. */
130
+ export class AssetManifestCorruptError extends AssetError {
131
+ code = 'ASSET_MANIFEST_CORRUPT';
132
+ httpStatus = 500;
133
+ constructor(path, cause) {
134
+ super(`Asset manifest corrupt at ${path}: ${cause?.message ?? cause}`);
135
+ }
136
+ }
137
+ /** Manifest file missing — asset name doesn't exist on this target. */
138
+ export class AssetManifestNotFoundError extends AssetError {
139
+ code = 'ASSET_MANIFEST_NOT_FOUND';
140
+ httpStatus = 404;
141
+ constructor(name) {
142
+ super(`Asset not found: ${name}`);
143
+ }
144
+ }
145
+ /**
146
+ * Delete was attempted on an asset that pages or fragments still reference.
147
+ * The design doc's delete-blocked contract: surface the usage list so the
148
+ * author can rewrite refs or pick a replacement. `refs` is attached as
149
+ * structured data — HTTP layer serializes it into the 409 response body.
150
+ */
151
+ export class AssetInUseError extends AssetError {
152
+ assetName;
153
+ refs;
154
+ code = 'ASSET_IN_USE';
155
+ httpStatus = 409;
156
+ constructor(assetName, refs) {
157
+ super(`Asset "${assetName}" is still referenced by ${refs.length} item(s)`);
158
+ this.assetName = assetName;
159
+ this.refs = refs;
160
+ }
161
+ toResponseBody() {
162
+ // Spread the base `{ code, message }` so future base-class fields
163
+ // (e.g. a request id) flow through automatically.
164
+ return {
165
+ ...super.toResponseBody(),
166
+ assetName: this.assetName,
167
+ refs: this.refs,
168
+ };
169
+ }
170
+ }
171
+ /**
172
+ * Manifest MIME has no known extension mapping, so path enumeration
173
+ * can't be completed. Operations that need the full path set (delete,
174
+ * rename, GC) can't proceed. Distinct from validation failure (the
175
+ * manifest is fine — we just don't know how to lay out bytes for this
176
+ * MIME) and from storage failure (nothing failed I/O).
177
+ *
178
+ * In practice, reaching this means a new kind was added without
179
+ * extending `url.ts#extFromMime` — the type points at exactly what
180
+ * needs a fix.
181
+ */
182
+ export class AssetMimeUnsupportedError extends AssetError {
183
+ mime;
184
+ assetName;
185
+ code = 'ASSET_MIME_UNSUPPORTED';
186
+ httpStatus = 500;
187
+ constructor(mime, assetName) {
188
+ super(`MIME "${mime}" has no extension mapping (asset "${assetName}")`);
189
+ this.mime = mime;
190
+ this.assetName = assetName;
191
+ }
192
+ }
193
+ /**
194
+ * Responsive-variant generation failed during upload ingest. The original
195
+ * bytes passed MIME sniffing and dimension extraction but sharp could not
196
+ * resize them — usually means truncation, corruption, or a decompression-
197
+ * bomb that sharp declined to decode. The ingest pipeline rolls back the
198
+ * main-bytes write on this error so the upload fails atomically. HTTP
199
+ * 400 (client-correctable: re-upload a non-broken image).
200
+ *
201
+ * Distinct from `AssetMimeMismatchError` (MIME-sniff rejection) because
202
+ * the file may be a legitimate JPEG/PNG on paper — we only discovered
203
+ * the problem once sharp tried to do real work with the pixels.
204
+ */
205
+ export class AssetVariantGenerationError extends AssetError {
206
+ assetName;
207
+ code = 'ASSET_VARIANT_GENERATION_FAILED';
208
+ httpStatus = 400;
209
+ constructor(assetName, cause) {
210
+ super(`Could not generate responsive variants for "${assetName}": ${cause?.message ?? cause}`);
211
+ this.assetName = assetName;
212
+ }
213
+ }
214
+ /**
215
+ * Format-specific preprocessing failed during ingest. Today: SVG
216
+ * sanitization (DOMPurify rejected the input as malformed XML or it
217
+ * carried oversized embedded base64). Future: HEIC→JPEG transcode,
218
+ * EXIF-orientation flatten, animated-GIF frame extraction.
219
+ *
220
+ * 400 because the input is the problem (client-correctable). The
221
+ * specific reason is on `reason` so route handlers / clients can
222
+ * branch on it. `format` (the MIME) lets clients show the right
223
+ * remediation copy.
224
+ */
225
+ export class AssetPreprocessError extends AssetError {
226
+ format;
227
+ reason;
228
+ code = 'ASSET_PREPROCESS_FAILED';
229
+ httpStatus = 400;
230
+ constructor(format, reason, cause) {
231
+ const detail = cause instanceof Error ? `: ${cause.message}` : '';
232
+ super(`Preprocessing ${format} failed (${reason})${detail}`);
233
+ this.format = format;
234
+ this.reason = reason;
235
+ }
236
+ toResponseBody() {
237
+ return {
238
+ ...super.toResponseBody(),
239
+ format: this.format,
240
+ reason: this.reason,
241
+ };
242
+ }
243
+ }
244
+ /**
245
+ * Rename was attempted to a name that's already taken by another asset.
246
+ * Per design-media.md → Rename: copying onto an existing asset would
247
+ * silently merge two distinct assets into one — the operation refuses
248
+ * instead. Authors who genuinely want to merge use replace-and-delete
249
+ * (different verb, explicit kind-compat check). HTTP 409.
250
+ */
251
+ export class AssetNameCollisionError extends AssetError {
252
+ newName;
253
+ code = 'ASSET_NAME_COLLISION';
254
+ httpStatus = 409;
255
+ constructor(newName) {
256
+ super(`Asset name already in use: ${newName}`);
257
+ this.newName = newName;
258
+ }
259
+ toResponseBody() {
260
+ return {
261
+ ...super.toResponseBody(),
262
+ newName: this.newName,
263
+ };
264
+ }
265
+ }
266
+ /**
267
+ * Replace was attempted between two assets whose kinds (or within
268
+ * `embedded`, MIME categories) don't match. Per design-media.md →
269
+ * Delete semantics: "same kind (embedded ↔ embedded, downloadable ↔
270
+ * downloadable). Within embedded, cross-subtype is blocked
271
+ * (image ≠ video)."
272
+ *
273
+ * Carries structured fields so the UI can render a specific message
274
+ * ("image → video not allowed") without parsing the human message.
275
+ */
276
+ export class AssetKindMismatchError extends AssetError {
277
+ oldKind;
278
+ oldMimeCategory;
279
+ newKind;
280
+ newMimeCategory;
281
+ code = 'ASSET_KIND_MISMATCH';
282
+ httpStatus = 409;
283
+ constructor(oldKind, oldMimeCategory, newKind, newMimeCategory) {
284
+ super(`Replacement asset kind/category mismatch: old=${oldKind}/${oldMimeCategory}, new=${newKind}/${newMimeCategory}`);
285
+ this.oldKind = oldKind;
286
+ this.oldMimeCategory = oldMimeCategory;
287
+ this.newKind = newKind;
288
+ this.newMimeCategory = newMimeCategory;
289
+ }
290
+ toResponseBody() {
291
+ return {
292
+ ...super.toResponseBody(),
293
+ oldKind: this.oldKind,
294
+ oldMimeCategory: this.oldMimeCategory,
295
+ newKind: this.newKind,
296
+ newMimeCategory: this.newMimeCategory,
297
+ };
298
+ }
299
+ }
300
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/assets/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoDH,MAAM,OAAgB,UAAW,SAAQ,KAAK;IAK5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAA;IACnC,CAAC;IAED;;;;;OAKG;IACH,cAAc;QACZ,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IACnD,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAgB,oBAAqB,SAAQ,UAAU;IAClD,UAAU,GAAG,GAAY,CAAA;CACnC;AAED,kDAAkD;AAClD,MAAM,OAAO,qBAAsB,SAAQ,oBAAoB;IAG3C;IAFT,IAAI,GAAG,oBAA6B,CAAA;IAC7C,YACkB,IAAY,EAC5B,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAA;QAHE,SAAI,GAAJ,IAAI,CAAQ;IAI9B,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,OAAO,uBAAwB,SAAQ,oBAAoB;IAEnC;IADnB,IAAI,GAAG,sBAA+B,CAAA;IAC/C,YAA4B,IAAY;QACtC,KAAK,CAAC,uCAAuC,IAAI,EAAE,CAAC,CAAA;QAD1B,SAAI,GAAJ,IAAI,CAAQ;IAExC,CAAC;CACF;AAED,4DAA4D;AAC5D,MAAM,OAAO,sBAAuB,SAAQ,oBAAoB;IAG5C;IACA;IACA;IAJT,IAAI,GAAG,qBAA8B,CAAA;IAC9C,YACkB,IAAY,EACZ,aAAqB,EACrB,QAA6B;QAE7C,KAAK,CAAC,wBAAwB,QAAQ,KAAK,aAAa,OAAO,IAAI,EAAE,CAAC,CAAA;QAJtD,SAAI,GAAJ,IAAI,CAAQ;QACZ,kBAAa,GAAb,aAAa,CAAQ;QACrB,aAAQ,GAAR,QAAQ,CAAqB;IAG/C,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,sBAAuB,SAAQ,oBAAoB;IAG5C;IACA;IAHT,IAAI,GAAG,qBAA8B,CAAA;IAC9C,YACkB,WAAmB,EACnB,QAAgB;QAEhC,KAAK,CACH,WAAW,IAAI,CAAC;YACd,CAAC,CAAC,mCAAmC;YACrC,CAAC,CAAC,6BAA6B,WAAW,YAAY,QAAQ,SAAS,CAC1E,CAAA;QAPe,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAAQ;IAOlC,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,sBAAuB,SAAQ,oBAAoB;IAG5C;IACA;IAHT,IAAI,GAAG,qBAA8B,CAAA;IAC9C,YACkB,WAA0B,EAC1B,YAA+B;QAE/C,KAAK,CAAC,wBAAwB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAA;QAH1C,gBAAW,GAAX,WAAW,CAAe;QAC1B,iBAAY,GAAZ,YAAY,CAAmB;IAGjD,CAAC;CACF;AAED,SAAS,wBAAwB,CAAC,WAA0B,EAAE,YAA+B;IAC3F,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACvF,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,wCAAwC,OAAO,EAAE,CAAA;IAClF,OAAO,SAAS,WAAW,gBAAgB,OAAO,EAAE,CAAA;AACtD,CAAC;AAED,2EAA2E;AAC3E,MAAM,OAAO,iBAAkB,SAAQ,UAAU;IAI7B;IACA;IAJT,IAAI,GAAG,uBAAgC,CAAA;IACvC,UAAU,GAAG,GAAY,CAAA;IAClC,YACkB,SAA+C,EAC/C,IAAY,EAC5B,KAAc;QAEd,KAAK,CAAC,WAAW,SAAS,eAAe,IAAI,KAAM,KAAe,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,CAAA;QAJvE,cAAS,GAAT,SAAS,CAAsC;QAC/C,SAAI,GAAJ,IAAI,CAAQ;IAI9B,CAAC;CACF;AAED,wCAAwC;AACxC,MAAM,OAAO,yBAA0B,SAAQ,UAAU;IAC9C,IAAI,GAAG,wBAAiC,CAAA;IACxC,UAAU,GAAG,GAAY,CAAA;IAClC,YAAY,IAAY,EAAE,KAAc;QACtC,KAAK,CAAC,6BAA6B,IAAI,KAAM,KAAe,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,CAAA;IACnF,CAAC;CACF;AAED,uEAAuE;AACvE,MAAM,OAAO,0BAA2B,SAAQ,UAAU;IAC/C,IAAI,GAAG,0BAAmC,CAAA;IAC1C,UAAU,GAAG,GAAY,CAAA;IAClC,YAAY,IAAY;QACtB,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAA;IACnC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAI3B;IACA;IAJT,IAAI,GAAG,cAAuB,CAAA;IAC9B,UAAU,GAAG,GAAY,CAAA;IAClC,YACkB,SAAiB,EACjB,IAAyB;QAEzC,KAAK,CAAC,UAAU,SAAS,4BAA4B,IAAI,CAAC,MAAM,UAAU,CAAC,CAAA;QAH3D,cAAS,GAAT,SAAS,CAAQ;QACjB,SAAI,GAAJ,IAAI,CAAqB;IAG3C,CAAC;IAEQ,cAAc;QACrB,kEAAkE;QAClE,kDAAkD;QAClD,OAAO;YACL,GAAG,KAAK,CAAC,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAA;IACH,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,yBAA0B,SAAQ,UAAU;IAIrC;IACA;IAJT,IAAI,GAAG,wBAAiC,CAAA;IACxC,UAAU,GAAG,GAAY,CAAA;IAClC,YACkB,IAAY,EACZ,SAAiB;QAEjC,KAAK,CAAC,SAAS,IAAI,sCAAsC,SAAS,IAAI,CAAC,CAAA;QAHvD,SAAI,GAAJ,IAAI,CAAQ;QACZ,cAAS,GAAT,SAAS,CAAQ;IAGnC,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,2BAA4B,SAAQ,UAAU;IAIvC;IAHT,IAAI,GAAG,iCAA0C,CAAA;IACjD,UAAU,GAAG,GAAY,CAAA;IAClC,YACkB,SAAiB,EACjC,KAAc;QAEd,KAAK,CAAC,+CAA+C,SAAS,MAAO,KAAe,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,CAAA;QAHzF,cAAS,GAAT,SAAS,CAAQ;IAInC,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IAIhC;IACA;IAJT,IAAI,GAAG,yBAAkC,CAAA;IACzC,UAAU,GAAG,GAAY,CAAA;IAClC,YACkB,MAAc,EACd,MAAc,EAC9B,KAAe;QAEf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACjE,KAAK,CAAC,iBAAiB,MAAM,YAAY,MAAM,IAAI,MAAM,EAAE,CAAC,CAAA;QAL5C,WAAM,GAAN,MAAM,CAAQ;QACd,WAAM,GAAN,MAAM,CAAQ;IAKhC,CAAC;IAEQ,cAAc;QACrB,OAAO;YACL,GAAG,KAAK,CAAC,cAAc,EAAE;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAA;IACH,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,uBAAwB,SAAQ,UAAU;IAGzB;IAFnB,IAAI,GAAG,sBAA+B,CAAA;IACtC,UAAU,GAAG,GAAY,CAAA;IAClC,YAA4B,OAAe;QACzC,KAAK,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAA;QADpB,YAAO,GAAP,OAAO,CAAQ;IAE3C,CAAC;IAEQ,cAAc;QACrB,OAAO;YACL,GAAG,KAAK,CAAC,cAAc,EAAE;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAA;IACH,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IAIlC;IACA;IACA;IACA;IANT,IAAI,GAAG,qBAA8B,CAAA;IACrC,UAAU,GAAG,GAAY,CAAA;IAClC,YACkB,OAAe,EACf,eAAuB,EACvB,OAAe,EACf,eAAuB;QAEvC,KAAK,CACH,iDAAiD,OAAO,IAAI,eAAe,SAAS,OAAO,IAAI,eAAe,EAAE,CACjH,CAAA;QAPe,YAAO,GAAP,OAAO,CAAQ;QACf,oBAAe,GAAf,eAAe,CAAQ;QACvB,YAAO,GAAP,OAAO,CAAQ;QACf,oBAAe,GAAf,eAAe,CAAQ;IAKzC,CAAC;IAEQ,cAAc;QACrB,OAAO;YACL,GAAG,KAAK,CAAC,cAAc,EAAE;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAA;IACH,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Find every reference to a given asset across a site's pages and
3
+ * fragments (including locale variants).
4
+ *
5
+ * Single responsibility: site-wide orchestration. Loads the site,
6
+ * iterates every manifest, delegates the per-manifest walk to
7
+ * `scan-manifest-for-asset.ts`, concatenates results.
8
+ *
9
+ * Scan-on-demand model (v1 simplification):
10
+ * - The design doc calls for an incremental `.refs/` index written on
11
+ * every save. That's a separate feature — its writer will import
12
+ * `scanManifestForAsset` directly (single-manifest granularity) and
13
+ * update the sidecar files, rather than calling this function.
14
+ * - For v1, delete-check and usage-panel reads use this full scan. O(site
15
+ * content size) per call, fine up to a few thousand pages.
16
+ */
17
+ import type { SiteManifest, StorageProvider } from '../types.js';
18
+ import type { AssetRef } from './refs.js';
19
+ export interface FindRefsInput {
20
+ storage: StorageProvider;
21
+ /** Path prefix applied to storage operations (content root). */
22
+ siteDir: string;
23
+ /** The asset name to find references to. */
24
+ assetName: string;
25
+ /**
26
+ * Optional project-level site manifest. Passed through to `loadSite` so
27
+ * scans work in contexts where the target doesn't have its own site.yaml.
28
+ */
29
+ manifest?: SiteManifest;
30
+ }
31
+ /**
32
+ * Find every page or fragment manifest that references `assetName`. One
33
+ * entry per match — a manifest that references the asset twice produces
34
+ * two entries with different `componentPath` values.
35
+ */
36
+ export declare function findAssetRefs(input: FindRefsInput): Promise<AssetRef[]>;
37
+ //# sourceMappingURL=find-refs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-refs.d.ts","sourceRoot":"","sources":["../../src/assets/find-refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIhE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,eAAe,CAAA;IACxB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA6B7E"}
@@ -0,0 +1,35 @@
1
+ import { createContentRoot } from '../content-root.js';
2
+ import { allFragmentEntries, allPageEntries, loadSite } from '../site-loader.js';
3
+ import { scanManifestForAsset } from './scan-manifest-for-asset.js';
4
+ /**
5
+ * Find every page or fragment manifest that references `assetName`. One
6
+ * entry per match — a manifest that references the asset twice produces
7
+ * two entries with different `componentPath` values.
8
+ */
9
+ export async function findAssetRefs(input) {
10
+ const contentRoot = createContentRoot(input.storage, input.siteDir);
11
+ const site = await loadSite({ contentRoot, manifest: input.manifest });
12
+ const refs = [];
13
+ for (const { name, page, locale } of allPageEntries(site)) {
14
+ refs.push(...scanManifestForAsset({
15
+ manifest: page,
16
+ manifestPath: localeManifestPath('pages', name, 'page', locale),
17
+ source: 'page',
18
+ assetName: input.assetName,
19
+ }));
20
+ }
21
+ for (const { name, fragment, locale } of allFragmentEntries(site)) {
22
+ refs.push(...scanManifestForAsset({
23
+ manifest: fragment,
24
+ manifestPath: localeManifestPath('fragments', name, 'fragment', locale),
25
+ source: 'fragment',
26
+ assetName: input.assetName,
27
+ }));
28
+ }
29
+ return refs;
30
+ }
31
+ function localeManifestPath(root, itemName, baseName, locale) {
32
+ const file = locale ? `${baseName}.${locale}.json` : `${baseName}.json`;
33
+ return `${root}/${itemName}/${file}`;
34
+ }
35
+ //# sourceMappingURL=find-refs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-refs.js","sourceRoot":"","sources":["../../src/assets/find-refs.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAgBnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAoB;IACtD,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IACnE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEtE,MAAM,IAAI,GAAe,EAAE,CAAA;IAE3B,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI,CACP,GAAG,oBAAoB,CAAC;YACtB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/D,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CACH,CAAA;IACH,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QAClE,IAAI,CAAC,IAAI,CACP,GAAG,oBAAoB,CAAC;YACtB,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,kBAAkB,CAAC,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC;YACvE,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CACH,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,kBAAkB,CACzB,IAA2B,EAC3B,QAAgB,EAChB,QAA6B,EAC7B,MAA0B;IAE1B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,OAAO,CAAA;IACvE,OAAO,GAAG,IAAI,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAA;AACtC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Length of the hex prefix embedded in asset URLs. Matches the doc's `{hash8}`. */
2
+ export declare const ASSET_HASH_LENGTH = 8;
3
+ /** Hash a complete byte buffer — convenience wrapper for tests and small payloads. */
4
+ export declare function hashBytes(bytes: Uint8Array): string;
5
+ /**
6
+ * Hash a byte stream as it flows through. Consumes the stream. Returns the
7
+ * 8-char hex prefix once the stream ends.
8
+ *
9
+ * For upload pipelines that need to both hash and persist bytes, tee the
10
+ * source stream and pass one branch here, the other to storage.
11
+ */
12
+ export declare function hashStream(stream: ReadableStream<Uint8Array>): Promise<string>;
13
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/assets/hash.ts"],"names":[],"mappings":"AAiBA,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,IAAI,CAAA;AAElC,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGnD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CASpF"}