npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@data-loom/storage-js

v0.4.13

Published

Dataloom service, modified from supabase/storage-js

Readme

@data-loom/storage-js

Dataloom 存储服务 JavaScript SDK,基于 Supabase Storage 修改而来,提供了强大的文件存储和管理功能。

功能特性

  • 📁 文件上传和下载 - 支持多种文件格式的上传和下载
  • 🔗 签名URL - 创建具有时效性的安全文件访问链接
  • 🗑️ 文件管理 - 删除、列表等文件操作
  • 🌐 URL上传 - 从公共URL下载文件并上传到存储桶
  • 📊 批量操作 - 支持批量创建签名URL等批量操作
  • 🔍 文件搜索 - 支持文件搜索和分页
  • 🛡️ 错误处理 - 完善的错误处理机制

安装

npm install @data-loom/storage-js

快速开始

默认推荐使用挂载在 @data-loom/js 中的 storage 接口。

import { createClient } from '@data-loom/js';
const dataloom = createClient(url, key, workspace, {
  global: {
      brandName: 'your_brand_name',
      appId: 'your_app_id',
      enableDataloomLog: true,
      requestRateLimit: 10,
      onError: (error) => {
      }
  },
});
const { data, error } = await dataloom.storage.from('bucket_id').download('file_path');

或者可以独立使用 storage-js 包。

import { StorageClient } from '@data-loom/storage-js'

// 独立初始化存储客户端
const storage = new StorageClient(
  storageUrl,
  customHeaders,
  customFetch,
  {
    enableLogger: true,
    appId: 'your-app-id',
    onRequestError: (error) => console.error('请求错误:', error),
  },
);

// 上传文件
const { data, error } = await storage.upload('folder/image.png', file);
if (error) {
  console.error('上传失败:', error);
} else {
  console.log('上传成功:', data);
}

API 接口文档

构造函数

constructor(
  url: string,                    // 存储服务URL
  headers: { [key: string]: string } = {},  // 请求头
  bucketId?: string,            // 存储桶ID
  appId?: string,               // 应用ID
  fetch?: Fetch,                // 自定义fetch函数
  loggerEnabled?: boolean,      // 是否启用日志
  onRequestError?: (error: OnRequestErrorType) => void  // 请求错误回调
)

文件上传

upload(path, fileBody, fileOptions?) - 重载1

上传文件到指定的存储桶路径。

入参:

function upload(
  path: string,           // 文件路径,格式为 `folder/subfolder/filename.png`
  fileBody: FileBody,     // 文件内容
  fileOptions?: FileOptions  // 上传选项
): Promise<UploadResult>

出参:

type UploadResult =
  | { data: UploadFileData; error: null }
  | { data: null; error: StorageError }

示例:

const { data, error } = await storage.upload('avatars/user-123.jpg', file, {
  cacheControl: 3600,
  contentType: 'image/jpeg',
  upsert: false
});

upload(fileBody, fileOptions?) - 重载2

使用 FileOptionsV2 上传文件,路径通过 options.filePath 指定。

入参:

function upload(
  fileBody: FileBody,         // 文件内容
  fileOptions?: FileOptionsV2 // 上传选项(包含 filePath)
): Promise<UploadResult>

出参:

type UploadResult =
  | { data: UploadFileData; error: null }
  | { data: null; error: StorageError }

示例:

const { data, error } = await storage.upload(file, {
  filePath: 'documents/report.pdf',
  contentType: 'application/pdf',
  contentDisposition: 'attachment; filename="report.pdf"'
});

uploadFile(fileBody, fileOptions?)

使用文件选项上传文件(推荐,与 upload 重载2 功能相同)。

入参:

function uploadFile(
  fileBody: FileBody,         // 文件内容
  fileOptions?: FileOptionsV2 // 上传选项
): Promise<UploadResult>

出参:

type UploadResult =
  | { data: UploadFileData; error: null }
  | { data: null; error: StorageError }

示例:

const { data, error } = await storage.uploadFile(file, {
  filePath: 'documents/report.pdf',
  cacheControl: 3600,
  contentType: 'application/pdf',
  contentDisposition: 'attachment; filename="report.pdf"'
});

文件更新

update(path, fileBody, fileOptions?)

替换指定路径的现有文件。

入参:

function update(
  path: string,              // 文件路径
  fileBody: FileBody,        // 文件内容
  fileOptions?: FileOptions  // 上传选项
): Promise<UploadResult>

出参:

type UploadResult =
  | { data: UploadFileData; error: null }
  | { data: null; error: StorageError }

从URL上传文件

uploadFromUrl(url)

从公共URL上传文件到存储桶。自动透传响应头(content-type、content-disposition、cache-control)到上传请求。对于火山引擎北京区域的 TOS URL,会使用服务端复制优化性能。

