@we8/cms 0.1.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 (304) hide show
  1. package/README.md +78 -0
  2. package/dist/auth/auth.d.ts +87 -0
  3. package/dist/auth/auth.d.ts.map +1 -0
  4. package/dist/auth/auth.js +90 -0
  5. package/dist/auth/auth.js.map +1 -0
  6. package/dist/auth/routes.admin.d.ts +22 -0
  7. package/dist/auth/routes.admin.d.ts.map +1 -0
  8. package/dist/auth/routes.admin.js +106 -0
  9. package/dist/auth/routes.admin.js.map +1 -0
  10. package/dist/auth/schema.d.ts +1395 -0
  11. package/dist/auth/schema.d.ts.map +1 -0
  12. package/dist/auth/schema.js +76 -0
  13. package/dist/auth/schema.js.map +1 -0
  14. package/dist/env.d.ts +64 -0
  15. package/dist/env.d.ts.map +1 -0
  16. package/dist/env.js +48 -0
  17. package/dist/env.js.map +1 -0
  18. package/dist/index.d.ts +22 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +170 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/keys/middleware.d.ts +54 -0
  23. package/dist/keys/middleware.d.ts.map +1 -0
  24. package/dist/keys/middleware.js +84 -0
  25. package/dist/keys/middleware.js.map +1 -0
  26. package/dist/keys/routes.admin.d.ts +16 -0
  27. package/dist/keys/routes.admin.d.ts.map +1 -0
  28. package/dist/keys/routes.admin.js +34 -0
  29. package/dist/keys/routes.admin.js.map +1 -0
  30. package/dist/keys/service.d.ts +36 -0
  31. package/dist/keys/service.d.ts.map +1 -0
  32. package/dist/keys/service.js +120 -0
  33. package/dist/keys/service.js.map +1 -0
  34. package/dist/lib/bots.d.ts +24 -0
  35. package/dist/lib/bots.d.ts.map +1 -0
  36. package/dist/lib/bots.js +79 -0
  37. package/dist/lib/bots.js.map +1 -0
  38. package/dist/lib/email.d.ts +62 -0
  39. package/dist/lib/email.d.ts.map +1 -0
  40. package/dist/lib/email.js +64 -0
  41. package/dist/lib/email.js.map +1 -0
  42. package/dist/lib/errors.d.ts +12 -0
  43. package/dist/lib/errors.d.ts.map +1 -0
  44. package/dist/lib/errors.js +23 -0
  45. package/dist/lib/errors.js.map +1 -0
  46. package/dist/lib/notify.d.ts +20 -0
  47. package/dist/lib/notify.d.ts.map +1 -0
  48. package/dist/lib/notify.js +60 -0
  49. package/dist/lib/notify.js.map +1 -0
  50. package/dist/lib/retention.d.ts +15 -0
  51. package/dist/lib/retention.d.ts.map +1 -0
  52. package/dist/lib/retention.js +40 -0
  53. package/dist/lib/retention.js.map +1 -0
  54. package/dist/lib/sanitize.d.ts +14 -0
  55. package/dist/lib/sanitize.d.ts.map +1 -0
  56. package/dist/lib/sanitize.js +145 -0
  57. package/dist/lib/sanitize.js.map +1 -0
  58. package/dist/lib/turnstile.d.ts +7 -0
  59. package/dist/lib/turnstile.d.ts.map +1 -0
  60. package/dist/lib/turnstile.js +32 -0
  61. package/dist/lib/turnstile.js.map +1 -0
  62. package/dist/lib/validate.d.ts +11 -0
  63. package/dist/lib/validate.d.ts.map +1 -0
  64. package/dist/lib/validate.js +22 -0
  65. package/dist/lib/validate.js.map +1 -0
  66. package/dist/lib/word-count.d.ts +7 -0
  67. package/dist/lib/word-count.d.ts.map +1 -0
  68. package/dist/lib/word-count.js +14 -0
  69. package/dist/lib/word-count.js.map +1 -0
  70. package/dist/middleware/auth.d.ts +46 -0
  71. package/dist/middleware/auth.d.ts.map +1 -0
  72. package/dist/middleware/auth.js +60 -0
  73. package/dist/middleware/auth.js.map +1 -0
  74. package/dist/middleware/cors.d.ts +33 -0
  75. package/dist/middleware/cors.d.ts.map +1 -0
  76. package/dist/middleware/cors.js +55 -0
  77. package/dist/middleware/cors.js.map +1 -0
  78. package/dist/middleware/module-gate.d.ts +11 -0
  79. package/dist/middleware/module-gate.d.ts.map +1 -0
  80. package/dist/middleware/module-gate.js +18 -0
  81. package/dist/middleware/module-gate.js.map +1 -0
  82. package/dist/middleware/rate-limit.d.ts +13 -0
  83. package/dist/middleware/rate-limit.d.ts.map +1 -0
  84. package/dist/middleware/rate-limit.js +30 -0
  85. package/dist/middleware/rate-limit.js.map +1 -0
  86. package/dist/middleware/request-id.d.ts +8 -0
  87. package/dist/middleware/request-id.d.ts.map +1 -0
  88. package/dist/middleware/request-id.js +11 -0
  89. package/dist/middleware/request-id.js.map +1 -0
  90. package/dist/modules/aeo/checks.d.ts +41 -0
  91. package/dist/modules/aeo/checks.d.ts.map +1 -0
  92. package/dist/modules/aeo/checks.js +127 -0
  93. package/dist/modules/aeo/checks.js.map +1 -0
  94. package/dist/modules/aeo/llms.d.ts +24 -0
  95. package/dist/modules/aeo/llms.d.ts.map +1 -0
  96. package/dist/modules/aeo/llms.js +92 -0
  97. package/dist/modules/aeo/llms.js.map +1 -0
  98. package/dist/modules/aeo/routes.admin.d.ts +12 -0
  99. package/dist/modules/aeo/routes.admin.d.ts.map +1 -0
  100. package/dist/modules/aeo/routes.admin.js +37 -0
  101. package/dist/modules/aeo/routes.admin.js.map +1 -0
  102. package/dist/modules/analytics/db.d.ts +24 -0
  103. package/dist/modules/analytics/db.d.ts.map +1 -0
  104. package/dist/modules/analytics/db.js +24 -0
  105. package/dist/modules/analytics/db.js.map +1 -0
  106. package/dist/modules/analytics/routes.admin.d.ts +6 -0
  107. package/dist/modules/analytics/routes.admin.d.ts.map +1 -0
  108. package/dist/modules/analytics/routes.admin.js +21 -0
  109. package/dist/modules/analytics/routes.admin.js.map +1 -0
  110. package/dist/modules/analytics/routes.public.d.ts +6 -0
  111. package/dist/modules/analytics/routes.public.d.ts.map +1 -0
  112. package/dist/modules/analytics/routes.public.js +33 -0
  113. package/dist/modules/analytics/routes.public.js.map +1 -0
  114. package/dist/modules/analytics/service.d.ts +16 -0
  115. package/dist/modules/analytics/service.d.ts.map +1 -0
  116. package/dist/modules/analytics/service.js +148 -0
  117. package/dist/modules/analytics/service.js.map +1 -0
  118. package/dist/modules/authors/routes.admin.d.ts +6 -0
  119. package/dist/modules/authors/routes.admin.d.ts.map +1 -0
  120. package/dist/modules/authors/routes.admin.js +29 -0
  121. package/dist/modules/authors/routes.admin.js.map +1 -0
  122. package/dist/modules/authors/routes.public.d.ts +6 -0
  123. package/dist/modules/authors/routes.public.d.ts.map +1 -0
  124. package/dist/modules/authors/routes.public.js +11 -0
  125. package/dist/modules/authors/routes.public.js.map +1 -0
  126. package/dist/modules/authors/service.d.ts +26 -0
  127. package/dist/modules/authors/service.d.ts.map +1 -0
  128. package/dist/modules/authors/service.js +116 -0
  129. package/dist/modules/authors/service.js.map +1 -0
  130. package/dist/modules/content/db.d.ts +127 -0
  131. package/dist/modules/content/db.d.ts.map +1 -0
  132. package/dist/modules/content/db.js +203 -0
  133. package/dist/modules/content/db.js.map +1 -0
  134. package/dist/modules/content/publish.d.ts +38 -0
  135. package/dist/modules/content/publish.d.ts.map +1 -0
  136. package/dist/modules/content/publish.js +184 -0
  137. package/dist/modules/content/publish.js.map +1 -0
  138. package/dist/modules/content/routes.admin.d.ts +8 -0
  139. package/dist/modules/content/routes.admin.d.ts.map +1 -0
  140. package/dist/modules/content/routes.admin.js +122 -0
  141. package/dist/modules/content/routes.admin.js.map +1 -0
  142. package/dist/modules/content/routes.public.d.ts +6 -0
  143. package/dist/modules/content/routes.public.d.ts.map +1 -0
  144. package/dist/modules/content/routes.public.js +56 -0
  145. package/dist/modules/content/routes.public.js.map +1 -0
  146. package/dist/modules/content/service.d.ts +137 -0
  147. package/dist/modules/content/service.d.ts.map +1 -0
  148. package/dist/modules/content/service.js +348 -0
  149. package/dist/modules/content/service.js.map +1 -0
  150. package/dist/modules/forms/db.d.ts +42 -0
  151. package/dist/modules/forms/db.d.ts.map +1 -0
  152. package/dist/modules/forms/db.js +62 -0
  153. package/dist/modules/forms/db.js.map +1 -0
  154. package/dist/modules/forms/forms-routes.admin.d.ts +6 -0
  155. package/dist/modules/forms/forms-routes.admin.d.ts.map +1 -0
  156. package/dist/modules/forms/forms-routes.admin.js +37 -0
  157. package/dist/modules/forms/forms-routes.admin.js.map +1 -0
  158. package/dist/modules/forms/forms-service.d.ts +18 -0
  159. package/dist/modules/forms/forms-service.d.ts.map +1 -0
  160. package/dist/modules/forms/forms-service.js +121 -0
  161. package/dist/modules/forms/forms-service.js.map +1 -0
  162. package/dist/modules/forms/routes.public.d.ts +6 -0
  163. package/dist/modules/forms/routes.public.d.ts.map +1 -0
  164. package/dist/modules/forms/routes.public.js +41 -0
  165. package/dist/modules/forms/routes.public.js.map +1 -0
  166. package/dist/modules/forms/submissions-routes.admin.d.ts +6 -0
  167. package/dist/modules/forms/submissions-routes.admin.d.ts.map +1 -0
  168. package/dist/modules/forms/submissions-routes.admin.js +46 -0
  169. package/dist/modules/forms/submissions-routes.admin.js.map +1 -0
  170. package/dist/modules/forms/submissions-service.d.ts +45 -0
  171. package/dist/modules/forms/submissions-service.d.ts.map +1 -0
  172. package/dist/modules/forms/submissions-service.js +174 -0
  173. package/dist/modules/forms/submissions-service.js.map +1 -0
  174. package/dist/modules/media/db.d.ts +15 -0
  175. package/dist/modules/media/db.d.ts.map +1 -0
  176. package/dist/modules/media/db.js +24 -0
  177. package/dist/modules/media/db.js.map +1 -0
  178. package/dist/modules/media/routes.admin.d.ts +6 -0
  179. package/dist/modules/media/routes.admin.d.ts.map +1 -0
  180. package/dist/modules/media/routes.admin.js +30 -0
  181. package/dist/modules/media/routes.admin.js.map +1 -0
  182. package/dist/modules/media/routes.public.d.ts +6 -0
  183. package/dist/modules/media/routes.public.d.ts.map +1 -0
  184. package/dist/modules/media/routes.public.js +35 -0
  185. package/dist/modules/media/routes.public.js.map +1 -0
  186. package/dist/modules/media/service.d.ts +32 -0
  187. package/dist/modules/media/service.d.ts.map +1 -0
  188. package/dist/modules/media/service.js +99 -0
  189. package/dist/modules/media/service.js.map +1 -0
  190. package/dist/modules/openapi/spec.d.ts +21 -0
  191. package/dist/modules/openapi/spec.d.ts.map +1 -0
  192. package/dist/modules/openapi/spec.js +468 -0
  193. package/dist/modules/openapi/spec.js.map +1 -0
  194. package/dist/modules/seo/jsonld.d.ts +25 -0
  195. package/dist/modules/seo/jsonld.d.ts.map +1 -0
  196. package/dist/modules/seo/jsonld.js +67 -0
  197. package/dist/modules/seo/jsonld.js.map +1 -0
  198. package/dist/modules/seo/routes.public.d.ts +6 -0
  199. package/dist/modules/seo/routes.public.d.ts.map +1 -0
  200. package/dist/modules/seo/routes.public.js +39 -0
  201. package/dist/modules/seo/routes.public.js.map +1 -0
  202. package/dist/modules/seo/sitemap.d.ts +3 -0
  203. package/dist/modules/seo/sitemap.d.ts.map +1 -0
  204. package/dist/modules/seo/sitemap.js +39 -0
  205. package/dist/modules/seo/sitemap.js.map +1 -0
  206. package/dist/modules/settings/routes.admin.d.ts +12 -0
  207. package/dist/modules/settings/routes.admin.d.ts.map +1 -0
  208. package/dist/modules/settings/routes.admin.js +27 -0
  209. package/dist/modules/settings/routes.admin.js.map +1 -0
  210. package/dist/modules/site-documents/routes.admin.d.ts +10 -0
  211. package/dist/modules/site-documents/routes.admin.d.ts.map +1 -0
  212. package/dist/modules/site-documents/routes.admin.js +29 -0
  213. package/dist/modules/site-documents/routes.admin.js.map +1 -0
  214. package/dist/modules/site-documents/routes.public.d.ts +6 -0
  215. package/dist/modules/site-documents/routes.public.d.ts.map +1 -0
  216. package/dist/modules/site-documents/routes.public.js +16 -0
  217. package/dist/modules/site-documents/routes.public.js.map +1 -0
  218. package/dist/modules/site-documents/service.d.ts +11 -0
  219. package/dist/modules/site-documents/service.d.ts.map +1 -0
  220. package/dist/modules/site-documents/service.js +42 -0
  221. package/dist/modules/site-documents/service.js.map +1 -0
  222. package/dist/modules/webhooks/dispatch.d.ts +14 -0
  223. package/dist/modules/webhooks/dispatch.d.ts.map +1 -0
  224. package/dist/modules/webhooks/dispatch.js +84 -0
  225. package/dist/modules/webhooks/dispatch.js.map +1 -0
  226. package/dist/shared/constants.d.ts +79 -0
  227. package/dist/shared/constants.d.ts.map +1 -0
  228. package/dist/shared/constants.js +89 -0
  229. package/dist/shared/constants.js.map +1 -0
  230. package/dist/shared/envelope.d.ts +37 -0
  231. package/dist/shared/envelope.d.ts.map +1 -0
  232. package/dist/shared/envelope.js +46 -0
  233. package/dist/shared/envelope.js.map +1 -0
  234. package/dist/shared/hash.d.ts +2 -0
  235. package/dist/shared/hash.d.ts.map +1 -0
  236. package/dist/shared/hash.js +8 -0
  237. package/dist/shared/hash.js.map +1 -0
  238. package/dist/shared/index.d.ts +13 -0
  239. package/dist/shared/index.d.ts.map +1 -0
  240. package/dist/shared/index.js +13 -0
  241. package/dist/shared/index.js.map +1 -0
  242. package/dist/shared/schemas/aeo.d.ts +182 -0
  243. package/dist/shared/schemas/aeo.d.ts.map +1 -0
  244. package/dist/shared/schemas/aeo.js +43 -0
  245. package/dist/shared/schemas/aeo.js.map +1 -0
  246. package/dist/shared/schemas/analytics.d.ts +277 -0
  247. package/dist/shared/schemas/analytics.d.ts.map +1 -0
  248. package/dist/shared/schemas/analytics.js +74 -0
  249. package/dist/shared/schemas/analytics.js.map +1 -0
  250. package/dist/shared/schemas/api-key.d.ts +77 -0
  251. package/dist/shared/schemas/api-key.d.ts.map +1 -0
  252. package/dist/shared/schemas/api-key.js +27 -0
  253. package/dist/shared/schemas/api-key.js.map +1 -0
  254. package/dist/shared/schemas/author.d.ts +147 -0
  255. package/dist/shared/schemas/author.d.ts.map +1 -0
  256. package/dist/shared/schemas/author.js +27 -0
  257. package/dist/shared/schemas/author.js.map +1 -0
  258. package/dist/shared/schemas/form.d.ts +341 -0
  259. package/dist/shared/schemas/form.d.ts.map +1 -0
  260. package/dist/shared/schemas/form.js +117 -0
  261. package/dist/shared/schemas/form.js.map +1 -0
  262. package/dist/shared/schemas/index.d.ts +12 -0
  263. package/dist/shared/schemas/index.d.ts.map +1 -0
  264. package/dist/shared/schemas/index.js +12 -0
  265. package/dist/shared/schemas/index.js.map +1 -0
  266. package/dist/shared/schemas/media.d.ts +42 -0
  267. package/dist/shared/schemas/media.d.ts.map +1 -0
  268. package/dist/shared/schemas/media.js +16 -0
  269. package/dist/shared/schemas/media.js.map +1 -0
  270. package/dist/shared/schemas/pagination.d.ts +34 -0
  271. package/dist/shared/schemas/pagination.d.ts.map +1 -0
  272. package/dist/shared/schemas/pagination.js +21 -0
  273. package/dist/shared/schemas/pagination.js.map +1 -0
  274. package/dist/shared/schemas/post.d.ts +862 -0
  275. package/dist/shared/schemas/post.d.ts.map +1 -0
  276. package/dist/shared/schemas/post.js +187 -0
  277. package/dist/shared/schemas/post.js.map +1 -0
  278. package/dist/shared/schemas/settings.d.ts +839 -0
  279. package/dist/shared/schemas/settings.d.ts.map +1 -0
  280. package/dist/shared/schemas/settings.js +202 -0
  281. package/dist/shared/schemas/settings.js.map +1 -0
  282. package/dist/shared/schemas/site-document.d.ts +38 -0
  283. package/dist/shared/schemas/site-document.d.ts.map +1 -0
  284. package/dist/shared/schemas/site-document.js +21 -0
  285. package/dist/shared/schemas/site-document.js.map +1 -0
  286. package/dist/shared/schemas/webhook.d.ts +39 -0
  287. package/dist/shared/schemas/webhook.d.ts.map +1 -0
  288. package/dist/shared/schemas/webhook.js +20 -0
  289. package/dist/shared/schemas/webhook.js.map +1 -0
  290. package/dist/spa.d.ts +9 -0
  291. package/dist/spa.d.ts.map +1 -0
  292. package/dist/spa.js +57 -0
  293. package/dist/spa.js.map +1 -0
  294. package/migrations/0001_settings.sql +39 -0
  295. package/migrations/0002_content.sql +135 -0
  296. package/migrations/0003_forms.sql +35 -0
  297. package/migrations/0004_analytics.sql +42 -0
  298. package/migrations/0005_media.sql +17 -0
  299. package/migrations/0006_site_documents.sql +18 -0
  300. package/migrations/0007_auth.sql +81 -0
  301. package/migrations/0008_api_keys.sql +20 -0
  302. package/package.json +68 -0
  303. package/scripts/bundle-admin.mjs +54 -0
  304. package/seed/local.sql +63 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissions-service.js","sourceRoot":"","sources":["../../../src/modules/forms/submissions-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { MediaAssetRecord } from '../../shared/index.js';
