@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.
- package/README.md +78 -0
- package/dist/auth/auth.d.ts +87 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +90 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/routes.admin.d.ts +22 -0
- package/dist/auth/routes.admin.d.ts.map +1 -0
- package/dist/auth/routes.admin.js +106 -0
- package/dist/auth/routes.admin.js.map +1 -0
- package/dist/auth/schema.d.ts +1395 -0
- package/dist/auth/schema.d.ts.map +1 -0
- package/dist/auth/schema.js +76 -0
- package/dist/auth/schema.js.map +1 -0
- package/dist/env.d.ts +64 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +48 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/middleware.d.ts +54 -0
- package/dist/keys/middleware.d.ts.map +1 -0
- package/dist/keys/middleware.js +84 -0
- package/dist/keys/middleware.js.map +1 -0
- package/dist/keys/routes.admin.d.ts +16 -0
- package/dist/keys/routes.admin.d.ts.map +1 -0
- package/dist/keys/routes.admin.js +34 -0
- package/dist/keys/routes.admin.js.map +1 -0
- package/dist/keys/service.d.ts +36 -0
- package/dist/keys/service.d.ts.map +1 -0
- package/dist/keys/service.js +120 -0
- package/dist/keys/service.js.map +1 -0
- package/dist/lib/bots.d.ts +24 -0
- package/dist/lib/bots.d.ts.map +1 -0
- package/dist/lib/bots.js +79 -0
- package/dist/lib/bots.js.map +1 -0
- package/dist/lib/email.d.ts +62 -0
- package/dist/lib/email.d.ts.map +1 -0
- package/dist/lib/email.js +64 -0
- package/dist/lib/email.js.map +1 -0
- package/dist/lib/errors.d.ts +12 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +23 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/notify.d.ts +20 -0
- package/dist/lib/notify.d.ts.map +1 -0
- package/dist/lib/notify.js +60 -0
- package/dist/lib/notify.js.map +1 -0
- package/dist/lib/retention.d.ts +15 -0
- package/dist/lib/retention.d.ts.map +1 -0
- package/dist/lib/retention.js +40 -0
- package/dist/lib/retention.js.map +1 -0
- package/dist/lib/sanitize.d.ts +14 -0
- package/dist/lib/sanitize.d.ts.map +1 -0
- package/dist/lib/sanitize.js +145 -0
- package/dist/lib/sanitize.js.map +1 -0
- package/dist/lib/turnstile.d.ts +7 -0
- package/dist/lib/turnstile.d.ts.map +1 -0
- package/dist/lib/turnstile.js +32 -0
- package/dist/lib/turnstile.js.map +1 -0
- package/dist/lib/validate.d.ts +11 -0
- package/dist/lib/validate.d.ts.map +1 -0
- package/dist/lib/validate.js +22 -0
- package/dist/lib/validate.js.map +1 -0
- package/dist/lib/word-count.d.ts +7 -0
- package/dist/lib/word-count.d.ts.map +1 -0
- package/dist/lib/word-count.js +14 -0
- package/dist/lib/word-count.js.map +1 -0
- package/dist/middleware/auth.d.ts +46 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +60 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts +33 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +55 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/module-gate.d.ts +11 -0
- package/dist/middleware/module-gate.d.ts.map +1 -0
- package/dist/middleware/module-gate.js +18 -0
- package/dist/middleware/module-gate.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +13 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +30 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-id.d.ts +8 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +11 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/modules/aeo/checks.d.ts +41 -0
- package/dist/modules/aeo/checks.d.ts.map +1 -0
- package/dist/modules/aeo/checks.js +127 -0
- package/dist/modules/aeo/checks.js.map +1 -0
- package/dist/modules/aeo/llms.d.ts +24 -0
- package/dist/modules/aeo/llms.d.ts.map +1 -0
- package/dist/modules/aeo/llms.js +92 -0
- package/dist/modules/aeo/llms.js.map +1 -0
- package/dist/modules/aeo/routes.admin.d.ts +12 -0
- package/dist/modules/aeo/routes.admin.d.ts.map +1 -0
- package/dist/modules/aeo/routes.admin.js +37 -0
- package/dist/modules/aeo/routes.admin.js.map +1 -0
- package/dist/modules/analytics/db.d.ts +24 -0
- package/dist/modules/analytics/db.d.ts.map +1 -0
- package/dist/modules/analytics/db.js +24 -0
- package/dist/modules/analytics/db.js.map +1 -0
- package/dist/modules/analytics/routes.admin.d.ts +6 -0
- package/dist/modules/analytics/routes.admin.d.ts.map +1 -0
- package/dist/modules/analytics/routes.admin.js +21 -0
- package/dist/modules/analytics/routes.admin.js.map +1 -0
- package/dist/modules/analytics/routes.public.d.ts +6 -0
- package/dist/modules/analytics/routes.public.d.ts.map +1 -0
- package/dist/modules/analytics/routes.public.js +33 -0
- package/dist/modules/analytics/routes.public.js.map +1 -0
- package/dist/modules/analytics/service.d.ts +16 -0
- package/dist/modules/analytics/service.d.ts.map +1 -0
- package/dist/modules/analytics/service.js +148 -0
- package/dist/modules/analytics/service.js.map +1 -0
- package/dist/modules/authors/routes.admin.d.ts +6 -0
- package/dist/modules/authors/routes.admin.d.ts.map +1 -0
- package/dist/modules/authors/routes.admin.js +29 -0
- package/dist/modules/authors/routes.admin.js.map +1 -0
- package/dist/modules/authors/routes.public.d.ts +6 -0
- package/dist/modules/authors/routes.public.d.ts.map +1 -0
- package/dist/modules/authors/routes.public.js +11 -0
- package/dist/modules/authors/routes.public.js.map +1 -0
- package/dist/modules/authors/service.d.ts +26 -0
- package/dist/modules/authors/service.d.ts.map +1 -0
- package/dist/modules/authors/service.js +116 -0
- package/dist/modules/authors/service.js.map +1 -0
- package/dist/modules/content/db.d.ts +127 -0
- package/dist/modules/content/db.d.ts.map +1 -0
- package/dist/modules/content/db.js +203 -0
- package/dist/modules/content/db.js.map +1 -0
- package/dist/modules/content/publish.d.ts +38 -0
- package/dist/modules/content/publish.d.ts.map +1 -0
- package/dist/modules/content/publish.js +184 -0
- package/dist/modules/content/publish.js.map +1 -0
- package/dist/modules/content/routes.admin.d.ts +8 -0
- package/dist/modules/content/routes.admin.d.ts.map +1 -0
- package/dist/modules/content/routes.admin.js +122 -0
- package/dist/modules/content/routes.admin.js.map +1 -0
- package/dist/modules/content/routes.public.d.ts +6 -0
- package/dist/modules/content/routes.public.d.ts.map +1 -0
- package/dist/modules/content/routes.public.js +56 -0
- package/dist/modules/content/routes.public.js.map +1 -0
- package/dist/modules/content/service.d.ts +137 -0
- package/dist/modules/content/service.d.ts.map +1 -0
- package/dist/modules/content/service.js +348 -0
- package/dist/modules/content/service.js.map +1 -0
- package/dist/modules/forms/db.d.ts +42 -0
- package/dist/modules/forms/db.d.ts.map +1 -0
- package/dist/modules/forms/db.js +62 -0
- package/dist/modules/forms/db.js.map +1 -0
- package/dist/modules/forms/forms-routes.admin.d.ts +6 -0
- package/dist/modules/forms/forms-routes.admin.d.ts.map +1 -0
- package/dist/modules/forms/forms-routes.admin.js +37 -0
- package/dist/modules/forms/forms-routes.admin.js.map +1 -0
- package/dist/modules/forms/forms-service.d.ts +18 -0
- package/dist/modules/forms/forms-service.d.ts.map +1 -0
- package/dist/modules/forms/forms-service.js +121 -0
- package/dist/modules/forms/forms-service.js.map +1 -0
- package/dist/modules/forms/routes.public.d.ts +6 -0
- package/dist/modules/forms/routes.public.d.ts.map +1 -0
- package/dist/modules/forms/routes.public.js +41 -0
- package/dist/modules/forms/routes.public.js.map +1 -0
- package/dist/modules/forms/submissions-routes.admin.d.ts +6 -0
- package/dist/modules/forms/submissions-routes.admin.d.ts.map +1 -0
- package/dist/modules/forms/submissions-routes.admin.js +46 -0
- package/dist/modules/forms/submissions-routes.admin.js.map +1 -0
- package/dist/modules/forms/submissions-service.d.ts +45 -0
- package/dist/modules/forms/submissions-service.d.ts.map +1 -0
- package/dist/modules/forms/submissions-service.js +174 -0
- package/dist/modules/forms/submissions-service.js.map +1 -0
- package/dist/modules/media/db.d.ts +15 -0
- package/dist/modules/media/db.d.ts.map +1 -0
- package/dist/modules/media/db.js +24 -0
- package/dist/modules/media/db.js.map +1 -0
- package/dist/modules/media/routes.admin.d.ts +6 -0
- package/dist/modules/media/routes.admin.d.ts.map +1 -0
- package/dist/modules/media/routes.admin.js +30 -0
- package/dist/modules/media/routes.admin.js.map +1 -0
- package/dist/modules/media/routes.public.d.ts +6 -0
- package/dist/modules/media/routes.public.d.ts.map +1 -0
- package/dist/modules/media/routes.public.js +35 -0
- package/dist/modules/media/routes.public.js.map +1 -0
- package/dist/modules/media/service.d.ts +32 -0
- package/dist/modules/media/service.d.ts.map +1 -0
- package/dist/modules/media/service.js +99 -0
- package/dist/modules/media/service.js.map +1 -0
- package/dist/modules/openapi/spec.d.ts +21 -0
- package/dist/modules/openapi/spec.d.ts.map +1 -0
- package/dist/modules/openapi/spec.js +468 -0
- package/dist/modules/openapi/spec.js.map +1 -0
- package/dist/modules/seo/jsonld.d.ts +25 -0
- package/dist/modules/seo/jsonld.d.ts.map +1 -0
- package/dist/modules/seo/jsonld.js +67 -0
- package/dist/modules/seo/jsonld.js.map +1 -0
- package/dist/modules/seo/routes.public.d.ts +6 -0
- package/dist/modules/seo/routes.public.d.ts.map +1 -0
- package/dist/modules/seo/routes.public.js +39 -0
- package/dist/modules/seo/routes.public.js.map +1 -0
- package/dist/modules/seo/sitemap.d.ts +3 -0
- package/dist/modules/seo/sitemap.d.ts.map +1 -0
- package/dist/modules/seo/sitemap.js +39 -0
- package/dist/modules/seo/sitemap.js.map +1 -0
- package/dist/modules/settings/routes.admin.d.ts +12 -0
- package/dist/modules/settings/routes.admin.d.ts.map +1 -0
- package/dist/modules/settings/routes.admin.js +27 -0
- package/dist/modules/settings/routes.admin.js.map +1 -0
- package/dist/modules/site-documents/routes.admin.d.ts +10 -0
- package/dist/modules/site-documents/routes.admin.d.ts.map +1 -0
- package/dist/modules/site-documents/routes.admin.js +29 -0
- package/dist/modules/site-documents/routes.admin.js.map +1 -0
- package/dist/modules/site-documents/routes.public.d.ts +6 -0
- package/dist/modules/site-documents/routes.public.d.ts.map +1 -0
- package/dist/modules/site-documents/routes.public.js +16 -0
- package/dist/modules/site-documents/routes.public.js.map +1 -0
- package/dist/modules/site-documents/service.d.ts +11 -0
- package/dist/modules/site-documents/service.d.ts.map +1 -0
- package/dist/modules/site-documents/service.js +42 -0
- package/dist/modules/site-documents/service.js.map +1 -0
- package/dist/modules/webhooks/dispatch.d.ts +14 -0
- package/dist/modules/webhooks/dispatch.d.ts.map +1 -0
- package/dist/modules/webhooks/dispatch.js +84 -0
- package/dist/modules/webhooks/dispatch.js.map +1 -0
- package/dist/shared/constants.d.ts +79 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +89 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/envelope.d.ts +37 -0
- package/dist/shared/envelope.d.ts.map +1 -0
- package/dist/shared/envelope.js +46 -0
- package/dist/shared/envelope.js.map +1 -0
- package/dist/shared/hash.d.ts +2 -0
- package/dist/shared/hash.d.ts.map +1 -0
- package/dist/shared/hash.js +8 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/index.d.ts +13 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +13 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/schemas/aeo.d.ts +182 -0
- package/dist/shared/schemas/aeo.d.ts.map +1 -0
- package/dist/shared/schemas/aeo.js +43 -0
- package/dist/shared/schemas/aeo.js.map +1 -0
- package/dist/shared/schemas/analytics.d.ts +277 -0
- package/dist/shared/schemas/analytics.d.ts.map +1 -0
- package/dist/shared/schemas/analytics.js +74 -0
- package/dist/shared/schemas/analytics.js.map +1 -0
- package/dist/shared/schemas/api-key.d.ts +77 -0
- package/dist/shared/schemas/api-key.d.ts.map +1 -0
- package/dist/shared/schemas/api-key.js +27 -0
- package/dist/shared/schemas/api-key.js.map +1 -0
- package/dist/shared/schemas/author.d.ts +147 -0
- package/dist/shared/schemas/author.d.ts.map +1 -0
- package/dist/shared/schemas/author.js +27 -0
- package/dist/shared/schemas/author.js.map +1 -0
- package/dist/shared/schemas/form.d.ts +341 -0
- package/dist/shared/schemas/form.d.ts.map +1 -0
- package/dist/shared/schemas/form.js +117 -0
- package/dist/shared/schemas/form.js.map +1 -0
- package/dist/shared/schemas/index.d.ts +12 -0
- package/dist/shared/schemas/index.d.ts.map +1 -0
- package/dist/shared/schemas/index.js +12 -0
- package/dist/shared/schemas/index.js.map +1 -0
- package/dist/shared/schemas/media.d.ts +42 -0
- package/dist/shared/schemas/media.d.ts.map +1 -0
- package/dist/shared/schemas/media.js +16 -0
- package/dist/shared/schemas/media.js.map +1 -0
- package/dist/shared/schemas/pagination.d.ts +34 -0
- package/dist/shared/schemas/pagination.d.ts.map +1 -0
- package/dist/shared/schemas/pagination.js +21 -0
- package/dist/shared/schemas/pagination.js.map +1 -0
- package/dist/shared/schemas/post.d.ts +862 -0
- package/dist/shared/schemas/post.d.ts.map +1 -0
- package/dist/shared/schemas/post.js +187 -0
- package/dist/shared/schemas/post.js.map +1 -0
- package/dist/shared/schemas/settings.d.ts +839 -0
- package/dist/shared/schemas/settings.d.ts.map +1 -0
- package/dist/shared/schemas/settings.js +202 -0
- package/dist/shared/schemas/settings.js.map +1 -0
- package/dist/shared/schemas/site-document.d.ts +38 -0
- package/dist/shared/schemas/site-document.d.ts.map +1 -0
- package/dist/shared/schemas/site-document.js +21 -0
- package/dist/shared/schemas/site-document.js.map +1 -0
- package/dist/shared/schemas/webhook.d.ts +39 -0
- package/dist/shared/schemas/webhook.d.ts.map +1 -0
- package/dist/shared/schemas/webhook.js +20 -0
- package/dist/shared/schemas/webhook.js.map +1 -0
- package/dist/spa.d.ts +9 -0
- package/dist/spa.d.ts.map +1 -0
- package/dist/spa.js +57 -0
- package/dist/spa.js.map +1 -0
- package/migrations/0001_settings.sql +39 -0
- package/migrations/0002_content.sql +135 -0
- package/migrations/0003_forms.sql +35 -0
- package/migrations/0004_analytics.sql +42 -0
- package/migrations/0005_media.sql +17 -0
- package/migrations/0006_site_documents.sql +18 -0
- package/migrations/0007_auth.sql +81 -0
- package/migrations/0008_api_keys.sql +20 -0
- package/package.json +68 -0
- package/scripts/bundle-admin.mjs +54 -0
- 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":"AAAA,OAAO,EACL,2BAA2B,GAK5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GAEnB,MAAM,SAAS,CAAC;AAEjB,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAmBhC;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAc,EACd,OAAe,EACf,OAAgC,EAChC,eAAmC,EACnC,OAA0B;IAE1B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAElD,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACtD,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzE,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;YACV,UAAU,EAAE,IAAI;YAChB,oBAAoB,EAAE,QAAQ,CAAC,YAAY;SAC5C,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;IAEjE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,WAAW,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;QAC3C,MAAM,IAAI,SAAS,CAAC,mBAAmB,EAAE,8BAA8B,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,eAAe,CACpC,eAAe,EACf,KAAK,CAAC,cAAc,EACpB,OAAO,CAAC,MAAM,IAAI,SAAS,CAC5B,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,+BAA+B,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,YAAY,CAAC;IACrF,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtF,MAAM,SAAS,GAAG,MAAM,EAAE;SACvB,OAAO,CACN,qCAAqC,eAAe,yCAAyC,cAAc,CAAC,MAAM,GAAG,CAAC,GAAG,CAC1H;SACA,IAAI,CAAC,GAAG,cAAc,EAAE,IAAI,qBAAqB,UAAU,CAAC;SAC5D,KAAK,EAAE,CAAC;IACX,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,IAAI,SAAS,CACjB,cAAc,EACd,kEAAkE,CACnE,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAC/B,MAAM,EAAE;SACL,OAAO,CACN;;mDAE6C,CAC9C;SACA,IAAI,CACH,EAAE,EACF,IAAI,CAAC,EAAE,EACP,WAAW,EACX,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,IAAI,IAAI,EAClB,KAAK,CAAC,UAAU,IAAI,IAAI,EACxB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,SAAS,CAClB;SACA,GAAG,EAAE,CAAC;IAET,OAAO;QACL,EAAE;QACF,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;QACpC,oBAAoB,EAAE,QAAQ,CAAC,YAAY;KAC5C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAc,EAAE,EAAU;IACjE,OAAO,kBAAkB,CAAC,MAAM,kBAAkB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,qFAAqF;AACrF,SAAS,iBAAiB,CAAC,OAI1B;IACC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QAChE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,0BAA0B,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QACjE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CACb,4BAA4B,QAAQ,CAAC,MAAM,GAAG,CAAC,8BAA8B,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,CACpG,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAc,EACd,KAA0B;IAE1B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;IACjD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAErD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE;SACzB,OAAO,CACN;;WAEK,KAAK;yDACyC,QAAQ,CAAC,MAAM,GAAG,CAAC,YAAY,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CACxG;SACA,IAAI,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;SACzC,GAAG,EAAyB,CAAC;IAEhC,MAAM,QAAQ,GAAG,MAAM,EAAE;SACtB,OAAO,CAAC,6CAA6C,KAAK,EAAE,CAAC;SAC7D,IAAI,CAAC,GAAG,QAAQ,CAAC;SACjB,KAAK,EAAqB,CAAC;IAE9B,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AACjF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAc,EACd,EAAU,EACV,KAA4B;IAE5B,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,EAAE;SACL,OAAO,CAAC,wDAAwD,CAAC;SACjE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;SACzF,GAAG,EAAE,CAAC;IACT,OAAO,kBAAkB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAc,EAAE,IAAY;IACpE,MAAM,KAAK,GAAG,IAAI,IAAI,OAAO,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,EAAE;SACpB,OAAO,CAAC,oFAAoF,CAAC;SAC7F,IAAI,CAAC,KAAK,CAAC;SACX,KAAK,EAAqB,CAAC;IAE9B,MAAM,MAAM,GAAG,CACb,MAAM,EAAE;SACL,OAAO,CACN;;;4DAGoD,CACrD;SACA,IAAI,CAAC,KAAK,CAAC;SACX,GAAG,EAA8D,CACrE,CAAC,OAAO,CAAC;IAEV,MAAM,KAAK,GAAG,CACZ,MAAM,EAAE;SACL,OAAO,CACN;;yDAEiD,CAClD;SACA,IAAI,CAAC,KAAK,CAAC;SACX,GAAG,EAAmC,CAC1C,CAAC,OAAO,CAAC;IAEV,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAc,EACd,OAIC;IAED,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEvD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE;SACzB,OAAO,CACN;;WAEK,KAAK,yCAAyC,CACpD;SACA,IAAI,CAAC,GAAG,QAAQ,CAAC;SACjB,GAAG,EAAyB,CAAC;IAEhC,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/F,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CACR;YACE,GAAG,CAAC,EAAE;YACN,GAAG,CAAC,YAAY;YAChB,GAAG,CAAC,SAAS,IAAI,EAAE;YACnB,GAAG,CAAC,KAAK,IAAI,EAAE;YACf,GAAG,CAAC,IAAI,IAAI,EAAE;YACd,GAAG,CAAC,MAAM;YACV,GAAG,CAAC,WAAW,IAAI,EAAE;YACrB,GAAG,CAAC,KAAK,IAAI,EAAE;SAChB;aACE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;aACxC,IAAI,CAAC,GAAG,CAAC,CACb,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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"}
|