UNPKG

@curvenote/cli

Version:
116 lines (115 loc) 4.35 kB
import { stageUploads, stageWithRequest } from './stage.js'; import { commitUploads } from './commit.js'; import { makeFileInfo, performFileUploads } from './utils.js'; export * from './types.js'; export * from './utils.js'; /** * Upload a list of named files to chosen storage paths under an existing cdnKey. * No folder scanning: each entry is an explicit localPath/storagePath pair. * Stages all files, uploads to signed URLs as needed, then commits with the given cdnKey * so each file lands at {cdnKey}/{storagePath}. */ export async function uploadNamedFilesToCdn(session, opts) { if (opts.files.length === 0) { return { paths: [], cdnKey: opts.cdnKey }; } const fileInfos = opts.files.map((f) => makeFileInfo(f.localPath, f.storagePath)); const uploadRequest = { files: fileInfos.map((info) => ({ path: info.to, content_type: info.contentType, md5: info.md5, size: info.size, })), }; const staged = await stageWithRequest(session, uploadRequest); // Pass `upload` (protocol + URL) so performFileUploads can use GCS resumable vs single PUT (Azure/S3). const filesToUpload = staged.upload_items .map((upload) => { const fileInfo = fileInfos.find((f) => f.md5 === upload.md5); if (!fileInfo) return null; return { from: fileInfo.from, to: upload.path, md5: fileInfo.md5, size: fileInfo.size, contentType: fileInfo.contentType, signedUrl: upload.signed_url, ...(upload.upload ? { upload: upload.upload } : {}), }; }) .filter((f) => f !== null); if (filesToUpload.length > 0) { await performFileUploads(session, filesToUpload, { resume: opts.resume }); } // Commit only stable file metadata; signed_url and upload are upload-time secrets/protocol hints, not part of UploadFileInfo. const files = [ ...staged.cached_items, ...staged.upload_items.map((f) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { signed_url, upload: _upload, ...rest } = f; return rest; }), ]; await commitUploads(session, { cdn: opts.cdn, cdnKey: opts.cdnKey, files, }); const paths = opts.files.map((f) => `${opts.cdnKey}/${f.storagePath}`); return { paths, cdnKey: opts.cdnKey }; } /** * Upload a single file to a chosen storage path under an existing cdnKey. * Convenience wrapper around uploadNamedFilesToCdn with one file. */ export async function uploadSingleFileToCdn(session, opts) { const { paths, cdnKey } = await uploadNamedFilesToCdn(session, { cdn: opts.cdn, cdnKey: opts.cdnKey, files: [{ localPath: opts.localPath, storagePath: opts.storagePath }], resume: opts.resume, }); return { path: paths[0], cdnKey }; } export async function uploadToTmpCdn(session, opts) { return uploadToCdn(session, session.config.tempCdnUrl, opts); } export async function uploadToCdn(session, cdn, opts) { const { cdnKey, cached_items, upload_items, files } = await stageUploads(session); const filesToUpload = files .map((file) => { const upload = upload_items.find((f) => f.md5 === file.md5); if (!upload) { session.log.error(`🚨 Could not find upload url for ${file.md5} ${file.from}, upload will be skipped`); return null; } return { from: file.from, to: upload.path, md5: file.md5, size: file.size, contentType: file.contentType, signedUrl: upload.signed_url, ...(upload.upload ? { upload: upload.upload } : {}), }; }) .filter((f) => f !== null); if (filesToUpload.length > 0) { await performFileUploads(session, filesToUpload, opts); } await commitUploads(session, { cdn, cdnKey, files: [ ...cached_items, ...upload_items.map((f) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { signed_url, upload: _upload, ...rest } = f; return rest; }), ], }); return { cdnKey }; }