{"_id":"@ai-media/uploader","_rev":"6-dabea94ff4fb33dfef8e41d9a2a5ba12","name":"@ai-media/uploader","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@ai-media/uploader","version":"0.1.0","license":"MIT","_id":"@ai-media/uploader@0.1.0","maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"dist":{"shasum":"937ad5b2e58276c76de52f49207e2a6acbc0125e","tarball":"https://registry.npmjs.org/@ai-media/uploader/-/uploader-0.1.0.tgz","fileCount":13,"integrity":"sha512-oinfuYsOm6RY/g5JU5DR6aodfy9Vwo1Z0kW4ETR5+M4SY9wgyUIH8POmfWzK35+WV3fUoxgN8ABCdNY2E8z//w==","signatures":[{"sig":"MEQCIFPuyOMnjwWjHMV9z5YcppLHIo1GIIOYeU2TFQedT6rGAiBTeCk4yRqZfnCnwgYwDfcyb4T+NpPFUNwLvxVYMM8S5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24223},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./aliyun":{"types":"./dist/aliyun/index.d.ts","import":"./dist/aliyun/index.js"},"./google":{"types":"./dist/google/index.d.ts","import":"./dist/google/index.js"}},"gitHead":"554268b9348db1e0795cc2e407fe175b654e025c","scripts":{"lint":"eslint","test":"bun test","build":"tsup src/index.ts src/core/index.ts src/aliyun/index.ts src/google/index.ts --format esm --dts --out-dir dist --clean","format":"prettier --write \"**/*.{ts,tsx}\"","typecheck":"tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit","typecheck:release":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"windzb","email":"windzb@qq.com"},"_npmVersion":"11.13.0","description":"Upload helpers for AI media provider inputs","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9","@types/bun":"^1.2.0","typescript":"^5","@types/node":"^20","@workspace/eslint-config":"workspace:*","@workspace/typescript-config":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/uploader_0.1.0_1786090723463_0.9332585701564133","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ai-media/uploader","version":"0.1.1","license":"MIT","_id":"@ai-media/uploader@0.1.1","maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"dist":{"shasum":"bdb306bc7b5b633eb604e7eeb01ba89a6bf3acff","tarball":"https://registry.npmjs.org/@ai-media/uploader/-/uploader-0.1.1.tgz","fileCount":23,"integrity":"sha512-nbW5UGd6a+g5L6E6GVvWxsI0AMa4WZkdj/bHG/juUKAH03gkcB1im6ElsOKei5K6FvH8jcpsmMyS2rb/gSI6pw==","signatures":[{"sig":"MEUCIDf25py43nIJ2cT7GZEVqoZkMleEQfIIrgaELjbeTFt8AiEA3qa973lntaxg4ih594iR+M9O7E3g/U5EeYztyYDOvIA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34812},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./aliyun":{"types":"./dist/aliyun/index.d.ts","import":"./dist/aliyun/index.js"},"./google":{"types":"./dist/google/index.d.ts","import":"./dist/google/index.js"}},"gitHead":"2424f1f89827219fc8467a3752f06b84bef86807","scripts":{"test":"bun test","build":"tsup src/index.ts src/core/index.ts src/aliyun/index.ts src/google/index.ts --format esm --out-dir dist --clean && tsc -p tsconfig.emit-dts.json","typecheck":"tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit","typecheck:release":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"windzb","email":"windzb@qq.com"},"_npmVersion":"11.13.0","description":"Upload helpers for AI media provider inputs","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.0","typescript":"^7.0.2","@types/node":"^20","@workspace/typescript-config":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/uploader_0.1.1_1786609206709_0.0000706673837720384","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@ai-media/uploader","version":"0.1.2","license":"MIT","_id":"@ai-media/uploader@0.1.2","maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"dist":{"shasum":"b658976fe43848e0d5a4e8db47a7353af4872a25","tarball":"https://registry.npmjs.org/@ai-media/uploader/-/uploader-0.1.2.tgz","fileCount":23,"integrity":"sha512-lDi1qEh83gPRqNhGOSlhRzsA4Jfj2kGL1yk7AZh8rZM0s87r3VfiDlubLuT7s73oYsed60kcAbi6k6GDbSJIrw==","signatures":[{"sig":"MEQCIGwJYwI15/q343rWQx8Rwmfv3cIMoSXyrBhncl+71f0lAiBjtrCsxpnI+FHvNqAn44pmDJWcYGo+r9I578rwdtkDYw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34812},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./aliyun":{"types":"./dist/aliyun/index.d.ts","import":"./dist/aliyun/index.js"},"./google":{"types":"./dist/google/index.d.ts","import":"./dist/google/index.js"}},"gitHead":"ea34b4d9d1140bae548933472771a6dd44d7865b","scripts":{"test":"bun test","build":"tsup src/index.ts src/core/index.ts src/aliyun/index.ts src/google/index.ts --format esm --out-dir dist --clean && tsc -p tsconfig.emit-dts.json","typecheck":"tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit","typecheck:release":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"windzb","email":"windzb@qq.com"},"_npmVersion":"11.13.0","description":"Upload helpers for AI media provider inputs","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.0","typescript":"^7.0.2","@types/node":"^20","@workspace/typescript-config":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/uploader_0.1.2_1786617039798_0.5861464273628734","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@ai-media/uploader","version":"0.1.3","license":"MIT","_id":"@ai-media/uploader@0.1.3","maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"dist":{"shasum":"1ae01fce401eb158553ce50a1d91e5ba836901e5","tarball":"https://registry.npmjs.org/@ai-media/uploader/-/uploader-0.1.3.tgz","fileCount":26,"integrity":"sha512-7h/QhhlUqat3/LMDT81KBdKrydfPqbWJjiBzguFlHLeCt/AhWoU4GqEFlqoaVdIwSnc/tffDJMIg7dtpDGM1Jg==","signatures":[{"sig":"MEUCIHFnvO+MtlukdOhHnpevqb8sz6UG+aOxVGRKdjTRv52JAiEA/yfPpmmfRXc2t4aOqSs28bJoen+/7Vb9/geAY4xf2Ik=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38428},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./aliyun":{"types":"./dist/aliyun/index.d.ts","import":"./dist/aliyun/index.js"},"./google":{"types":"./dist/google/index.d.ts","import":"./dist/google/index.js"},"./aliyun/browser":{"types":"./dist/aliyun/browser.d.ts","import":"./dist/aliyun/browser.js"}},"gitHead":"6c3b3f554fde04c18b01ab1db1a640c686a1b627","scripts":{"test":"bun test","build":"tsup src/index.ts src/core/index.ts src/aliyun/index.ts src/aliyun/browser.ts src/google/index.ts --format esm --out-dir dist --clean && tsc -p tsconfig.emit-dts.json","typecheck":"tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit","typecheck:release":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"windzb","email":"windzb@qq.com"},"_npmVersion":"11.13.0","description":"Upload helpers for AI media provider inputs","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.0","typescript":"^7.0.2","@types/node":"^20","@workspace/typescript-config":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/uploader_0.1.3_1788338213658_0.0400027438625552","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@ai-media/uploader","version":"0.1.4","license":"MIT","_id":"@ai-media/uploader@0.1.4","maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"dist":{"shasum":"535699e16250d449b2a3ca84bcfe55c435602391","tarball":"https://registry.npmjs.org/@ai-media/uploader/-/uploader-0.1.4.tgz","fileCount":26,"integrity":"sha512-EaNl1OIdgQh+d4lK4sW7y7QpY5ObWc+xkzD1uzp5hn48sUa7s75mVZGZY9DisNLil8MH77BgPW32fsr33joIBA==","signatures":[{"sig":"MEUCIQDdDlFo054IEaVQnkqMEy/f6W06uEShTtvxcA60aoiBAQIgfT78Cm3Aqb86/buFl1mCCaRxOZQCNrLSq37DPnxJXgs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38428},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./aliyun":{"types":"./dist/aliyun/index.d.ts","import":"./dist/aliyun/index.js"},"./google":{"types":"./dist/google/index.d.ts","import":"./dist/google/index.js"},"./aliyun/browser":{"types":"./dist/aliyun/browser.d.ts","import":"./dist/aliyun/browser.js"}},"gitHead":"5c8cd107a8ccb6238e595123b53eff87d2da7f26","scripts":{"test":"bun test","build":"tsup src/index.ts src/core/index.ts src/aliyun/index.ts src/aliyun/browser.ts src/google/index.ts --format esm --out-dir dist --clean && tsc -p tsconfig.emit-dts.json","typecheck":"tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit","typecheck:release":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"windzb","email":"windzb@qq.com"},"_npmVersion":"10.9.3","description":"Upload helpers for AI media provider inputs","directories":{},"_nodeVersion":"22.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.0","typescript":"^7.0.2","@types/node":"^20","@workspace/typescript-config":"workspace:*"},"_npmOperationalInternal":{"tmp":"tmp/uploader_0.1.4_1788873421111_0.3003460161696425","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@ai-media/uploader","version":"0.1.5","type":"module","description":"Upload helpers for AI media provider inputs","license":"MIT","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./aliyun":{"types":"./dist/aliyun/index.d.ts","import":"./dist/aliyun/index.js"},"./aliyun/browser":{"types":"./dist/aliyun/browser.d.ts","import":"./dist/aliyun/browser.js"},"./google":{"types":"./dist/google/index.d.ts","import":"./dist/google/index.js"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsup src/index.ts src/core/index.ts src/aliyun/index.ts src/aliyun/browser.ts src/google/index.ts --format esm --out-dir dist --clean && tsc -p tsconfig.emit-dts.json","typecheck":"tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit","typecheck:release":"tsc -p tsconfig.json --noEmit","test":"bun test"},"devDependencies":{"@types/bun":"^1.2.0","@types/node":"^20","@workspace/typescript-config":"workspace:*","typescript":"^7.0.2"},"_id":"@ai-media/uploader@0.1.5","gitHead":"ca953c8881ebb066181712b134a2e559b827aa9f","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-1uaYkgghXFtAlCpNZNWZNuRta5w48kE3bCsYrhtcfiT6JDV3wn37mNq1xzHRbiYaIQ5hLwsJFM91zHh1i0QNGw==","shasum":"dd1574dd77c97871e302236ec0135f904aa57842","tarball":"https://registry.npmjs.org/@ai-media/uploader/-/uploader-0.1.5.tgz","fileCount":26,"unpackedSize":38428,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEta+UnVvW23VLfkJvcH9f3llIqkX5xbb5j34Kdg9D53AiA6B32HzQfpzcjfXlFXrZZoRjkQ4FD12U3F4i6IRzWpsw=="}]},"_npmUser":{"name":"windzb","email":"windzb@qq.com"},"directories":{},"maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/uploader_0.1.5_1789053218176_0.45147766360347075"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-07T08:18:43.312Z","modified":"2026-09-10T15:13:38.484Z","0.1.0":"2026-08-07T08:18:43.597Z","0.1.1":"2026-08-13T08:20:06.845Z","0.1.2":"2026-08-13T10:30:40.003Z","0.1.3":"2026-09-02T08:36:53.786Z","0.1.4":"2026-09-08T13:17:01.250Z","0.1.5":"2026-09-10T15:13:38.302Z"},"license":"MIT","description":"Upload helpers for AI media provider inputs","maintainers":[{"name":"windzb","email":"windzb@qq.com"}],"readme":"# @ai-media/uploader\n\n[![npm version](https://img.shields.io/npm/v/@ai-media/uploader.svg)](https://www.npmjs.com/package/@ai-media/uploader)\n[![npm downloads](https://img.shields.io/npm/dm/@ai-media/uploader.svg)](https://www.npmjs.com/package/@ai-media/uploader)\n[![License](https://img.shields.io/npm/l/@ai-media/uploader.svg)](https://github.com/ecafe8/ai-media-sdk/blob/main/packages/uploader/LICENSE)\n\nAI Provider 输入文件的临时上传辅助。将本地文件或字节流上传为 Provider 可接受的临时 URL，供图像/视频生成调用引用。\n\n> **定位**：开发/测试便利工具。各平台临时 URL 均有有效期与配额限制，生产环境请使用自有持久存储。\n>\n> **注意**：本项目处于快速迭代期间，API 可能随时变更，生产使用请锁定版本。\n\n## 安装\n\n```bash\nnpm install @ai-media/uploader\n```\n\n运行时要求：Node.js >= 20（或 Bun），ESM-only。上传实现依赖 Node 内置模块读取本地文件，适用于服务端环境。\n\n## 子路径导出\n\n| 导入路径                    | 内容                                                                       |\n| --------------------------- | -------------------------------------------------------------------------- |\n| `@ai-media/uploader`        | 通用类型与错误（同 `./core`）                                              |\n| `@ai-media/uploader/core`   | `UploadedFile`、`UploaderOptions`、`UploaderError`、`UPLOADER_ERROR_CODES` |\n| `@ai-media/uploader/aliyun` | `createAliyunUploader` — DashScope 临时文件上传                            |\n| `@ai-media/uploader/google` | `createGoogleUploader` — Gemini Files API 上传与生命周期                   |\n\n## Aliyun（DashScope 临时上传）\n\n三步流程（获取上传凭证 → OSS 直传 → 返回 `oss://` URL），凭据通过 `apiKey` 传入：\n\n```ts\nimport { createAliyunUploader } from \"@ai-media/uploader/aliyun\";\n\nconst uploader = createAliyunUploader({\n  apiKey: \"<your-dashscope-api-key>\",\n  // baseUrl 可选，默认 https://dashscope.aliyuncs.com\n  // timeoutMs 可选，默认 30_000\n});\n\nconst uploaded = await uploader.upload({\n  model: \"qwen-image-2.0-pro\", // 必填：DashScope 将文件绑定到模型，\n  // 必须与下游生成调用的模型一致\n  filePath: \"./input.png\", // 本地文件路径\n  // 或内存字节：fileBytes: new Uint8Array(...), fileName: \"input.png\"\n});\n\nconsole.log(uploaded.url); // oss://...\nconsole.log(uploaded.expiresAt); // 48 小时后过期\n```\n\n- 返回的 `requiresHeaders` 声明了下游调用需要的 `X-DashScope-OssResourceResolve: enable` 请求头；使用 `@ai-media/provider-aliyun-bailian` 时，适配器检测到 `oss://` URL 会**自动注入**该请求头，无需手动处理。\n- 凭证接口限流：每账号 + 模型 100 QPS；临时 URL 48 小时过期。\n\n与 SDK 配合（上传后作为编辑输入）：\n\n```ts\nimport { createAliyunBailianProvider } from \"@ai-media/provider-aliyun-bailian\";\nimport { editImage } from \"@ai-media/sdk\";\n\nconst provider = createAliyunBailianProvider({\n  apiKey: \"<your-dashscope-api-key>\",\n  baseUrl: \"https://<WorkspaceId>.cn-beijing.maas.aliyuncs.com/api/v1\",\n});\n\nconst result = await editImage({\n  model: provider.image(\"qwen-image-2.0-pro\"),\n  prompt: \"把画面改成雪天\",\n  images: [{ url: uploaded.url }],\n});\n```\n\n## Google（Gemini Files API）\n\n可续传协议上传，返回标准 `https://` URL，并提供文件生命周期管理：\n\n```ts\nimport { createGoogleUploader } from \"@ai-media/uploader/google\";\n\nconst uploader = createGoogleUploader({\n  apiKey: \"<your-gemini-api-key>\",\n  // baseUrl 可选，默认 https://generativelanguage.googleapis.com\n});\n\nconst uploaded = await uploader.upload({\n  filePath: \"./input.png\",\n  // 或内存字节：fileBytes + fileName + mimeType（fileBytes 时 mimeType 必填）\n  displayName: \"input.png\", // 可选\n});\n\nconsole.log(uploaded.url); // 传给模型的 https URL\nconsole.log(uploaded.name); // 文件资源 id，如 files/abc，用于 get/delete\nconsole.log(uploaded.state); // PROCESSING / ACTIVE / FAILED\nconsole.log(uploaded.expiresAt); // 48 小时后过期\n\nconst meta = await uploader.get(uploaded.name);\nfor await (const file of uploader.list()) {\n  console.log(file.name, file.state);\n}\nawait uploader.delete(uploaded.name);\n```\n\n限制：单文件最大 2GB，单项目存储上限 20GB，文件 48 小时自动过期。\n\n## 通用结果与错误\n\n所有上传结果都实现通用 `UploadedFile` 形状：\n\n```ts\ninterface UploadedFile {\n  url: string; // 传给模型的临时 URL\n  mimeType?: string;\n  sizeBytes?: number;\n  expiresAt?: Date; // 平台声明的过期时间\n  requiresHeaders?: Record<string, string>; // 下游调用需携带的请求头\n}\n```\n\n失败统一抛出 `UploaderError`，携带稳定 `code` 与上游 `statusCode`（如适用）：\n\n`INVALID_REQUEST` / `POLICY_ERROR` / `UPLOAD_ERROR` / `RATE_LIMITED` / `NOT_FOUND` / `INVALID_RESPONSE` / `UNKNOWN`\n\n```ts\nimport { UploaderError } from \"@ai-media/uploader\";\n\ntry {\n  await uploader.upload({\n    model: \"qwen-image-2.0-pro\",\n    filePath: \"./input.png\",\n  });\n} catch (error) {\n  if (error instanceof UploaderError) {\n    console.error(error.code, error.message);\n  }\n}\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}