diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..319299684 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +quote_type = single + +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore index 1c4abd1b6..e75f6190b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,18 +1,17 @@ -node_modules/ +build/ coverage/ -.tmp/ -.git/ -lib/browser/version.js +dist/ +es/ +lib/ +node_modules/ +**/*.min.js +**/*-min.js +**/*.bundle.js +example/ +test/ +browser-build.js shims/ -example/node_modules/ -example/public/ -example/public/index.js -test/.tmp/ -test/browser/.tmp -test/browser/build -test/benchmark/ -test/fixtures/ task/ -browser-build.js -es -cjs +karma.conf.js +publish-check.js +publish.js diff --git a/.eslintrc.js b/.eslintrc.js index d3ea422ca..dabebb47d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,35 +1,6 @@ -/* eslint max-len: [0] */ module.exports = { - extends: ['airbnb', 'eslint-config-ali/typescript'], - parserOptions: { - ecmaFeatures: { - experimentalObjectRestSpread: true, - }, - }, - env: { - browser: true, - node: true, - es6: true, - mocha: true, - jasmine: true, - jest: true, - }, - rules: { - indent: ['error', 2], - // override default options - 'no-underscore-dangle': [0], - 'no-plusplus': [0], - 'no-return-await':[0], - 'no-param-reassign': [0], - 'max-len': ['warn', 120, 2, { - ignoreUrls: true, - ignoreComments: false, - ignoreRegExpLiterals: true, - ignoreStrings: true, - ignoreTemplateLiterals: true, - }], - 'no-buffer-constructor': [2], - "comma-dangle": [0], - 'import/prefer-default-export': [0], - } + extends: [ + 'eslint-config-ali/node', + 'prettier', + ], }; diff --git a/.husky/pre-commit b/.husky/pre-commit index 57757f4ed..05f52abb4 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -2,3 +2,4 @@ . "$(dirname "$0")/_/husky.sh" npm run lint-staged +npm run f2elint-scan diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 796853bf4..000000000 --- a/.prettierrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "semi": true, - "singleQuote": true, - "tabWidth": 2, - "useTabs": false, - "printWidth": 120, - "bracketSpacing": true, - "arrowParens": "avoid", - "trailingComma": "none" -} diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..9353f639c --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,8 @@ +module.exports = { + printWidth: 100, + tabWidth: 2, + semi: true, + singleQuote: true, + trailingComma: 'all', + arrowParens: 'always', +}; diff --git a/commitlint.config.js b/commitlint.config.js index 422b19445..52f3b754b 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1 +1,3 @@ -module.exports = { extends: ['@commitlint/config-conventional'] }; +module.exports = { + extends: ['ali'], +}; diff --git a/f2elint.config.js b/f2elint.config.js new file mode 100644 index 000000000..9cdb28fd8 --- /dev/null +++ b/f2elint.config.js @@ -0,0 +1,5 @@ +module.exports = { + enableStylelint: false, + enableMarkdownlint: false, + enablePrettier: true, +}; diff --git a/lib/browser/managed-upload.js b/lib/browser/managed-upload.js index c70a9e3d9..54268bfaa 100644 --- a/lib/browser/managed-upload.js +++ b/lib/browser/managed-upload.js @@ -30,6 +30,11 @@ const proto = exports; * } */ proto.multipartUpload = async function multipartUpload(name, file, options = {}) { + if (this.options.multipartRunning) { + console.warn( + 'multipartUpload is already executing, if you need to call more than one multipartUpload at the same time, please create more instances', + ); + } this.resetCancelFlag(); options.disabledMD5 = options.disabledMD5 === undefined ? true : !!options.disabledMD5; if (options.checkpoint && options.checkpoint.uploadId) { @@ -67,7 +72,7 @@ proto.multipartUpload = async function multipartUpload(name, file, options = {}) res: result.res, bucket: this.options.bucket, name, - etag: result.res.headers.etag + etag: result.res.headers.etag, }; if ((options.headers && options.headers['x-oss-callback']) || options.callback) { @@ -94,7 +99,7 @@ proto.multipartUpload = async function multipartUpload(name, file, options = {}) fileSize, partSize, uploadId, - doneParts: [] + doneParts: [], }; if (options && options.progress) { @@ -136,14 +141,14 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { const content = await self._createBuffer(file, pi.start, pi.end); const data = { content, - size: pi.end - pi.start + size: pi.end - pi.start, }; let result; try { result = await self._uploadPart(name, uploadId, partNo, data, { timeout: options.timeout, - disabledMD5: options.disabledMD5 + disabledMD5: options.disabledMD5, }); } catch (error) { if (error.status === 404) { @@ -154,7 +159,7 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { if (!self.isCancel() && !multipartFinish) { checkpoint.doneParts.push({ number: partNo, - etag: result.res.headers.etag + etag: result.res.headers.etag, }); if (options.progress) { @@ -163,7 +168,7 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { resolve({ number: partNo, - etag: result.res.headers.etag + etag: result.res.headers.etag, }); } else { resolve(); @@ -184,8 +189,8 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { }; const all = Array.from(new Array(numParts), (x, i) => i + 1); - const done = internalDoneParts.map(p => p.number); - const todo = all.filter(p => done.indexOf(p) < 0); + const done = internalDoneParts.map((p) => p.number); + const todo = all.filter((p) => done.indexOf(p) < 0); const defaultParallel = 5; const parallel = options.parallel || defaultParallel; @@ -193,22 +198,23 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { const jobErr = await this._parallel( todo, parallel, - value => new Promise((resolve, reject) => { - uploadPartJob(that, value) - .then(result => { - if (result) { - internalDoneParts.push(result); - } - resolve(); - }) - .catch(err => { - reject(err); - }); - }) + (value) => + new Promise((resolve, reject) => { + uploadPartJob(that, value) + .then((result) => { + if (result) { + internalDoneParts.push(result); + } + resolve(); + }) + .catch((err) => { + reject(err); + }); + }), ); multipartFinish = true; - const abortEvent = jobErr.find(err => err.name === 'abort'); + const abortEvent = jobErr.find((err) => err.name === 'abort'); if (abortEvent) throw abortEvent; if (this.isCancel()) { @@ -341,7 +347,7 @@ proto._getPartSize = function _getPartSize(fileSize, partSize) { if (partSize < safeSize) { partSize = safeSize; console.warn( - `partSize has been set to ${partSize}, because the partSize you provided causes partNumber to be greater than 10,000` + `partSize has been set to ${partSize}, because the partSize you provided causes partNumber to be greater than 10,000`, ); } return partSize; @@ -357,7 +363,7 @@ proto._divideParts = function _divideParts(fileSize, partSize) { partOffs.push({ start, - end + end, }); } diff --git a/lib/common/client/initOptions.js b/lib/common/client/initOptions.js index 297a5924d..4e5ddba64 100644 --- a/lib/common/client/initOptions.js +++ b/lib/common/client/initOptions.js @@ -26,7 +26,7 @@ module.exports = function (options) { if (options.stsToken && !options.refreshSTSToken && !options.refreshSTSTokenInterval) { console.warn( "It's recommended to set 'refreshSTSToken' and 'refreshSTSTokenInterval' to refresh" + - ' stsToken、accessKeyId、accessKeySecret automatically when sts token has expired' + ' stsToken、accessKeyId、accessKeySecret automatically when sts token has expired', ); } if (options.bucket) { @@ -46,9 +46,10 @@ module.exports = function (options) { headerEncoding: 'utf-8', refreshSTSToken: null, refreshSTSTokenInterval: 60000 * 5, - retryMax: 0 + retryMax: 0, + multipartRunning: false, }, - options + options, ); opts.accessKeyId = opts.accessKeyId.trim(); diff --git a/lib/common/multipart.js b/lib/common/multipart.js index b46515dd0..d402b2bf8 100644 --- a/lib/common/multipart.js +++ b/lib/common/multipart.js @@ -27,10 +27,10 @@ proto.listUploads = async function listUploads(query, options) { if (!Array.isArray(uploads)) { uploads = [uploads]; } - uploads = uploads.map(up => ({ + uploads = uploads.map((up) => ({ name: up.Key, uploadId: up.UploadId, - initiated: up.Initiated + initiated: up.Initiated, })); return { @@ -39,7 +39,7 @@ proto.listUploads = async function listUploads(query, options) { bucket: result.data.Bucket, nextKeyMarker: result.data.NextKeyMarker, nextUploadIdMarker: result.data.NextUploadIdMarker, - isTruncated: result.data.IsTruncated === 'true' + isTruncated: result.data.IsTruncated === 'true', }; }; @@ -59,7 +59,7 @@ proto.listParts = async function listParts(name, uploadId, query, options) { const opt = {}; copy(options).to(opt); opt.subres = { - uploadId + uploadId, }; const params = this._objectRequestParams('GET', name, opt); params.query = query; @@ -77,7 +77,7 @@ proto.listParts = async function listParts(name, uploadId, query, options) { nextPartNumberMarker: result.data.NextPartNumberMarker, maxParts: result.data.MaxParts, isTruncated: result.data.IsTruncated, - parts: result.data.Part || [] + parts: result.data.Part || [], }; }; @@ -98,7 +98,7 @@ proto.abortMultipartUpload = async function abortMultipartUpload(name, uploadId, const result = await this.request(params); return { - res: result.res + res: result.res, }; }; @@ -127,7 +127,7 @@ proto.initMultipartUpload = async function initMultipartUpload(name, options) { res: result.res, bucket: result.data.Bucket, name: result.data.Key, - uploadId: result.data.UploadId + uploadId: result.data.UploadId, }; }; @@ -143,7 +143,7 @@ proto.initMultipartUpload = async function initMultipartUpload(name, options) { */ proto.uploadPart = async function uploadPart(name, uploadId, partNo, file, start, end, options) { const data = { - size: end - start + size: end - start, }; const isBrowserEnv = process && process.browser; isBrowserEnv @@ -171,7 +171,12 @@ proto.uploadPart = async function uploadPart(name, uploadId, partNo, file, start * key2: 'value2' * } */ -proto.completeMultipartUpload = async function completeMultipartUpload(name, uploadId, parts, options) { +proto.completeMultipartUpload = async function completeMultipartUpload( + name, + uploadId, + parts, + options, +) { const completeParts = parts .concat() .sort((a, b) => a.number - b.number) @@ -188,7 +193,7 @@ proto.completeMultipartUpload = async function completeMultipartUpload(name, upl options = options || {}; let opt = {}; - opt = deepCopyWith(options, _ => { + opt = deepCopyWith(options, (_) => { if (isBuffer(_)) return null; }); opt.subres = { uploadId }; @@ -208,12 +213,13 @@ proto.completeMultipartUpload = async function completeMultipartUpload(name, upl if (options.progress) { await options.progress(1, null, result.res); } + this.options.multipartRunning = false; const ret = { res: result.res, bucket: params.bucket, name, - etag: result.res.headers.etag + etag: result.res.headers.etag, }; if (params.headers && params.headers['x-oss-callback']) { @@ -236,12 +242,12 @@ proto._uploadPart = async function _uploadPart(name, uploadId, partNo, data, opt const opt = {}; copy(options).to(opt); opt.headers = { - 'Content-Length': data.size + 'Content-Length': data.size, }; opt.subres = { partNumber: partNo, - uploadId + uploadId, }; const params = this._objectRequestParams('PUT', name, opt); params.mime = opt.mime; @@ -254,7 +260,7 @@ proto._uploadPart = async function _uploadPart(name, uploadId, partNo, data, opt if (!result.res.headers.etag) { throw new Error( - 'Please set the etag of expose-headers in OSS \n https://help.aliyun.com/document_detail/32069.html' + 'Please set the etag of expose-headers in OSS \n https://help.aliyun.com/document_detail/32069.html', ); } if (data.stream) { @@ -264,6 +270,6 @@ proto._uploadPart = async function _uploadPart(name, uploadId, partNo, data, opt return { name, etag: result.res.headers.etag, - res: result.res + res: result.res, }; }; diff --git a/lib/common/parallel.js b/lib/common/parallel.js index 25224e83f..0317fa6ef 100644 --- a/lib/common/parallel.js +++ b/lib/common/parallel.js @@ -9,7 +9,7 @@ proto._parallelNode = async function _parallelNode(todo, parallel, fn, sourceDat let jobs = []; const tempBatch = todo.length / parallel; const remainder = todo.length % parallel; - const batch = remainder === 0 ? tempBatch : ((todo.length - remainder) / parallel) + 1; + const batch = remainder === 0 ? tempBatch : (todo.length - remainder) / parallel + 1; let taskIndex = 1; for (let i = 0; i < todo.length; i++) { if (that.isCancel()) { @@ -22,7 +22,7 @@ proto._parallelNode = async function _parallelNode(todo, parallel, fn, sourceDat jobs.push(fn(that, todo[i])); } - if (jobs.length === parallel || (taskIndex === batch && i === (todo.length - 1))) { + if (jobs.length === parallel || (taskIndex === batch && i === todo.length - 1)) { try { taskIndex += 1; /* eslint no-await-in-loop: [0] */ @@ -59,7 +59,7 @@ proto._parallel = function _parallel(todo, parallel, jobPromise) { let i = -1; const len = coll.length; return function next() { - return (++i < len && !that.isCancel()) ? { value: coll[i], key: i } : null; + return ++i < len && !that.isCancel() ? { value: coll[i], key: i } : null; }; } @@ -88,11 +88,13 @@ proto._parallel = function _parallel(todo, parallel, jobPromise) { } function iteratee(value, callback) { - jobPromise(value).then((result) => { - callback(null, result); - }).catch((err) => { - callback(err); - }); + jobPromise(value) + .then((result) => { + callback(null, result); + }) + .catch((err) => { + callback(err); + }); } function replenish() { @@ -125,13 +127,14 @@ proto._parallel = function _parallel(todo, parallel, jobPromise) { */ proto.cancel = function cancel(abort) { this.options.cancelFlag = true; + this.options.multipartRunning = false; if (isArray(this.multipartUploadStreams)) { - this.multipartUploadStreams.forEach(_ => { + this.multipartUploadStreams.forEach((_) => { if (_.destroyed === false) { const err = { name: 'cancel', - message: 'cancel' + message: 'cancel', }; _.destroy(err); } @@ -149,17 +152,19 @@ proto.isCancel = function isCancel() { proto.resetCancelFlag = function resetCancelFlag() { this.options.cancelFlag = false; + this.options.multipartRunning = true; }; proto._stop = function _stop() { this.options.cancelFlag = true; + this.options.multipartRunning = false; }; // cancel is not error , so create an object proto._makeCancelEvent = function _makeCancelEvent() { const cancelEvent = { status: 0, - name: 'cancel' + name: 'cancel', }; return cancelEvent; }; @@ -169,7 +174,7 @@ proto._makeAbortEvent = function _makeAbortEvent() { const abortEvent = { status: 0, name: 'abort', - message: 'upload task has been abort' + message: 'upload task has been abort', }; return abortEvent; }; diff --git a/lib/managed-upload.js b/lib/managed-upload.js index 6902444f0..527db1c0c 100644 --- a/lib/managed-upload.js +++ b/lib/managed-upload.js @@ -31,6 +31,11 @@ const proto = exports; * } */ proto.multipartUpload = async function multipartUpload(name, file, options) { + if (this.options.multipartRunning) { + console.warn( + 'multipartUpload is already executing, if you need to call more than one multipartUpload at the same time, please create more instances', + ); + } this.resetCancelFlag(); options = options || {}; if (options.checkpoint && options.checkpoint.uploadId) { @@ -62,7 +67,7 @@ proto.multipartUpload = async function multipartUpload(name, file, options) { res: result.res, bucket: this.options.bucket, name, - etag: result.res.headers.etag + etag: result.res.headers.etag, }; if ((options.headers && options.headers['x-oss-callback']) || options.callback) { @@ -90,7 +95,7 @@ proto.multipartUpload = async function multipartUpload(name, file, options) { fileSize, partSize, uploadId, - doneParts: [] + doneParts: [], }; if (options && options.progress) { @@ -125,7 +130,7 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { const stream = await self._createStream(file, pi.start, pi.end); const data = { stream, - size: pi.end - pi.start + size: pi.end - pi.start, }; if (isArray(self.multipartUploadStreams)) { @@ -150,7 +155,7 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { let result; try { result = await self._uploadPart(name, uploadId, partNo, data, { - timeout: options.timeout + timeout: options.timeout, }); } catch (error) { removeStreamFromMultipartUploadStreams(); @@ -162,7 +167,7 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { if (!self.isCancel()) { doneParts.push({ number: partNo, - etag: result.res.headers.etag + etag: result.res.headers.etag, }); checkpoint.doneParts = doneParts; @@ -180,20 +185,20 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { }, this.options.retryMax, { - errorHandler: err => { - const _errHandle = _err => { + errorHandler: (err) => { + const _errHandle = (_err) => { const statusErr = [-1, -2].includes(_err.status); const requestErrorRetryHandle = this.options.requestErrorRetryHandle || (() => true); return statusErr && requestErrorRetryHandle(_err); }; return !!_errHandle(err); - } - } + }, + }, ); const all = Array.from(new Array(numParts), (x, i) => i + 1); - const done = doneParts.map(p => p.number); - const todo = all.filter(p => done.indexOf(p) < 0); + const done = doneParts.map((p) => p.number); + const todo = all.filter((p) => done.indexOf(p) < 0); const defaultParallel = 5; const parallel = options.parallel || defaultParallel; @@ -211,16 +216,17 @@ proto._resumeMultipart = async function _resumeMultipart(checkpoint, options) { const jobErr = await this._parallel( todo, parallel, - value => new Promise((resolve, reject) => { - uploadPartJob(that, value) - .then(() => { - resolve(); - }) - .catch(reject); - }) + (value) => + new Promise((resolve, reject) => { + uploadPartJob(that, value) + .then(() => { + resolve(); + }) + .catch(reject); + }), ); - const abortEvent = jobErr.find(err => err.name === 'abort'); + const abortEvent = jobErr.find((err) => err.name === 'abort'); if (abortEvent) throw abortEvent; if (this.isCancel()) { @@ -339,12 +345,12 @@ proto._createStream = function _createStream(file, start, end) { read() { this.push(iterable); this.push(null); - } + }, }); } else if (is.string(file)) { return fs.createReadStream(file, { start, - end: end - 1 + end: end - 1, }); } throw new Error('_createStream requires Buffer/File/String.'); @@ -360,7 +366,7 @@ proto._getPartSize = function _getPartSize(fileSize, partSize) { if (partSize < safeSize) { partSize = safeSize; console.warn( - `partSize has been set to ${partSize}, because the partSize you provided causes partNumber to be greater than 10,000` + `partSize has been set to ${partSize}, because the partSize you provided causes partNumber to be greater than 10,000`, ); } return partSize; @@ -376,7 +382,7 @@ proto._divideParts = function _divideParts(fileSize, partSize) { partOffs.push({ start, - end + end, }); } diff --git a/package.json b/package.json index 1e6355c95..4b4520c7c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,9 @@ "tsc:build": "tsc -b tsconfig.json tsconfig-cjs.json", "tsc:watch": "tsc -b tsconfig.json tsconfig-cjs.json --watch", "tsc:clean": "tsc -b tsconfig.json tsconfig-cjs.json --clean ", - "prepare": "husky install" + "prepare": "husky install", + "f2elint-scan": "f2elint scan", + "f2elint-fix": "f2elint fix" }, "git-pre-hooks": { "pre-release": "npm run build-dist", @@ -72,11 +74,8 @@ "@babel/plugin-transform-runtime": "^7.11.5", "@babel/preset-env": "^7.11.5", "@babel/runtime": "^7.11.2", - "@commitlint/cli": "^16.2.4", "@commitlint/config-conventional": "^16.2.4", "@types/node": "^14.0.12", - "@typescript-eslint/eslint-plugin": "^2.34.0", - "@typescript-eslint/parser": "^2.34.0", "aliasify": "^2.0.0", "autod": "^2.6.1", "babelify": "^10.0.0", @@ -87,15 +86,10 @@ "core-js": "^3.6.5", "crypto-js": "^3.1.9-1", "dotenv": "^8.2.0", - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.2.1", - "eslint-config-ali": "^9.0.2", - "eslint-plugin-import": "^2.21.1", - "eslint-plugin-jsx-a11y": "^6.0.3", - "eslint-plugin-react": "^7.7.0", + "f2elint": "^2.2.1", "filereader": "^0.10.3", "git-pre-hooks": "^1.2.0", - "husky": "^7.0.4", + "husky": "^8.0.1", "immediate": "^3.3.0", "karma": "^6.3.4", "karma-browserify": "^5.1.1", @@ -108,6 +102,7 @@ "mm": "^2.0.0", "mocha": "^9.1.2", "nyc": "^15.1.0", + "prettier": "^2.7.1", "promise-polyfill": "^6.0.2", "puppeteer": "^10.4.0", "request": "^2.88.0", @@ -150,7 +145,12 @@ "lint-staged": { "**/!(dist)/*": [ "npm run detect-secrets --" - ], - "lib/**/*.js": "eslint --cache --fix" + ] + }, + "husky": { + "hooks": { + "pre-commit": "f2elint commit-file-scan", + "commit-msg": "f2elint commit-msg-scan" + } } } \ No newline at end of file