Comparing version 1.0.1 to 2.0.0
262
index.js
@@ -1,110 +0,196 @@ | ||
/** | ||
* Module dependencies. | ||
*/ | ||
'use strict'; | ||
const Client = require('cos-nodejs-sdk-v5'); | ||
const fs = require('fs'); | ||
const util = require('util'); | ||
const stream = require('stream'); | ||
const assert = require('assert'); | ||
var path = require('path'); | ||
var COS = require('./sdk/cos'); | ||
var fs = require('co-fs') | ||
var stream = require('stream'); | ||
var sdkConfig = require('./sdk/config') | ||
function trimKey(key) { | ||
return key ? key.replace(/^\//, '') : ''; | ||
} | ||
/** | ||
* Expose `Client` | ||
*/ | ||
module.exports = Client; | ||
function addBrowserDownloadQuery(url = '') { | ||
const prefix = url.includes('?') ? '&' : '?'; | ||
return `${url}${prefix}response-content-disposition=attachment`; | ||
} | ||
function Client(options) { | ||
if (!(this instanceof Client)) { | ||
return new Client(options); | ||
} | ||
function bufferToReadStream(buf) { | ||
const bufferStream = new stream.PassThrough(); | ||
bufferStream.end(buf); | ||
this.bucket = options.bucket || 'tnpmnfs'; | ||
this.region = options.region || 'cn-south'; | ||
sdkConfig.APPID = options.APPID; | ||
sdkConfig.SECRET_ID = options.SECRET_ID; | ||
sdkConfig.SECRET_KEY = options.SECRET_KEY; | ||
return bufferStream; | ||
} | ||
Client.prototype.upload = function*(filepath, options) { | ||
var content = yield fs.readFile(filepath); | ||
return yield this.uploadBuffer(content, options) | ||
}; | ||
class OssWrapper { | ||
constructor(options) { | ||
assert(options.bucket, 'options.bucket 为必传字段'); | ||
assert(options.region, 'options.region 为必传字段'); | ||
assert(options.secretId, 'options.secretId 为必传字段'); | ||
assert(options.secretKey, 'options.secretKey 为必传字段'); | ||
this.client = new Client({ | ||
SecretId: options.secretId, | ||
SecretKey: options.secretKey, | ||
Protocol: options.protocol || 'https:', | ||
}); | ||
this.options = options; | ||
this.bucket = options.bucket; | ||
this.region = options.region; | ||
this.storageClass = options.storageClass || 'MAZ_STANDARD'; | ||
} | ||
Client.prototype.uploadBuffer = function*(content, options) { | ||
var key = trimKey(options.key); | ||
var contentLength = content.length; | ||
var body = bufferToReadStream(content); // 转换成 read stream | ||
get commonBucketConfig() { | ||
return { | ||
Bucket: this.bucket, | ||
Region: this.region, | ||
}; | ||
} | ||
var params = { | ||
Bucket: this.bucket, /* 必须 */ | ||
Region: this.region, //cn-south、cn-north、cn-east /* 必须 */ | ||
Key: key, /* 必须 */ | ||
Body: body, /* 必须 */ | ||
ContentLength: contentLength, /* 必须 */ | ||
}; | ||
async upload(filePath, options) { | ||
return await this.uploadBuffer(filePath, options); | ||
} | ||
yield new Promise(function (resolve, reject) { | ||
COS.putObject(params, function (err, data) { | ||
if (err) { | ||
return reject(err); | ||
async uploadBuffer(content, options) { | ||
const key = trimKey(options.key); | ||
const contentLength = content.length; | ||
const body = bufferToReadStream(content); | ||
const params = { | ||
...this.commonBucketConfig, | ||
Key: key, | ||
Body: body, | ||
ContentLength: contentLength, | ||
StorageClass: this.storageClass, | ||
}; | ||
const putObjectPromise = util.promisify(this.client.putObject).bind(this.client); | ||
await putObjectPromise(params); | ||
return { key }; | ||
} | ||
async uploadBytes(bytes, options) { | ||
if (typeof bytes === 'string') { | ||
bytes = Buffer.from(bytes); | ||
} | ||
return await this.upload(bytes, options); | ||
} | ||
async appendBytes(bytes, options) { | ||
const Key = trimKey(options.key); | ||
if (typeof bytes === 'string') { | ||
bytes = Buffer.from(bytes); | ||
} | ||
const headObjectPromise = util.promisify(this.client.headObject).bind(this.client); | ||
try { | ||
const headRes = await headObjectPromise({ | ||
...this.commonBucketConfig, | ||
...options, | ||
Key, | ||
}); | ||
if (!options.position) { | ||
options.position = headRes.headers['content-length'] ?? 0; | ||
} | ||
resolve(data); // {ETag: 'xxxxxxx'} | ||
} catch (err) { | ||
console.log('head object error', err); | ||
} | ||
const appendObjectPromise = util.promisify(this.client.appendObject).bind(this.client); | ||
const appendRes = await appendObjectPromise({ | ||
...this.commonBucketConfig, | ||
...options, | ||
Key, | ||
Body: bytes, | ||
Position: Number(options.position) || 0, | ||
}); | ||
}) | ||
return {key: key}; | ||
}; | ||
return { | ||
...appendRes, | ||
// 这是因为 cnpmcore 的 NFSAdapter 需要 | ||
nextAppendPosition: appendRes.headers['x-cos-next-append-position'], | ||
}; | ||
} | ||
Client.prototype.download = function*(key, savePath, options) { | ||
var key = trimKey(key); | ||
async readBytes(key) { | ||
const Key = trimKey(key); | ||
const getObjectPromise = util.promisify(this.client.getObject).bind(this.client); | ||
const { Body } = await getObjectPromise({ | ||
Key, | ||
...this.commonBucketConfig, | ||
}); | ||
return Body; | ||
} | ||
var params = { | ||
Bucket: this.bucket, /* 必须 */ | ||
Region: this.region, //cn-south、cn-north、cn-east /* 必须 */ | ||
Key: key, /* 必须 */ | ||
Output: savePath | ||
}; | ||
// eslint-disable-next-line no-unused-vars | ||
async download(key, filepath, options) { | ||
const Key = trimKey(key); | ||
const getObjectPromise = util.promisify(this.client.getObject).bind(this.client); | ||
// todo: 检查options | ||
await getObjectPromise({ | ||
Key, | ||
...this.commonBucketConfig, | ||
Output: fs.createWriteStream(filepath), | ||
}); | ||
} | ||
/** | ||
* @param {string} prefix - file prefix | ||
* @param {object} [options] - | ||
* @param {number} [options.max] - default 1000 | ||
* @return {Promise<string[]>} - | ||
*/ | ||
async list(prefix, options) { | ||
const max = options && options.max || 1000; | ||
const stepMax = Math.min(1000, max); | ||
let Marker = null; | ||
let files = []; | ||
const getBucketPromise = util.promisify(this.client.getBucket).bind(this.client); | ||
do { | ||
const trimPrefix = trimKey(prefix); | ||
const res = await getBucketPromise({ | ||
...this.commonBucketConfig, | ||
Prefix: trimPrefix, | ||
MaxKeys: stepMax, | ||
Marker, | ||
}); | ||
const objects = res.Contents || []; | ||
const prefixLength = trimPrefix; | ||
const nextFiles = objects.map(o => o.Key.substring(prefixLength)); | ||
files = files.concat(nextFiles); | ||
Marker = res.NextMarker; | ||
} while (Marker && files.length <= max); | ||
return files; | ||
} | ||
yield new Promise(function (resolve, reject) { | ||
COS.getObject(params, function (err, data) { | ||
if (err) { | ||
return reject(err); | ||
} | ||
resolve(data); | ||
}) | ||
}) | ||
}; | ||
async createDownloadStream(key) { | ||
const Key = trimKey(key); | ||
Client.prototype.remove = function*(key) { | ||
var key = trimKey(key); | ||
return this.client.getObjectStream({ | ||
...this.commonBucketConfig, | ||
Key, | ||
}); | ||
} | ||
var params = { | ||
Bucket: this.bucket, /* 必须 */ | ||
Region: this.region, //cn-south、cn-north、cn-east /* 必须 */ | ||
Key: key, /* 必须 */ | ||
}; | ||
// todo options 会传什么值? | ||
// eslint-disable-next-line no-unused-vars | ||
async url(key, options) { | ||
const Key = trimKey(key); | ||
const getObjectUrlPromise = util.promisify(this.client.getObjectUrl).bind(this.client); | ||
const { Url } = await getObjectUrlPromise({ | ||
...this.commonBucketConfig, | ||
Key, | ||
Sign: true, | ||
}); | ||
return addBrowserDownloadQuery(Url); | ||
} | ||
yield new Promise(function (resolve, reject) { | ||
COS.deleteObject(params, function (err, data) { | ||
if (err) { | ||
return reject(err); | ||
} | ||
resolve(); | ||
}) | ||
}) | ||
}; | ||
async urls(key, options) { | ||
return await this.url(key, options); | ||
} | ||
function trimKey(key) { | ||
return key ? key.replace(/^\//, '') : ''; | ||
async remove(key) { | ||
const deleteObjectPromise = util.promisify(this.client.deleteObject).bind(this.client); | ||
const Key = trimKey(key); | ||
await deleteObjectPromise({ | ||
...this.commonBucketConfig, | ||
Key, | ||
}); | ||
} | ||
} | ||
function bufferToReadStream(buf) { | ||
// Initiate the source | ||
var bufferStream = new stream.PassThrough(); | ||
// Write your buffer | ||
bufferStream.end(buf); | ||
return bufferStream | ||
} | ||
module.exports = OssWrapper; |
{ | ||
"name": "cos-cnpm", | ||
"version": "1.0.1", | ||
"version": "2.0.0", | ||
"description": "tencent-cloud cos wrapper for cnpm", | ||
"main": "index.js", | ||
"files": [ | ||
"index.js" | ||
], | ||
"engines": { | ||
"node": ">= 16.0.0" | ||
}, | ||
"scripts": { | ||
"test": "make test" | ||
"lint": "eslint . --ext .js", | ||
"lint:fix": "eslint . --ext .js --fix", | ||
"test": "npm run lint:fix && npm run test-local", | ||
"test-local": "egg-bin test --full-trace", | ||
"t": "egg-bin test --changed --full-trace", | ||
"cov": "egg-bin cov --full-trace", | ||
"ci": "npm run lint && npm run cov" | ||
}, | ||
@@ -24,12 +36,12 @@ "keywords": [ | ||
"dependencies": { | ||
"async": "^2.2.0", | ||
"co-fs": "^1.2.0", | ||
"eventproxy": "^0.3.5", | ||
"request": "^2.81.0", | ||
"xml2js": "^0.4.17" | ||
"cos-nodejs-sdk-v5": "^2.11.6" | ||
}, | ||
"devDependencies": { | ||
"co": "^4.6.0", | ||
"mocha": "^1.21.4" | ||
"egg-bin": "^4.16.4", | ||
"eslint": "^7.32.0", | ||
"eslint-config-egg": "^9.0.0", | ||
"eslint-plugin-jsdoc": "^39.2.9", | ||
"eslint-plugin-node": "^11.1.0", | ||
"urllib": "^2.8.0" | ||
} | ||
} |
@@ -18,11 +18,13 @@ # cos-cnpm | ||
```js | ||
var client = require('cos-cnpm')({ | ||
APPID: '', | ||
SECRET_ID: '', | ||
SECRET_KEY: '', | ||
bucket: 'tnpmnfs', | ||
// 从 https://github.com/tencentyun/cos-java-sdk-v5/blob/master/src/main/java/com/qcloud/cos/region/Region.java 中选择。默认是 cn-south 华南 | ||
region: 'cn-south', | ||
}) | ||
import COSClient from 'cos-cnpm'; | ||
config.nfs = { | ||
client: new COSClient({ | ||
secretId: '', | ||
secretKey: '', | ||
bucket: '', | ||
region: '', | ||
}), | ||
// dir: join(config.dataDir, 'nfs'), | ||
}; | ||
``` | ||
@@ -42,4 +44,16 @@ | ||
- `uploadBytes`: upload bytes | ||
- `appendBytes`: append bytes | ||
- `readBytes`: read bytes | ||
- `list`: list files by prefix | ||
- `url`: get download url | ||
- `urls`: get download urls | ||
### License | ||
MIT |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
1
58
1
7659
6
4
176
2
+ Addedcos-nodejs-sdk-v5@^2.11.6
+ Addedajv@7.2.4(transitive)
+ Addedajv-formats@1.6.1(transitive)
+ Addedatomically@1.7.0(transitive)
+ Addedconf@9.0.2(transitive)
+ Addedcos-nodejs-sdk-v5@2.14.6(transitive)
+ Addeddebounce-fn@4.0.0(transitive)
+ Addeddot-prop@6.0.1(transitive)
+ Addedenv-paths@2.2.1(transitive)
+ Addedfast-xml-parser@4.2.5(transitive)
+ Addedfind-up@3.0.0(transitive)
+ Addedis-obj@2.0.0(transitive)
+ Addedjson-schema-traverse@1.0.0(transitive)
+ Addedjson-schema-typed@7.0.3(transitive)
+ Addedlocate-path@3.0.0(transitive)
+ Addedmake-dir@3.1.0(transitive)
+ Addedmimic-fn@2.1.03.1.0(transitive)
+ Addedonetime@5.1.2(transitive)
+ Addedp-limit@2.3.0(transitive)
+ Addedp-locate@3.0.0(transitive)
+ Addedp-try@2.2.0(transitive)
+ Addedpath-exists@3.0.0(transitive)
+ Addedpkg-up@3.1.0(transitive)
+ Addedrequire-from-string@2.0.2(transitive)
+ Addedsemver@6.3.17.7.1(transitive)
+ Addedstrnum@1.1.2(transitive)
- Removedasync@^2.2.0
- Removedco-fs@^1.2.0
- Removedeventproxy@^0.3.5
- Removedrequest@^2.81.0
- Removedxml2js@^0.4.17
- Removedasync@2.6.4(transitive)
- Removedco-from-stream@0.0.0(transitive)
- Removedco-fs@1.2.0(transitive)
- Removedco-read@0.0.1(transitive)
- Removeddebug@2.2.0(transitive)
- Removedeventproxy@0.3.5(transitive)
- Removedlodash@4.17.21(transitive)
- Removedms@0.7.1(transitive)
- Removedsax@1.4.1(transitive)
- Removedthunkify@0.0.1(transitive)
- Removedxml2js@0.4.23(transitive)
- Removedxmlbuilder@11.0.1(transitive)