入参:

function uploadFromUrl(
  url: string  // 公共文件URL(如 CDN 链接)
): Promise<UploadFromUrlResult>

出参:

type UploadFromUrlResult =
  | { data: UploadFileData; error: null }
  | { data: null; error: StorageError }

功能特性:

  • ✅ 只允许 http://https:// 协议
  • ✅ 自动透传响应头到上传请求(contentType、contentDisposition、cacheControl)
  • ✅ 检测并拒绝空文件
  • ✅ 火山引擎北京区域 TOS URL 使用服务端复制优化

示例:

// 基本用法
const { data, error } = await storage.uploadFromUrl(
  'https://cdn.example.com/images/photo.jpg'
);

if (data) {
  console.log('文件上传成功:', data.download_url);
}

错误处理:

const { data, error } = await storage.uploadFromUrl('https://example.com/file.pdf');

if (error) {
  // 可能的错误类型:
  // - 'Invalid URL provided' - URL格式无效
  // - 'Only http and https protocols are supported' - 协议不支持
  // - 'Failed to download file from URL: 404 Not Found' - 下载失败
  // - 'Downloaded file is empty' - 下载的文件为空
  console.error(error.message);
}

创建签名URL

createSignedUrl(path, expiresIn, options?)

创建具有时效性的安全文件访问链接。

入参:

function createSignedUrl(
  path: string,      // 文件路径或 download_url
  expiresIn: number, // 过期时间(秒)
  options?: {
    download?: string | boolean;    // 是否触发下载
    transform?: TransformOptions;   // 图片转换选项
  }
): Promise<SignedUrlResult>

出参:

type SignedUrlResult =
  | { data: { signedUrl: string }; error: null }
  | { data: null; error: StorageError }

示例:

// 创建1小时有效的签名URL
const { data, error } = await storage.createSignedUrl('documents/report.pdf', 3600);

// 创建带图片转换的签名URL
const { data, error } = await storage.createSignedUrl('images/photo.jpg', 3600, {
  transform: {
    width: 300,
    height: 200,
    resize: 'cover',
    quality: 80
  }
});

createSignedUrls(paths, expiresIn, options?)

批量创建签名URL。

入参:

function createSignedUrls(
  paths: string[],    // 文件路径或 download_url 数组
  expiresIn: number,  // 过期时间(秒)
  options?: {
    download?: string | boolean;
  }
): Promise<SignedUrlsResult>

出参:

type SignedUrlsResult =
  | {
      data: Array<{
        error: string | null;
        path: string | null;
        signedUrl: string;
      }>;
      error: null
    }
  | { data: null; error: StorageError }

示例:

const { data, error } = await storage.createSignedUrls(
  ['file1.pdf', 'file2.pdf', 'file3.pdf'],
  3600
);

文件下载

download(path, options?)

从私有存储桶下载文件。

入参:

function download(
  path: string,  // 文件路径
  options?: {
    transform?: TransformOptions;  // 图片转换选项
  }
): Promise<DownloadResult>

出参:

type DownloadResult =
  | { data: Blob; error: null }
  | { data: null; error: StorageError }

示例:

const { data, error } = await storage.download('documents/report.pdf');
if (data) {
  const url = URL.createObjectURL(data);
  window.open(url);
}

文件删除

remove(paths)

删除指定路径的文件。

入参:

function remove(
  paths: string[]  // 文件路径或 download_url 数组
): Promise<RemoveResult>

出参:

type RemoveResult =
  | { data: FileObject[]; error: null }
  | { data: null; error: StorageError }

示例:

const { data, error } = await storage.remove([
  'temp/file1.txt',
  'temp/file2.txt'
]);

文件列表

list(path?, options?, parameters?)

列出存储桶中的文件。

入参:

function list(
  path?: string,              // 文件夹路径
  options?: SearchOptions,    // 搜索选项
  parameters?: FetchParameters // 请求参数
): Promise<ListResult>

出参:

type ListResult =
  | { data: FileObject[]; error: null }
  | { data: null; error: StorageError }

示例:

// 列出根目录文件
const { data, error } = await storage.list();

// 搜索特定文件夹的文件
const { data, error } = await storage.list('documents', {
  limit: 50,
  offset: 0,
  sortBy: {
    column: 'name',
    order: 'asc'
  },
  search: 'report'
});

类型定义

FileBody

支持以下文件格式:

type FileBody =
  | ArrayBuffer
  | ArrayBufferView
  | Blob
  | Buffer
  | File
  | FormData
  | NodeJS.ReadableStream
  | ReadableStream<Uint8Array>
  | URLSearchParams
  | string;

FileOptions

