mirror of
https://github.com/jackwener/OpenCLI.git
synced 2026-09-14 18:25:42 +08:00
d2974a9ff6
* refactor(adapters): convert adapter layer from TypeScript to JavaScript Core framework stays TypeScript; adapter layer moves to JS-first. Adapters are essentially "executable config + browser scripts" that barely use TS features — this simplifies the build/distribution pipeline by removing the dist/clis/ intermediate compilation step. Changes: - Convert all 753 adapter files in clis/ from .ts to .js - Update tsconfig to exclude clis/ from compilation - Simplify build-manifest to scan clis/*.js directly (no dist/clis/) - Update discovery, main, fetch-adapters to load JS adapters from clis/ - Update generate-verified to output .js artifacts - Update package.json files field: dist/clis/ → clis/ - Fix all test files for the .ts → .js transition * fix(main): use findPackageRoot for BUILTIN_CLIS path The previous relative path (../../clis from __dirname) only worked for dist/src/main.js but broke dev mode (tsx src/main.ts) where __dirname is <repo>/src — resolving to /clis instead of <repo>/clis. Use findPackageRoot() which works for both dev and prod paths.
54 lines
1.8 KiB
JavaScript
54 lines
1.8 KiB
JavaScript
/**
|
|
* ImageX cover image uploader.
|
|
*
|
|
* Uploads a JPEG/PNG image to ByteDance ImageX via a pre-signed PUT URL
|
|
* obtained from the Douyin "apply cover upload" API.
|
|
*/
|
|
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import { CommandExecutionError } from '@jackwener/opencli/errors';
|
|
/**
|
|
* Detect MIME type from file extension.
|
|
* Falls back to image/jpeg for unknown extensions.
|
|
*/
|
|
function detectContentType(filePath) {
|
|
const ext = path.extname(filePath).toLowerCase();
|
|
switch (ext) {
|
|
case '.png':
|
|
return 'image/png';
|
|
case '.gif':
|
|
return 'image/gif';
|
|
case '.webp':
|
|
return 'image/webp';
|
|
default:
|
|
return 'image/jpeg';
|
|
}
|
|
}
|
|
/**
|
|
* Upload a cover image to ByteDance ImageX via a pre-signed PUT URL.
|
|
*
|
|
* @param imagePath - Local file path to the image (JPEG/PNG/etc.)
|
|
* @param uploadInfo - Upload URL and store_uri from the apply cover upload API
|
|
* @returns The store_uri (= image_uri for use in create_v2)
|
|
*/
|
|
export async function imagexUpload(imagePath, uploadInfo) {
|
|
if (!fs.existsSync(imagePath)) {
|
|
throw new CommandExecutionError(`Cover image file not found: ${imagePath}`, 'Ensure the file path is correct and accessible.');
|
|
}
|
|
const imageBuffer = fs.readFileSync(imagePath);
|
|
const contentType = detectContentType(imagePath);
|
|
const res = await fetch(uploadInfo.upload_url, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': contentType,
|
|
'Content-Length': String(imageBuffer.byteLength),
|
|
},
|
|
body: imageBuffer,
|
|
});
|
|
if (!res.ok) {
|
|
const body = await res.text().catch(() => '');
|
|
throw new CommandExecutionError(`ImageX upload failed with status ${res.status}: ${body}`, 'Check that the upload URL is valid and has not expired.');
|
|
}
|
|
return uploadInfo.store_uri;
|
|
}
|