Initial WallMuse project
This commit is contained in:
11
packages/image-pipeline/package.json
Normal file
11
packages/image-pipeline/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "@wallmuse/image-pipeline",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": { ".": { "types": "./src/index.ts", "default": "./src/index.ts" } },
|
||||
"scripts": { "typecheck": "tsc --noEmit -p tsconfig.json", "build": "tsc -p tsconfig.json" },
|
||||
"dependencies": { "@wallmuse/shared": "workspace:*" }
|
||||
}
|
||||
7
packages/image-pipeline/src/index.ts
Normal file
7
packages/image-pipeline/src/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { mkdir, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import type { AssetKind } from "@wallmuse/shared";
|
||||
export interface StoredProviderImage { bucket: string; objectKey: string; storageUrl: string; publicUrl: string; sha256: string; byteSize: number; mimeType: string; width?: number; height?: number; }
|
||||
export interface StoreProviderAssetInput { userId: string; groupId: string; assetKind: Extract<AssetKind, "master" | "landscape" | "portrait">; source: { kind: "url" | "base64"; value: string; mimeType?: string; width?: number; height?: number } }
|
||||
export class LocalProviderAssetStore { constructor(private readonly rootDir = process.env.WALLMUSE_STORAGE_DIR ?? ".wallmuse-data/storage") {} async storeProviderAsset(input: StoreProviderAssetInput): Promise<StoredProviderImage> { const bytes = await this.readSource(input.source); const mimeType = input.source.mimeType ?? "image/png"; const extension = mimeType.includes("jpeg") ? "jpg" : mimeType.includes("webp") ? "webp" : "png"; const objectKey = `users/${input.userId}/groups/${input.groupId}/${input.assetKind}/original.${extension}`; const targetPath = path.join(this.rootDir, "wallpaper-originals", objectKey); await mkdir(path.dirname(targetPath), { recursive: true }); await writeFile(targetPath, bytes); const stored: StoredProviderImage = { bucket: "wallpaper-originals", objectKey, storageUrl: `local://${path.resolve(targetPath)}`, publicUrl: `/storage/wallpaper-originals/${objectKey}`, sha256: createHash("sha256").update(bytes).digest("hex"), byteSize: bytes.byteLength, mimeType }; if (input.source.width !== undefined) stored.width = input.source.width; if (input.source.height !== undefined) stored.height = input.source.height; return stored; } private async readSource(source: StoreProviderAssetInput["source"]): Promise<Buffer> { if (source.kind === "base64") return Buffer.from(source.value, "base64"); if (source.value.startsWith("mock://")) return Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=", "base64"); const response = await fetch(source.value); if (!response.ok) throw new Error(`Failed to download provider URL: ${response.status} ${response.statusText}`); return Buffer.from(await response.arrayBuffer()); } }
|
||||
1
packages/image-pipeline/tsconfig.json
Normal file
1
packages/image-pipeline/tsconfig.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "dist", "declaration": true, "types": ["node"] }, "include": ["src/**/*.ts"] }
|
||||
Reference in New Issue
Block a user