初始提交
This commit is contained in:
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
node_modules/
|
||||
.env
|
||||
*.log
|
||||
.DS_Store
|
||||
img_2/*.jpg
|
||||
img_2/*.png
|
||||
img_2/*.webp
|
||||
|
||||
BIN
P1191464.JPG
Normal file
BIN
P1191464.JPG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
138
README.md
Normal file
138
README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# 亚马逊产品图生成工作流
|
||||
|
||||
这是一个基于Node.js的自动化工作流,用于通过速创API生成亚马逊所需的主图和产品图。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ 自动生成亚马逊主图(白底图、生活场景图)
|
||||
- ✅ 自动生成亚马逊产品图(细节图、使用场景图、功能展示图)
|
||||
- ✅ 定时查询图片生成状态
|
||||
- ✅ 自动下载并保存生成的图片
|
||||
- ✅ 支持批量处理多个图片生成任务
|
||||
|
||||
## 安装依赖
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
1. 复制环境变量示例文件:
|
||||
```bash
|
||||
# Windows
|
||||
copy config.example.env .env
|
||||
|
||||
# Linux/Mac
|
||||
cp config.example.env .env
|
||||
```
|
||||
|
||||
2. 编辑 `.env` 文件,配置以下参数:
|
||||
|
||||
```env
|
||||
# 必填:API密钥(在速创API控制台->密钥管理查看)
|
||||
API_KEY=your_api_key_here
|
||||
|
||||
# 必填:源图片URL(需要将P1191464.JPG上传到图床服务,获取外网可访问的URL)
|
||||
SOURCE_IMAGE_URL=https://your-image-host.com/P1191464.JPG
|
||||
|
||||
# 可选:图片尺寸 (1K/2K/4K)
|
||||
IMAGE_SIZE=2K
|
||||
|
||||
# 可选:图片比例 (1:1/16:9/4:3等)
|
||||
ASPECT_RATIO=1:1
|
||||
|
||||
# 可选:查询间隔(毫秒)
|
||||
QUERY_INTERVAL=5000
|
||||
|
||||
# 可选:最大查询次数
|
||||
MAX_QUERY_COUNT=60
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 1. 准备源图片
|
||||
|
||||
由于API要求图片URL必须是外网可访问的链接,您需要:
|
||||
|
||||
- 将 `P1191464.JPG` 上传到图床服务(如:Imgur、SM.MS、七牛云等)
|
||||
- 获取图片的公开访问URL
|
||||
- 将URL填入 `.env` 文件的 `SOURCE_IMAGE_URL`
|
||||
|
||||
### 2. 配置API密钥
|
||||
|
||||
在速创API控制台的密钥管理页面获取您的API密钥,填入 `.env` 文件。
|
||||
|
||||
### 3. 运行工作流
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
## 生成图片说明
|
||||
|
||||
工作流会自动生成以下类型的图片:
|
||||
|
||||
### 主图(Main Images)
|
||||
- `main_image_white_bg.jpg` - 白底主图
|
||||
- `main_image_lifestyle.jpg` - 生活场景主图
|
||||
|
||||
### 产品图(Product Images)
|
||||
- `product_detail_1.jpg` - 产品细节图1
|
||||
- `product_detail_2.jpg` - 产品细节图2
|
||||
- `product_in_use.jpg` - 产品使用场景图
|
||||
- `product_features.jpg` - 产品功能展示图
|
||||
|
||||
所有生成的图片将保存在 `img_2` 文件夹中。
|
||||
|
||||
## API接口说明
|
||||
|
||||
### 生图接口
|
||||
- 文档:https://api.wuyinkeji.com/doc/43
|
||||
- 接口:`POST https://api.wuyinkeji.com/api/img/nanoBanana-pro`
|
||||
|
||||
### 查询接口
|
||||
- 文档:https://api.wuyinkeji.com/doc/9
|
||||
- 接口:`GET https://api.wuyinkeji.com/api/img/drawDetail`
|
||||
- 请求方式:HTTP GET
|
||||
- 请求参数:
|
||||
- `id` (必填, int类型) - 图片ID(从生图接口返回)
|
||||
- 请求头:
|
||||
- `Content-Type: application/json;charset:utf-8;`
|
||||
- `Authorization: 接口密钥`
|
||||
- 响应格式:
|
||||
- `code`: 状态码(200表示成功)
|
||||
- `msg`: 状态信息
|
||||
- `data.status`: 图片生成状态
|
||||
- `0`: 排队中
|
||||
- `1`: 生成中
|
||||
- `2`: 成功(此时 `data.image_url` 包含图片地址)
|
||||
- `3`: 失败
|
||||
- `data.image_url`: 生成的图片地址(仅当 status=2 时返回)
|
||||
- `data.prompt`: 生成时使用的提示词
|
||||
- `data.size`: 图片比例
|
||||
- `data.created_at`: 创建时间
|
||||
- `data.updated_at`: 更新时间
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 如何修改生成的图片类型?
|
||||
A: 编辑 `index.js` 文件中的 `MAIN_IMAGE_PROMPTS` 和 `PRODUCT_IMAGE_PROMPTS` 数组,修改或添加prompt模板。
|
||||
|
||||
### Q: 查询接口已根据官方文档配置
|
||||
A: 查询接口已完全按照 [官方文档](https://api.wuyinkeji.com/doc/9) 实现,支持状态码 0-3 的完整处理流程。
|
||||
|
||||
### Q: 如何调整查询频率?
|
||||
A: 修改 `.env` 文件中的 `QUERY_INTERVAL` 参数(单位:毫秒)。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保API密钥有效且有足够的余额
|
||||
2. 源图片URL必须是外网可访问的HTTPS链接
|
||||
3. 图片生成可能需要较长时间,请耐心等待
|
||||
4. 建议在测试环境先运行,确认配置正确后再批量生成
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT
|
||||
|
||||
24
config.example.env
Normal file
24
config.example.env
Normal file
@@ -0,0 +1,24 @@
|
||||
# 速创API配置
|
||||
API_KEY=your_api_key_here
|
||||
API_BASE_URL=https://api.wuyinkeji.com
|
||||
|
||||
# 生图接口
|
||||
GENERATE_API=/api/img/nanoBanana-pro
|
||||
|
||||
# 查询接口(图片生成结果查询)
|
||||
QUERY_API=/api/img/drawDetail
|
||||
|
||||
# 图片配置
|
||||
SOURCE_IMAGE_URL=https://your-image-host.com/P1191464.JPG
|
||||
# 或者如果使用本地图片,需要先上传到图床服务
|
||||
|
||||
# 生成配置
|
||||
IMAGE_SIZE=2K
|
||||
ASPECT_RATIO=1:1
|
||||
|
||||
# 查询间隔(毫秒)
|
||||
QUERY_INTERVAL=5000
|
||||
|
||||
# 最大查询次数
|
||||
MAX_QUERY_COUNT=60
|
||||
|
||||
338
index.js
Normal file
338
index.js
Normal file
@@ -0,0 +1,338 @@
|
||||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
require('dotenv').config();
|
||||
|
||||
// 配置
|
||||
const config = {
|
||||
apiKey: process.env.API_KEY,
|
||||
apiBaseUrl: process.env.API_BASE_URL || 'https://api.wuyinkeji.com',
|
||||
generateApi: process.env.GENERATE_API || '/api/img/nanoBanana-pro',
|
||||
queryApi: process.env.QUERY_API || '/api/img/drawDetail',
|
||||
sourceImageUrl: process.env.SOURCE_IMAGE_URL,
|
||||
imageSize: process.env.IMAGE_SIZE || '2K',
|
||||
aspectRatio: process.env.ASPECT_RATIO || '1:1',
|
||||
queryInterval: parseInt(process.env.QUERY_INTERVAL) || 5000,
|
||||
maxQueryCount: parseInt(process.env.MAX_QUERY_COUNT) || 60,
|
||||
outputDir: path.join(__dirname, 'img_2')
|
||||
};
|
||||
|
||||
// 确保输出目录存在
|
||||
if (!fs.existsSync(config.outputDir)) {
|
||||
fs.mkdirSync(config.outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 亚马逊主图prompt模板
|
||||
const MAIN_IMAGE_PROMPTS = [
|
||||
{
|
||||
name: 'main_image_white_bg',
|
||||
prompt: 'Create a professional Amazon product main image with pure white background. The product should be centered, well-lit, showing all key features clearly. High quality commercial photography style, clean and minimalist.',
|
||||
aspectRatio: '1:1'
|
||||
},
|
||||
{
|
||||
name: 'main_image_lifestyle',
|
||||
prompt: 'Create a lifestyle Amazon product main image showing the product in a natural, appealing setting. Professional product photography, bright and inviting atmosphere.',
|
||||
aspectRatio: '1:1'
|
||||
}
|
||||
];
|
||||
|
||||
// 亚马逊产品图prompt模板
|
||||
const PRODUCT_IMAGE_PROMPTS = [
|
||||
{
|
||||
name: 'product_detail_1',
|
||||
prompt: 'Create a detailed Amazon product image showing close-up details and features. Professional product photography, white background, high resolution.',
|
||||
aspectRatio: '1:1'
|
||||
},
|
||||
{
|
||||
name: 'product_detail_2',
|
||||
prompt: 'Create an Amazon product image showing different angles and perspectives. Clean white background, professional lighting, showcasing product quality.',
|
||||
aspectRatio: '1:1'
|
||||
},
|
||||
{
|
||||
name: 'product_in_use',
|
||||
prompt: 'Create an Amazon product image showing the product in use scenario. Natural setting, professional photography, highlighting product benefits.',
|
||||
aspectRatio: '4:3'
|
||||
},
|
||||
{
|
||||
name: 'product_features',
|
||||
prompt: 'Create an Amazon product image highlighting key features and specifications. Clean layout, professional design, easy to understand.',
|
||||
aspectRatio: '16:9'
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* 调用生图API
|
||||
*/
|
||||
async function generateImage(prompt, imageConfig) {
|
||||
try {
|
||||
const url = `${config.apiBaseUrl}${config.generateApi}`;
|
||||
const requestData = {
|
||||
prompt: prompt.prompt,
|
||||
aspectRatio: imageConfig.aspectRatio || prompt.aspectRatio || config.aspectRatio,
|
||||
imageSize: imageConfig.imageSize || config.imageSize
|
||||
};
|
||||
|
||||
// 如果提供了源图片URL,添加到请求中
|
||||
if (config.sourceImageUrl) {
|
||||
requestData.img_url = config.sourceImageUrl;
|
||||
}
|
||||
|
||||
console.log(`\n正在生成图片: ${prompt.name}`);
|
||||
console.log(`Prompt: ${prompt.prompt.substring(0, 100)}...`);
|
||||
console.log(`请求URL: ${url}`);
|
||||
|
||||
const response = await axios.post(url, requestData, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset:utf-8;',
|
||||
'Authorization': config.apiKey
|
||||
},
|
||||
timeout: 30000
|
||||
});
|
||||
|
||||
if (response.data && response.data.code === 200) {
|
||||
const taskId = response.data.data?.id || response.data.data?.taskId || response.data.taskId;
|
||||
console.log(`✅ 任务提交成功,任务ID: ${taskId}`);
|
||||
return { success: true, taskId, name: prompt.name };
|
||||
} else {
|
||||
console.error(`❌ 任务提交失败:`, response.data);
|
||||
return { success: false, error: response.data };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ 生成图片时出错:`, error.message);
|
||||
if (error.response) {
|
||||
console.error(`响应数据:`, error.response.data);
|
||||
}
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询图片生成结果
|
||||
*/
|
||||
async function queryImageResult(taskId, imageName) {
|
||||
let queryCount = 0;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const queryInterval = setInterval(async () => {
|
||||
queryCount++;
|
||||
|
||||
if (queryCount > config.maxQueryCount) {
|
||||
clearInterval(queryInterval);
|
||||
reject(new Error(`查询超时,已查询${queryCount}次`));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 根据API文档: https://api.wuyinkeji.com/doc/9
|
||||
// 接口地址: https://api.wuyinkeji.com/api/img/drawDetail
|
||||
// 请求方式: GET
|
||||
// 请求参数: id (必填, int类型) - 图片ID
|
||||
// 返回格式: data.status (0:排队中,1:生成中,2:成功,3:失败)
|
||||
// data.image_url (生成的图片地址)
|
||||
const queryUrl = `${config.apiBaseUrl}${config.queryApi}?id=${taskId}`;
|
||||
|
||||
console.log(`[${queryCount}/${config.maxQueryCount}] 查询任务状态: ID=${taskId}`);
|
||||
|
||||
const response = await axios.get(queryUrl, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset:utf-8;',
|
||||
'Authorization': config.apiKey
|
||||
},
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
|
||||
// 根据API文档响应格式:
|
||||
// code: 状态码
|
||||
// msg: 状态信息
|
||||
// data.status: 0:排队中,1:生成中,2:成功,3:失败
|
||||
// data.image_url: 生成的图片地址
|
||||
if (data.code === 200 && data.data) {
|
||||
const status = data.data.status;
|
||||
const imageUrl = data.data.image_url;
|
||||
|
||||
// status: 2 表示成功
|
||||
if (status === 2) {
|
||||
if (imageUrl) {
|
||||
clearInterval(queryInterval);
|
||||
console.log(`✅ 图片生成成功: ${imageName}`);
|
||||
console.log(`图片URL: ${imageUrl}`);
|
||||
resolve({ imageUrl, taskId, imageName });
|
||||
} else {
|
||||
console.log(`⏳ 图片生成成功但URL未返回,继续等待...`);
|
||||
}
|
||||
}
|
||||
// status: 3 表示失败
|
||||
else if (status === 3) {
|
||||
clearInterval(queryInterval);
|
||||
reject(new Error(`图片生成失败: ${data.msg || data.data.msg || '未知错误'}`));
|
||||
}
|
||||
// status: 0 排队中, 1 生成中
|
||||
else {
|
||||
const statusText = status === 0 ? '排队中' : status === 1 ? '生成中' : `未知状态${status}`;
|
||||
console.log(`⏳ ${statusText}...`);
|
||||
}
|
||||
} else if (data.code !== 200) {
|
||||
// API返回错误
|
||||
console.log(`⚠️ 查询返回错误: ${data.msg || '未知错误'} (code: ${data.code})`);
|
||||
// 继续重试,不立即失败
|
||||
} else {
|
||||
console.log(`⏳ 等待中... (响应: ${data.msg || '处理中'})`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 404) {
|
||||
// 任务可能还在处理中
|
||||
console.log(`⏳ 任务处理中,继续等待...`);
|
||||
} else {
|
||||
console.error(`查询时出错:`, error.message);
|
||||
// 不立即失败,继续重试
|
||||
}
|
||||
}
|
||||
}, config.queryInterval);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载并保存图片
|
||||
*/
|
||||
async function downloadAndSaveImage(imageUrl, imageName) {
|
||||
try {
|
||||
console.log(`\n开始下载图片: ${imageUrl}`);
|
||||
|
||||
const response = await axios({
|
||||
url: imageUrl,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
timeout: 60000
|
||||
});
|
||||
|
||||
// 确定文件扩展名
|
||||
const contentType = response.headers['content-type'];
|
||||
let extension = '.jpg';
|
||||
if (contentType) {
|
||||
if (contentType.includes('png')) extension = '.png';
|
||||
else if (contentType.includes('webp')) extension = '.webp';
|
||||
}
|
||||
|
||||
const filename = `${imageName}${extension}`;
|
||||
const filepath = path.join(config.outputDir, filename);
|
||||
|
||||
const writer = fs.createWriteStream(filepath);
|
||||
response.data.pipe(writer);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on('finish', () => {
|
||||
console.log(`✅ 图片已保存: ${filepath}`);
|
||||
resolve(filepath);
|
||||
});
|
||||
writer.on('error', (error) => {
|
||||
console.error(`❌ 保存图片失败:`, error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`❌ 下载图片失败:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个图片生成任务
|
||||
*/
|
||||
async function processImageGeneration(prompt) {
|
||||
try {
|
||||
// 1. 提交生成任务
|
||||
const generateResult = await generateImage(prompt, {
|
||||
aspectRatio: prompt.aspectRatio,
|
||||
imageSize: config.imageSize
|
||||
});
|
||||
|
||||
if (!generateResult.success) {
|
||||
throw new Error('任务提交失败');
|
||||
}
|
||||
|
||||
// 2. 查询生成结果
|
||||
const queryResult = await queryImageResult(generateResult.taskId, prompt.name);
|
||||
|
||||
// 3. 下载并保存图片
|
||||
await downloadAndSaveImage(queryResult.imageUrl, queryResult.imageName);
|
||||
|
||||
return { success: true, name: prompt.name };
|
||||
} catch (error) {
|
||||
console.error(`处理图片 ${prompt.name} 时出错:`, error.message);
|
||||
return { success: false, name: prompt.name, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主工作流
|
||||
*/
|
||||
async function main() {
|
||||
console.log('🚀 开始亚马逊产品图生成工作流...\n');
|
||||
console.log('配置信息:');
|
||||
console.log(`- API地址: ${config.apiBaseUrl}`);
|
||||
console.log(`- 源图片: ${config.sourceImageUrl || '使用本地图片'}`);
|
||||
console.log(`- 输出目录: ${config.outputDir}`);
|
||||
console.log(`- 图片尺寸: ${config.imageSize}`);
|
||||
console.log(`- 查询间隔: ${config.queryInterval}ms\n`);
|
||||
|
||||
if (!config.apiKey) {
|
||||
console.error('❌ 错误: 未设置API_KEY,请在.env文件中配置');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!config.sourceImageUrl) {
|
||||
console.warn('⚠️ 警告: 未设置SOURCE_IMAGE_URL');
|
||||
console.warn('提示: 请将P1191464.JPG上传到图床服务,然后在.env中设置SOURCE_IMAGE_URL');
|
||||
console.warn('或者修改代码以支持直接上传本地图片\n');
|
||||
}
|
||||
|
||||
const allPrompts = [...MAIN_IMAGE_PROMPTS, ...PRODUCT_IMAGE_PROMPTS];
|
||||
const results = [];
|
||||
|
||||
// 顺序处理每个图片生成任务
|
||||
for (const prompt of allPrompts) {
|
||||
const result = await processImageGeneration(prompt);
|
||||
results.push(result);
|
||||
|
||||
// 在任务之间稍作延迟,避免请求过快
|
||||
if (allPrompts.indexOf(prompt) < allPrompts.length - 1) {
|
||||
console.log('\n等待3秒后处理下一个任务...\n');
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
}
|
||||
}
|
||||
|
||||
// 输出总结
|
||||
console.log('\n' + '='.repeat(50));
|
||||
console.log('📊 工作流执行总结:');
|
||||
console.log('='.repeat(50));
|
||||
const successCount = results.filter(r => r.success).length;
|
||||
const failCount = results.filter(r => !r.success).length;
|
||||
console.log(`✅ 成功: ${successCount}/${results.length}`);
|
||||
console.log(`❌ 失败: ${failCount}/${results.length}`);
|
||||
|
||||
if (failCount > 0) {
|
||||
console.log('\n失败的任务:');
|
||||
results.filter(r => !r.success).forEach(r => {
|
||||
console.log(` - ${r.name}: ${r.error}`);
|
||||
});
|
||||
}
|
||||
console.log('='.repeat(50));
|
||||
}
|
||||
|
||||
// 运行主工作流
|
||||
if (require.main === module) {
|
||||
main().catch(error => {
|
||||
console.error('❌ 工作流执行失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generateImage,
|
||||
queryImageResult,
|
||||
downloadAndSaveImage,
|
||||
processImageGeneration
|
||||
};
|
||||
|
||||
285
package-lock.json
generated
Normal file
285
package-lock.json
generated
Normal file
@@ -0,0 +1,285 @@
|
||||
{
|
||||
"name": "amazon-image-generator",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "amazon-image-generator",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
|
||||
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.6.1",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
|
||||
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
22
package.json
Normal file
22
package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "amazon-image-generator",
|
||||
"version": "1.0.0",
|
||||
"description": "亚马逊产品图生成工作流",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"keywords": [
|
||||
"amazon",
|
||||
"image-generation",
|
||||
"workflow"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user