Zum Inhalt springen

Files & Renderer

Zwei Features für File-Uploads und Email-Templates.

files-provider-s3

Status: ✅ Stable

Wofür: S3-kompatibles File-Storage-Backend. Geht gegen AWS S3, Cloudflare R2, MinIO, Backblaze B2 — was auch immer S3-API spricht. Liefert Upload-URLs (presigned), Read-URLs (direct oder presigned), Delete-Operations.

Wie es funktioniert: createS3Provider({ region, bucket, accessKey, secretKey, endpoint?, forcePathStyle? }) baut einen Provider, den der Framework-File-Layer nutzt. forcePathStyle ist für MinIO + R2 wichtig (die unterstützen kein Virtual-Host-Style). Per-Tenant-Buckets sind über bucket: (tenantId) => \tenant-${tenantId}-files“ möglich — gibt natürliche Mandanten-Trennung auf S3-Ebene.

Env-Helper: createS3ProviderFromEnv() liest die Standard-S3- Env-Vars (AWS_ACCESS_KEY_ID etc.) — schnellster Setup für Single- Tenant-Apps, kein Code-Pfad ändern wenn du später migrierst.

Beispiel:

import { createS3Provider } from "@kumiko/bundled-features/files-provider-s3";
const fileProvider = createS3Provider({
region: "eu-central-1",
bucket: "kumiko-app-files",
accessKey: process.env["AWS_ACCESS_KEY_ID"]!,
secretKey: process.env["AWS_SECRET_ACCESS_KEY"]!,
});
// In einem Handler: presigned Upload-URL für den Browser
r.writeHandler({
qn: "files:upload-url",
handler: async (ctx, { filename }) => {
return fileProvider.uploadUrl({
key: `tenant-${ctx.tenantId}/${filename}`,
contentType: "application/octet-stream",
expiresIn: 600, // Sekunden
});
},
});

renderer-simple

Status: ✅ Stable

Wofür: Minimaler HTML-Renderer für Email-Templates. Kein React, keine SSR-Pipeline — nur ein Template-String mit {{ placeholders }} und eine Liste von Helpers (i18n, Date-Format, URL-Builder).

Wie es funktioniert: Ein Email-Template ist eine Funktion (data, helpers) => { html, text }. renderer-simple wird als Renderer-Implementation in delivery registriert und kümmert sich um Layout-Inheritance (Header + Footer wiederverwendbar) und Plain-Text-Fallback (text-Variant aus HTML stripping).

Wann nicht: Marketing-Mails mit komplexen Layouts → externes Tool wie MJML oder unlayer rendern und Output direkt durchschleifen. renderer-simple ist für Transactional-Mails (Reset-Link, Incident-Update, Welcome) — das, was die App selbst sendet, nicht das, was Marketing schickt.

Beispiel:

import { createRendererSimpleFeature } from "@kumiko/bundled-features/renderer-simple";
features: [createRendererSimpleFeature(), createDeliveryFeature(), /* ... */];
// Template definieren (in deinem Feature)
r.template({
id: "incident-created",
renderer: "simple",
render: ({ data }) => ({
subject: `[${data.tenant}] Incident: ${data.title}`,
html: `<h1>${data.title}</h1><p>${data.body}</p>`,
text: `${data.title}\n\n${data.body}`,
}),
});

Siehe auch