interface FileOptions {
  /** 缓存控制时间(秒),设置 Cache-Control: max-age=<seconds> 头 */
  cacheControl?: string | number;
  /** Content-Type 头值 */
  contentType?: string;
  /** 是否覆盖已存在文件,默认 false */
  upsert?: boolean;
  /** 双工流选项 */
  duplex?: string;
  /** 文件元数据 */
  metadata?: Record<string, any>;
  /** 额外请求头 */
  headers?: Record<string, string>;
}

FileOptionsV2

interface FileOptionsV2 {
  /** 文件上传路径 */
  filePath?: string;
  /** 缓存控制时间(秒) */
  cacheControl?: string | number;
  /** Content-Type 头值 */
  contentType?: string;
  /** 是否覆盖已存在文件,默认 false */
  upsert?: boolean;
  /** Content-Disposition 响应头值 */
  contentDisposition?: string;
}

UploadFileData

interface UploadFileData {
  /** 文件ID */
  id: string;
  /** 文件路径 */
  file_path: string;
  /** 存储桶ID */
  bucket_id: string;
  /** 下载URL */
  download_url: string;
}

FileObject

interface FileObject {
  /** 文件名 */
  name: string;
  /** 存储桶ID */
  bucket_id: string;
  /** 所有者 */
  owner: string;
  /** 文件ID */
  id: string;
  /** 更新时间 */
  updated_at: string;
  /** 创建时间 */
  created_at: string;
  /** 创建者 */
  created_by: string;
  /** 更新者 */
  updated_by: string;
  /** 最后访问时间 */
  last_accessed_at?: string;
  /** 元数据 */
  metadata: Record<string, any>;
  /** 存储桶信息 */
  buckets: Bucket;
}

Bucket

interface Bucket {
  /** 存储桶ID */
  id: string;
  /** 存储桶类型 */
  type?: 'STANDARD' | 'ANALYTICS';
  /** 存储桶名称 */
  name: string;
  /** 所有者 */
  owner: string;
  /** 文件大小限制 */
  file_size_limit?: number;
  /** 允许的MIME类型 */
  allowed_mime_types?: string[];
  /** 创建时间 */
  created_at: string;
  /** 更新时间 */
  updated_at: string;
  /** 是否公开 */
  public: boolean;
}

SearchOptions

interface SearchOptions {
  /** 返回文件数量,默认 100 */
  limit?: number;
  /** 起始位置 */
  offset?: number;
  /** 排序选项 */
  sortBy?: SortBy;
  /** 搜索字符串 */
  search?: string;
}

SortBy

interface SortBy {
  /** 排序列名 */
  column?: string;
  /** 排序顺序:'asc' | 'desc' */
  order?: string;
}

TransformOptions

interface TransformOptions {
  /** 宽度(像素) */
  width?: number;
  /** 高度(像素) */
  height?: number;
  /** 调整大小模式 */
  resize?: 'cover' | 'contain' | 'fill';
  /** 质量(20-100) */
  quality?: number;
  /** 格式 */
  format?: 'origin';
}

FetchParameters

interface FetchParameters {
  /** AbortController 信号,用于取消请求 */
  signal?: AbortSignal;
}

StorageError

class StorageError extends Error {
  message: string;
}

OnRequestErrorType

interface OnRequestErrorType {
  code: number;
  details: string;
  hint: string | null;
  message: string;
  status: number;
  statusText: string;
}

错误处理

所有API方法都返回包含 dataerror 的对象。当操作成功时,errornulldata 包含返回数据;当操作失败时,datanullerror 包含错误信息。

const { data, error } = await storage.upload('test.jpg', file);

if (error) {
  console.error('操作失败:', error.message);
} else {
  console.log('操作成功:', data);
}

高级用法

日志记录

可以通过设置 loggerEnabled 参数启用请求日志记录:

const storage = new StorageFileApi(
  'https://your-storage-service.com',
  { 'Authorization': 'Bearer your-token' },
  'bucket-id',
  'app-id',
  undefined,
  true  // 启用日志
);

错误回调

可以设置请求错误回调函数:

const storage = new StorageFileApi(
  'https://your-storage-service.com',
  { 'Authorization': 'Bearer your-token' },
  'bucket-id',
  'app-id',
  undefined,
  false,
  (error) => {
    console.error('请求错误:', error);
  }
);

自定义 fetch

可以传入自定义的 fetch 函数:

const customFetch = (url, options) => {
  // 自定义 fetch 逻辑
  return fetch(url, options);
};

const storage = new StorageFileApi(
  'https://your-storage-service.com',
  { 'Authorization': 'Bearer your-token' },
  'bucket-id',
  'app-id',
  customFetch
);

许可证

MIT License