2
+ export interface MediaAssetRow {
3
+ id: string;
4
+ r2_key: string;
5
+ filename: string;
6
+ content_type: string;
7
+ size: number;
8
+ width: number | null;
9
+ height: number | null;
10
+ alt: string | null;
11
+ created_at: string;
12
+ }
13
+ export declare function toMediaAssetRecord(row: MediaAssetRow): MediaAssetRecord;
14
+ export declare function fetchMediaAssetRow(db: D1Database, id: string): Promise<MediaAssetRow>;
15
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/modules/media/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,gBAAgB,CAYvE;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAO3F"}
@@ -0,0 +1,24 @@
1
+ import { HttpError } from '../../lib/errors.js';
2
+ export function toMediaAssetRecord(row) {
3
+ return {
4
+ id: row.id,
5
+ r2Key: row.r2_key,
6
+ filename: row.filename,
7
+ contentType: row.content_type,
8
+ size: row.size,
9
+ width: row.width,
10
+ height: row.height,
11
+ alt: row.alt,
12
+ createdAt: row.created_at,
13
+ };
14
+ }
15
+ export async function fetchMediaAssetRow(db, id) {
16
+ const row = await db
17
+ .prepare('SELECT * FROM media_assets WHERE id = ?1')
18
+ .bind(id)
19
+ .first();
20
+ if (!row)
21
+ throw new HttpError('not_found', 'media asset not found');
22
+ return row;
23
+ }
24
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/modules/media/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAchD,MAAM,UAAU,kBAAkB,CAAC,GAAkB;IACnD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,MAAM;QACjB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAc,EAAE,EAAU;IACjE,MAAM,GAAG,GAAG,MAAM,EAAE;SACjB,OAAO,CAAC,0CAA0C,CAAC;SACnD,IAAI,CAAC,EAAE,CAAC;SACR,KAAK,EAAiB,CAAC;IAC1B,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;IACpE,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Hono } from 'hono';
2
+ import type { Bindings } from '../../env.js';
3
+ export declare const mediaAdminRoutes: Hono<{
4
+ Bindings: Bindings;
5
+ }, import("hono/types").BlankSchema, "/">;
6
+ //# sourceMappingURL=routes.admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.admin.d.ts","sourceRoot":"","sources":["../../../src/modules/media/routes.admin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAK7C,eAAO,MAAM,gBAAgB;cAAwB,QAAQ;yCAAK,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { mediaUpdateInputSchema, ok, paginationQuerySchema } from '../../shared/index.js';
2
+ import { Hono } from 'hono';
3
+ import { HttpError } from '../../lib/errors.js';
4
+ import { parseOrThrow } from '../../lib/validate.js';
5
+ import { deleteMedia, listMediaAdmin, updateMediaAlt, uploadMedia } from './service.js';
6
+ export const mediaAdminRoutes = new Hono();
7
+ mediaAdminRoutes.get('/', async (c) => {
8
+ const query = parseOrThrow(paginationQuerySchema, c.req.query());
9
+ const { items, total } = await listMediaAdmin(c.env.DB, query);
10
+ return c.json(ok({ items, page: query.page, pageSize: query.pageSize, total }));
11
+ });
12
+ mediaAdminRoutes.post('/', async (c) => {
13
+ const body = await c.req.parseBody();
14
+ const file = body['file'];
15
+ if (!(file instanceof File)) {
16
+ throw new HttpError('validation_error', 'expected a "file" field in the multipart body');
17
+ }
18
+ const asset = await uploadMedia(c.env.DB, c.env.MEDIA, file);
19
+ return c.json(ok({ asset }), 201);
20
+ });
21
+ mediaAdminRoutes.patch('/:id', async (c) => {
22
+ const input = parseOrThrow(mediaUpdateInputSchema, await c.req.json());
23
+ const asset = await updateMediaAlt(c.env.DB, c.req.param('id'), input.alt);
24
+ return c.json(ok({ asset }));
25
+ });
26
+ mediaAdminRoutes.delete('/:id', async (c) => {
27
+ await deleteMedia(c.env.DB, c.env.MEDIA, c.req.param('id'));
28
+ return c.json(ok({}));
29
+ });
30
+ //# sourceMappingURL=routes.admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.admin.js","sourceRoot":"","sources":["../../../src/modules/media/routes.admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,EAAE,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAExF,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,IAAI,EAA0B,CAAC;AAEnE,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACpC,MAAM,KAAK,GAAG,YAAY,CAAC,qBAAqB,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACjE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAClF,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,+CAA+C,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACzC,MAAM,KAAK,GAAG,YAAY,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEH,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1C,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Hono } from 'hono';
2
+ import type { Bindings } from '../../env.js';
3
+ export declare const mediaPublicRoutes: Hono<{
4
+ Bindings: Bindings;
5
+ }, import("hono/types").BlankSchema, "/">;
6
+ //# sourceMappingURL=routes.public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.public.d.ts","sourceRoot":"","sources":["../../../src/modules/media/routes.public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,eAAO,MAAM,iBAAiB;cAAwB,QAAQ;yCAAK,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { Hono } from 'hono';
2
+ import { corsMiddleware } from '../../middleware/cors.js';
3
+ export const mediaPublicRoutes = new Hono();
4
+ mediaPublicRoutes.use('/:key{.+}', corsMiddleware('publicRead'));
5
+ // :key{.+}, not a bare *: R2 keys contain slashes ({yyyy}/{mm}/{uuid}-{slug}),
6
+ // and in this Hono version a bare `/*` route does not populate
7
+ // c.req.param('*') (confirmed empirically; it comes back undefined). The
8
+ // regex-constrained named param is what actually captures a multi-segment
9
+ // path here.
10
+ mediaPublicRoutes.get('/:key{.+}', async (c) => {
11
+ const key = c.req.param('key');
12
+ const object = await c.env.MEDIA.get(key);
13
+ if (!object) {
14
+ return c.notFound();
15
+ }
16
+ const contentType = object.httpMetadata?.contentType ?? 'application/octet-stream';
17
+ const headers = {
18
+ 'Content-Type': contentType,
19
+ 'Cache-Control': 'public, max-age=31536000, immutable',
20
+ // Never let the browser MIME-sniff a stored object into an executable
21
+ // type; the declared Content-Type is authoritative.
22
+ 'X-Content-Type-Options': 'nosniff',
23
+ };
24
+ // SVG and PDF can carry active content (script in an SVG, JavaScript in a
25
+ // PDF). They stay in the allowed upload set, since an SVG is a legitimate
26
+ // brand asset, and still embed through <img> and <embed>, but DIRECT
27
+ // navigation to the object URL is forced to download rather than render in
28
+ // the site's origin. That closes the stored-XSS path where a same-origin
29
+ // media URL is opened as a document.
30
+ if (contentType === 'image/svg+xml' || contentType === 'application/pdf') {
31
+ headers['Content-Disposition'] = 'attachment';
32
+ }
33
+ return new Response(object.body, { headers });
34
+ });
35
+ //# sourceMappingURL=routes.public.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.public.js","sourceRoot":"","sources":["../../../src/modules/media/routes.public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,IAAI,EAA0B,CAAC;AAEpE,iBAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;AAEjE,+EAA+E;AAC/E,+DAA+D;AAC/D,yEAAyE;AACzE,0EAA0E;AAC1E,aAAa;AACb,iBAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7C,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,EAAE,WAAW,IAAI,0BAA0B,CAAC;IAEnF,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,WAAW;QAC3B,eAAe,EAAE,qCAAqC;QACtD,sEAAsE;QACtE,oDAAoD;QACpD,wBAAwB,EAAE,SAAS;KACpC,CAAC;IAEF,0EAA0E;IAC1E,0EAA0E;IAC1E,qEAAqE;IACrE,2EAA2E;IAC3E,yEAAyE;IACzE,qCAAqC;IACrC,IAAI,WAAW,KAAK,eAAe,IAAI,WAAW,KAAK,iBAAiB,EAAE,CAAC;QACzE,OAAO,CAAC,qBAAqB,CAAC,GAAG,YAAY,CAAC;IAChD,CAAC;IAED,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { MediaAssetRecord } from '../../shared/index.js';
2
+ export interface UploadableFile {
3
+ name: string;
4
+ type: string;
5
+ size: number;
6
+ arrayBuffer(): Promise<ArrayBuffer>;
7
+ }
8
+ /**
9
+ * width and height are NOT computed here: doing so means parsing image binary
10
+ * headers, and this worker is deliberately not image-aware (variants belong to
11
+ * Cloudflare Image Resizing URL parameters, not to CMS code). Both columns stay
12
+ * NULL at upload time; revisit if the admin needs them.
13
+ */
14
+ export declare function uploadMedia(db: D1Database, bucket: R2Bucket, file: UploadableFile, now?: Date): Promise<MediaAssetRecord>;
15
+ export interface ListMediaQuery {
16
+ page: number;
17
+ pageSize: number;
18
+ }
19
+ export declare function listMediaAdmin(db: D1Database, query: ListMediaQuery): Promise<{
20
+ items: MediaAssetRecord[];
21
+ total: number;
22
+ }>;
23
+ /**
24
+ * Alt text is the ONLY mutable field on a media asset: the bytes
25
+ * and the R2 key are immutable by design (edge caches serve them with
26
+ * max-age=31536000), so everything derived from the file stays frozen while
27
+ * the accessibility metadata can be fixed after upload. An empty string
28
+ * clears (stored as NULL), matching the record's nullable alt.
29
+ */
30
+ export declare function updateMediaAlt(db: D1Database, id: string, alt: string | undefined): Promise<MediaAssetRecord>;
31
+ export declare function deleteMedia(db: D1Database, bucket: R2Bucket, id: string): Promise<void>;
32
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/media/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAuB9D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;CACrC;AAqBD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,cAAc,EACpB,GAAG,GAAE,IAAiB,GACrB,OAAO,CAAC,gBAAgB,CAAC,CA6B3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,cAAc,CAClC,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAavD;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,UAAU,EACd,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7F"}
@@ -0,0 +1,99 @@
1
+ import { HttpError } from '../../lib/errors.js';
2
+ import { fetchMediaAssetRow, toMediaAssetRecord } from './db.js';
3
+ const MAX_UPLOAD_BYTES = 10 * 1024 * 1024; // 10MB
4
+ /**
5
+ * Images and PDF. The two icon MIME types exist for one purpose:
6
+ * brand.faviconIcoUrl needs a real .ico uploadable through the same media pool
7
+ * every other brand slot uses, and browsers report .ico as either of them
8
+ * depending on the platform.
9
+ */
10
+ const ALLOWED_CONTENT_TYPES = new Set([
11
+ 'image/jpeg',
12
+ 'image/png',
13
+ 'image/gif',
14
+ 'image/webp',
15
+ 'image/svg+xml',
16
+ 'image/x-icon',
17
+ 'image/vnd.microsoft.icon',
18
+ 'application/pdf',
19
+ ]);
20
+ function slugifyFilenameBase(base) {
21
+ const slug = base
22
+ .toLowerCase()
23
+ .replace(/[^a-z0-9]+/g, '-')
24
+ .replace(/^-+|-+$/g, '');
25
+ return slug || 'file';
26
+ }
27
+ /** The object key layout: {yyyy}/{mm}/{uuid}-{slug-filename}. */
28
+ function buildR2Key(now, filename) {
29
+ const year = now.getUTCFullYear();
30
+ const month = String(now.getUTCMonth() + 1).padStart(2, '0');
31
+ const dotIndex = filename.lastIndexOf('.');
32
+ const base = dotIndex > 0 ? filename.slice(0, dotIndex) : filename;
33
+ const ext = dotIndex > 0 ? filename.slice(dotIndex) : '';
34
+ const slug = slugifyFilenameBase(base);
35
+ return `${year}/${month}/${crypto.randomUUID()}-${slug}${ext}`;
36
+ }
37
+ /**
38
+ * width and height are NOT computed here: doing so means parsing image binary
39
+ * headers, and this worker is deliberately not image-aware (variants belong to
40
+ * Cloudflare Image Resizing URL parameters, not to CMS code). Both columns stay
41
+ * NULL at upload time; revisit if the admin needs them.
42
+ */
43
+ export async function uploadMedia(db, bucket, file, now = new Date()) {
44
+ if (!ALLOWED_CONTENT_TYPES.has(file.type)) {
45
+ throw new HttpError('validation_error', `unsupported content type: ${file.type}`);
46
+ }
47
+ if (file.size > MAX_UPLOAD_BYTES) {
48
+ throw new HttpError('payload_too_large', 'file exceeds the 10MB upload limit');
49
+ }
50
+ const r2Key = buildR2Key(now, file.name);
51
+ const buffer = await file.arrayBuffer();
52
+ await bucket.put(r2Key, buffer, { httpMetadata: { contentType: file.type } });
53
+ const id = crypto.randomUUID();
54
+ try {
55
+ await db
56
+ .prepare(`INSERT INTO media_assets (id, r2_key, filename, content_type, size) VALUES (?1, ?2, ?3, ?4, ?5)`)
57
+ .bind(id, r2Key, file.name, file.type, file.size)
58
+ .run();
59
+ }
60
+ catch (err) {
61
+ // Keep R2 and D1 in sync: if the metadata row fails to write, don't
62
+ // leave an orphaned object with no corresponding admin-visible record.
63
+ await bucket.delete(r2Key);
64
+ throw err;
65
+ }
66
+ return toMediaAssetRecord(await fetchMediaAssetRow(db, id));
67
+ }
68
+ export async function listMediaAdmin(db, query) {
69
+ const offset = (query.page - 1) * query.pageSize;
70
+ const { results } = await db
71
+ .prepare('SELECT * FROM media_assets ORDER BY created_at DESC LIMIT ?1 OFFSET ?2')
72
+ .bind(query.pageSize, offset)
73
+ .all();
74
+ const { results: countResults } = await db
75
+ .prepare('SELECT COUNT(*) as count FROM media_assets')
76
+ .all();
77
+ return { items: results.map(toMediaAssetRecord), total: countResults[0]?.count ?? 0 };
78
+ }
79
+ /**
80
+ * Alt text is the ONLY mutable field on a media asset: the bytes
81
+ * and the R2 key are immutable by design (edge caches serve them with
82
+ * max-age=31536000), so everything derived from the file stays frozen while
83
+ * the accessibility metadata can be fixed after upload. An empty string
84
+ * clears (stored as NULL), matching the record's nullable alt.
85
+ */
86
+ export async function updateMediaAlt(db, id, alt) {
87
+ await fetchMediaAssetRow(db, id);
88
+ await db
89
+ .prepare('UPDATE media_assets SET alt = ?1 WHERE id = ?2')
90
+ .bind(alt ? alt : null, id)
91
+ .run();
92
+ return toMediaAssetRecord(await fetchMediaAssetRow(db, id));
93
+ }
94
+ export async function deleteMedia(db, bucket, id) {
95
+ const row = await fetchMediaAssetRow(db, id);
96
+ await bucket.delete(row.r2_key);
97
+ await db.prepare('DELETE FROM media_assets WHERE id = ?1').bind(id).run();
98
+ }
99
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/modules/media/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The we8 public API, described as OpenAPI 3.1.
3
+ *
4
+ * This is the durable, language-agnostic contract: a frontend in any stack
5
+ * calls these endpoints over HTTPS with the site's publishable key. The JS SDK
6
+ * (@we8/client, @we8/astro) is an optional convenience over exactly these
7
+ * routes, never a requirement. Served live at GET /v1/openapi.json so a
8
+ * deployment's API is self-describing, and kept in sync BY HAND with the public
9
+ * routes (the golden-file contract tests pin the actual JSON shapes; this
10
+ * document is the human and tooling facing description of the same surface).
11
+ *
12
+ * It is deliberately the SAME dialect a managed we8 tenant speaks, extended
13
+ * only by what 0.1 adds for AEO, so a site can move between the two without
14
+ * rewriting its frontend.
15
+ *
16
+ * Scope: the PUBLIC, frontend-facing surface only. The admin API (/v1/admin/*,
17
+ * reached with a signed-in session) is not documented here; this spec is what
18
+ * a site owner hands to whoever builds their site.
19
+ */
20
+ export declare function buildOpenApiSpec(siteUrl: string): Record<string, unknown>;
21
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../src/modules/openapi/spec.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqczE"}