fix: basic
This commit is contained in:
parent
8623442157
commit
6803a23aa3
|
|
@ -13,7 +13,7 @@ import { validateAndNormalizePagination } from '@/utils/validators';
|
|||
import { buildPaginatedResponse } from '@/utils/helpers';
|
||||
import { toImageResponse } from '@/types/responses';
|
||||
import { db } from '@/db';
|
||||
import { flows } from '@banatie/database';
|
||||
import { flows, type Image } from '@banatie/database';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import type {
|
||||
UploadImageResponse,
|
||||
|
|
@ -704,13 +704,14 @@ imagesRouter.put(
|
|||
);
|
||||
|
||||
/**
|
||||
* Assign a project-scoped alias to an image
|
||||
* Assign or remove a project-scoped alias from an image
|
||||
*
|
||||
* Sets or updates the project-scoped alias for an image:
|
||||
* - Alias must start with @ symbol
|
||||
* Sets, updates, or removes the project-scoped alias for an image:
|
||||
* - Alias must start with @ symbol (when assigning)
|
||||
* - Must be unique within the project
|
||||
* - Replaces existing alias if image already has one
|
||||
* - Used for alias resolution in generations and CDN access
|
||||
* - Set alias to null to remove existing alias
|
||||
*
|
||||
* This is a dedicated endpoint introduced in Section 6.1 to separate
|
||||
* alias assignment from general metadata updates.
|
||||
|
|
@ -722,24 +723,30 @@ imagesRouter.put(
|
|||
* @param {string} req.params.id_or_alias - Image ID (UUID) or alias (@-prefixed)
|
||||
* @param {string} [req.query.flowId] - Flow ID for flow-scoped alias resolution
|
||||
* @param {object} req.body - Request body
|
||||
* @param {string} req.body.alias - Project-scoped alias (e.g., "@hero-bg")
|
||||
* @param {string|null} req.body.alias - Project-scoped alias (e.g., "@hero-bg") or null to remove
|
||||
*
|
||||
* @returns {UpdateImageResponse} 200 - Updated image with new alias
|
||||
* @returns {UpdateImageResponse} 200 - Updated image with new/removed alias
|
||||
* @returns {object} 404 - Image not found or access denied
|
||||
* @returns {object} 400 - Missing or invalid alias
|
||||
* @returns {object} 400 - Invalid alias format
|
||||
* @returns {object} 401 - Missing or invalid API key
|
||||
* @returns {object} 409 - Alias already exists
|
||||
*
|
||||
* @throws {Error} IMAGE_NOT_FOUND - Image does not exist
|
||||
* @throws {Error} VALIDATION_ERROR - Alias is required
|
||||
* @throws {Error} VALIDATION_ERROR - Invalid alias format
|
||||
* @throws {Error} ALIAS_CONFLICT - Alias already assigned to another image
|
||||
*
|
||||
* @example UUID identifier
|
||||
* @example Assign alias
|
||||
* PUT /api/v1/images/550e8400-e29b-41d4-a716-446655440000/alias
|
||||
* {
|
||||
* "alias": "@hero-background"
|
||||
* }
|
||||
*
|
||||
* @example Remove alias
|
||||
* PUT /api/v1/images/550e8400-e29b-41d4-a716-446655440000/alias
|
||||
* {
|
||||
* "alias": null
|
||||
* }
|
||||
*
|
||||
* @example Project-scoped alias identifier
|
||||
* PUT /api/v1/images/@old-hero/alias
|
||||
* {
|
||||
|
|
@ -762,11 +769,12 @@ imagesRouter.put(
|
|||
const { flowId } = req.query;
|
||||
const { alias } = req.body;
|
||||
|
||||
if (!alias || typeof alias !== 'string') {
|
||||
// Validate: alias must be null (to remove) or a non-empty string
|
||||
if (alias !== null && (typeof alias !== 'string' || alias.trim() === '')) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: {
|
||||
message: 'Alias is required and must be a string',
|
||||
message: 'Alias must be null (to remove) or a non-empty string',
|
||||
code: 'VALIDATION_ERROR',
|
||||
},
|
||||
});
|
||||
|
|
@ -815,7 +823,16 @@ imagesRouter.put(
|
|||
return;
|
||||
}
|
||||
|
||||
const updated = await service.assignProjectAlias(imageId, alias);
|
||||
// Either remove alias (null) or assign new one (override behavior per Section 5.2)
|
||||
let updated: Image;
|
||||
if (alias === null) {
|
||||
// Remove alias
|
||||
updated = await service.update(imageId, { alias: null });
|
||||
} else {
|
||||
// Reassign alias (clears from any existing image, then assigns to this one)
|
||||
await service.reassignProjectAlias(alias, imageId, image.projectId);
|
||||
updated = (await service.getById(imageId))!;
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ export class ImageService {
|
|||
async update(
|
||||
id: string,
|
||||
updates: {
|
||||
alias?: string;
|
||||
alias?: string | null;
|
||||
focalPoint?: { x: number; y: number };
|
||||
meta?: Record<string, unknown>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,11 +139,21 @@ export async function uploadFile(
|
|||
): Promise<any> {
|
||||
const formData = new FormData();
|
||||
|
||||
// Read file
|
||||
// Read file and detect MIME type from extension
|
||||
const fs = await import('fs/promises');
|
||||
const path = await import('path');
|
||||
const fileBuffer = await fs.readFile(filepath);
|
||||
const blob = new Blob([fileBuffer]);
|
||||
formData.append('file', blob, 'test-image.png');
|
||||
const ext = path.extname(filepath).toLowerCase();
|
||||
const mimeTypes: Record<string, string> = {
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.webp': 'image/webp',
|
||||
};
|
||||
const mimeType = mimeTypes[ext] || 'application/octet-stream';
|
||||
const filename = path.basename(filepath);
|
||||
const blob = new Blob([fileBuffer], { type: mimeType });
|
||||
formData.append('file', blob, filename);
|
||||
|
||||
// Add other fields
|
||||
for (const [key, value] of Object.entries(fields)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue