diff --git a/package.json b/package.json index f713eb4b..96ec2a51 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,9 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "@fehey/monaco-markdown": "^0.0.3", "@iktakahiro/markdown-it-katex": "^3.1.0", + "@octokit/rest": "^18.10.0", "@sentry/electron": "^1.2.0", "ant-design-vue": "^1.3.5", "axios": "^0.18.1", @@ -37,6 +39,7 @@ "junk": "^3.1.0", "less": "^3.9.0", "lowdb": "^1.0.0", + "ls-all": "^1.1.0", "macaddress": "^0.2.9", "markdown-it": "^8.4.2", "markdown-it-abbr": "^1.0.4", @@ -50,7 +53,6 @@ "markdown-it-sup": "^1.0.0", "markdown-it-toc-and-anchor": "^4.2.0", "moment": "^2.24.0", - "monaco-markdown": "^0.0.6", "node-ssh": "^6.0.0", "normalize-path": "^3.0.0", "prismjs": "^1.16.0", diff --git a/src/components/Main.vue b/src/components/Main.vue index 1a5cd9c3..12a62c19 100644 --- a/src/components/Main.vue +++ b/src/components/Main.vue @@ -53,7 +53,8 @@ - 🙁 {{ $t('syncError1') }} FAQ {{ $t('or') }} Issues {{ $t('syncError2') }} +
🙁 {{ $t('syncError1') }} FAQ {{ $t('or') }} Issues {{ $t('syncError2') }}
+
{{ syncErrorMessage }}
@@ -124,6 +125,8 @@ export default class App extends Vue { syncErrorModalVisible = false + syncErrorMessage = '' + updateModalVisible = false systemModalVisible = false @@ -260,6 +263,7 @@ export default class App extends Vue { ga.event('Publish', 'Publish - success', { evLabel: this.site.setting.domain }) } else { this.syncErrorModalVisible = true + this.syncErrorMessage = result.message ga.event('Publish', 'Publish - failed', { evLabel: this.site.setting.domain }) } @@ -532,4 +536,8 @@ export default class App extends Vue { padding: 16px 0; background: #fafafa; } + +.sync-error-message { + margin-top: 16px; +} diff --git a/src/components/MonacoMarkdownEditor/Index.vue b/src/components/MonacoMarkdownEditor/Index.vue index b74e6b8e..eb471cc2 100644 --- a/src/components/MonacoMarkdownEditor/Index.vue +++ b/src/components/MonacoMarkdownEditor/Index.vue @@ -10,7 +10,7 @@ import { Vue, Component, Prop, Watch, Model, } from 'vue-property-decorator' import * as monaco from 'monaco-editor' -import * as MonacoMarkdown from 'monaco-markdown' +import * as MonacoMarkdown from '@fehey/monaco-markdown' import theme from './theme' @Component diff --git a/src/server/events/deploy.ts b/src/server/events/deploy.ts index 7af33a9e..4f6cd14e 100644 --- a/src/server/events/deploy.ts +++ b/src/server/events/deploy.ts @@ -2,6 +2,7 @@ import { ipcMain, IpcMainEvent } from 'electron' import Deploy from '../deploy' import Renderer from '../renderer' import SftpDeploy from '../plugins/deploys/sftp' +import GitHubDeploy from '../plugins/deploys/github' export default class DeployEvents { constructor(appInstance: any) { @@ -9,6 +10,7 @@ export default class DeployEvents { const deploy = new Deploy(appInstance) const sftp = new SftpDeploy(appInstance) + const github = new GitHubDeploy(appInstance) const renderer = new Renderer(appInstance) ipcMain.removeAllListeners('site-publish') @@ -18,23 +20,28 @@ export default class DeployEvents { ipcMain.on('site-publish', async (event: IpcMainEvent, params: any) => { const client = ({ - 'github': deploy, + 'github': github, 'coding': deploy, 'sftp': sftp, } as any)[platform] // render + console.time('site-publish-render') + renderer.db.themeConfig.domain = renderer.db.setting.domain await renderer.renderAll() + console.timeEnd('site-publish-render') // publish + console.time('site-publish') const result = await client.publish() + console.timeEnd('site-publish') event.sender.send('site-published', result) }) ipcMain.on('remote-detect', async (event: IpcMainEvent, params: any) => { const client = ({ - 'github': deploy, + 'github': github, 'coding': deploy, 'sftp': sftp, } as any)[platform] diff --git a/src/server/plugins/deploys/github.ts b/src/server/plugins/deploys/github.ts new file mode 100644 index 00000000..37d66a02 --- /dev/null +++ b/src/server/plugins/deploys/github.ts @@ -0,0 +1,405 @@ +import { Octokit } from '@octokit/rest' +import list from 'ls-all' +import fs from 'fs-extra' +import moment from 'moment' +import path from 'path' +import crypto from 'crypto' +import normalizePath from 'normalize-path' +import Model from '../../model' + +export default class GitHubDeploy extends Model { + private octokit: Octokit + + private uploadedBlobs: any + + private filesToUpdate: number + + private filesUpdated: number + + constructor(appInstance: any) { + super(appInstance) + + this.octokit = new Octokit({ + auth: appInstance.db.setting.token, + }) + + this.uploadedBlobs = {} + + this.filesToUpdate = 0 + this.filesUpdated = 0 + } + + async remoteDetect() { + const result = { + success: true, + message: '', + } + + try { + const { setting } = this.db + + const res = await this.octokit.rest.git.getRef({ + owner: setting.username, + repo: setting.repository, + ref: `heads/${setting.branch}`, + }) + + if (res.status === 200) { + result.message = '[Server] remote detect success' + + return result + } + + result.success = false + result.message = '[Server] remote detect failed' + + return result + } catch (e) { + result.success = false + result.message = `[Server] remote detect failed: ${e.message}` + + return result + } + } + + async publish() { + const result = { + success: true, + message: '同步成功', + data: null, + } + + try { + const commitSHA = await this.getLatestSHA() + const treeSHA = await this.getTreeSHA(commitSHA) + const remoteTree = await this.getTreeData(treeSHA) + const trees = await this.listFolderFiles(remoteTree) + let finalTree = await this.getNewTreeBasedOnDiffs(trees.remoteTree, trees.localTree) + finalTree = await this.createBlobs(finalTree, false) + finalTree = await this.updateBlobsList(finalTree) + let sha = await this.createTree(finalTree) + sha = await this.createCommit(sha, commitSHA) + const res = await this.createReference(sha) + + console.log('✅ published!', res) + return result + } catch (e) { + result.success = false + result.message = `[Server] 同步失败: ${e.message}` + + return result + } + } + + async getLatestSHA() { + const { setting } = this.db + + const res = await this.octokit.rest.git.getRef({ + owner: setting.username, + repo: setting.repository, + ref: `heads/${setting.branch}`, + }) + + if (res.data && res.data.object) { + return res.data.object.sha + } + + return null + } + + async getTreeSHA(commitSHA: string | null) { + if (!commitSHA) return null + + const { setting } = this.db + + const res = await this.octokit.rest.git.getCommit({ + owner: setting.username, + repo: setting.repository, + commit_sha: commitSHA, + }) + + if (res.data && res.data.tree) { + return res.data.tree.sha + } + + return null + } + + async getTreeData(treeSHA: string | null) { + if (!treeSHA) return null + + const { setting } = this.db + + const res = await this.octokit.rest.git.getTree({ + owner: setting.username, + repo: setting.repository, + tree_sha: treeSHA, + }) + + if (res.data && res.data.tree) { + return res.data.tree + } + + return null + } + + async listFolderFiles(remoteTree: any) { + const outputDir = `${this.appDir}/output` + + return list([outputDir], { + recurse: true, + flatten: true, + }).then((files: any) => { + const localTree = files + .filter((file: any) => !file.mode.dir) + .filter((file: any) => !file.path.includes('.git')) + .map((file: any) => { + let calculatedHash = '' + let fileSize = fs.statSync(file.path).size + + if (!this.isBinaryFile(file.path)) { + const fileContent = fs.readFileSync(file.path) + fileSize = fileContent.length + calculatedHash = crypto.createHash('sha1') + .update(`blob ${fileSize}\0${fileContent}`) + .digest('hex') + } + + return { + fullPath: normalizePath(file.path), + path: normalizePath(path.relative(outputDir, file.path)), + mode: file.mode.exec ? '100755' : '100644', + type: 'blob', + size: fileSize, + sha: calculatedHash, + encoding: 'base64', + getBlob: false, + } + }) + .filter((file: any) => this.isNecessaryFile(file.path)) + return { + localTree: localTree, + remoteTree: remoteTree, + } + }) + } + + async getNewTreeBasedOnDiffs(remoteTree: any, localTree: any) { + this.filesToUpdate = 0 + this.filesUpdated = 0 + + for (const localFile of localTree) { + const remoteFile = this.findRemoteFile(localFile.path, remoteTree) + + if (remoteFile === false) { + localFile.getBlob = true + this.filesToUpdate += 1 + continue + } + + if (localFile.sha === false) { + if (remoteFile.size !== localFile.size) { + localFile.getBlob = true + this.filesToUpdate += 1 + continue + } + + localFile.sha = remoteFile.sha + continue + } + + if (localFile.sha !== remoteFile.sha) { + localFile.getBlob = true + this.filesToUpdate += 1 + continue + } + } + + return localTree + } + + async createBlobs(files: any, reuploadSession = false) { + const result = await this.getAPIRateLimit() + + if (result.remaining < this.filesToUpdate + 10) { + throw Error(`Your GitHub API request limit were exceed (${parseInt(`${result.remaining}`, 10)} requests left). Please wait till (${moment(parseInt(`${result.reset * 1000}`, 10)).format('MMMM Do YYYY, h:mm:ss a')} UTC) and then try again.`) + } + + const filesToUpdate = [] + + for (let i = 0; i < files.length; i++) { + const file = files[i] + + if (file.getBlob) { + filesToUpdate.push(i) + } + } + + const parallelOperations = 20 + + for (let i = 0; i < filesToUpdate.length; i += parallelOperations) { + const requests = [] + + for (let j = 0; j < parallelOperations; j++) { + const index = filesToUpdate[i + j] + + if (typeof index === 'number') { + let file = files[index] + requests.push(this.createBlob(file.fullPath).then((sha: any) => { + file = Object.assign({}, file, { + sha: sha, + getBlob: false, + }) + })) + } + } + + // eslint-disable-next-line no-await-in-loop + await Promise.all(requests) + } + + return files + } + + async createBlob(filePath: string) { + const fileContent = fs.readFileSync(filePath, { encoding: 'base64' }) + console.log(`[${new Date().toUTCString()}] CREATE BLOB: ${filePath}`) + + const { setting } = this.db + + const res = await this.octokit.git.createBlob({ + owner: setting.username, + repo: setting.repository, + encoding: 'base64', + content: fileContent, + }) + + if (res.data) { + this.uploadedBlobs[filePath] = res.data.sha + console.log(`[${new Date().toUTCString()}] CREATED BLOB: ${filePath} - ${res.data.sha}`) + + this.filesUpdated += 1 + + return res.data.sha + } + } + + updateBlobsList(files: any) { + let counterOfFilesToUpload = 0 + const output = files.map((file: any) => { + if (this.uploadedBlobs[file.fullPath]) { + file.sha = this.uploadedBlobs[file.fullPath] + file.getBlob = false + } + + if (file.getBlob) { + counterOfFilesToUpload++ + } + + return file + }) + + return output + } + + async createTree(tree: any) { + if (!tree || !tree.length) { + return [] + } + + const { setting } = this.db + + const res = await this.octokit.git.createTree({ + owner: setting.username, + repo: setting.repository, + tree, + }) + + return res.data.sha + } + + async createCommit(tree: any, parentSHA: any) { + if (!tree.length) { + return '' + } + + const { setting } = this.db + + const res = await this.octokit.git.createCommit({ + owner: setting.username, + repo: setting.repository, + message: `update from gridea: ${moment().format('YYYY-MM-DD HH:mm:ss')}`, + tree, + parents: [parentSHA], + }) + + return res.data.sha + } + + async createReference(sha: string) { + if (sha === '') { + return false + } + + const { setting } = this.db + + const res = await this.octokit.git.updateRef({ + owner: setting.username, + repo: setting.repository, + sha, + ref: `heads/${setting.branch}`, + }) + + return res + } + + async getAPIRateLimit() { + const res = await this.octokit.rest.rateLimit.get() + return res.data.resources.core + } + + isBinaryFile(fullPath: string) { + const extension = path.parse(fullPath).ext + const nonBinaryExtensions = [ + '.html', + '.htm', + '.xml', + '.json', + '.css', + '.js', + '.map', + '.svg', + ] + + if (nonBinaryExtensions.indexOf(extension) > -1) { + return false + } + + return true + } + + isNecessaryFile(filePath: string) { + const filename = path.parse(filePath).base + const unnecessaryFiles = [ + '.DS_Store', + 'thumbs.db', + '.git', + ] + + if (unnecessaryFiles.indexOf(filename) > -1) { + return false + } + + return true + } + + findRemoteFile(filePath: string, remoteTree: any) { + for (const remoteFile of remoteTree) { + if (remoteFile.path === filePath) { + return remoteFile + } + } + + return false + } +} diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts index 2816398f..d99e62e8 100644 --- a/src/shims-vue.d.ts +++ b/src/shims-vue.d.ts @@ -71,3 +71,5 @@ declare module 'vuedraggable' { export default draggableComponent } + +declare module 'ls-all' diff --git a/yarn.lock b/yarn.lock index a23001eb..a08da2f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -714,6 +714,14 @@ global-agent "^2.0.2" global-tunnel-ng "^2.7.1" +"@fehey/monaco-markdown@^0.0.3": + version "0.0.3" + resolved "http://bnpm.byted.org/@fehey/monaco-markdown/-/monaco-markdown-0.0.3.tgz#5d83c34efd13a04246dc86f475e75c2568a59af5" + integrity sha1-XYPDTv0ToEJG3Ib0dedcJWilmvU= + dependencies: + monaco-editor "^0.17.1" + string-similarity "^3.0.0" + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -772,6 +780,107 @@ version "1.1.3" resolved "http://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" +"@octokit/auth-token@^2.4.4": + version "2.4.5" + resolved "http://bnpm.byted.org/@octokit/auth-token/-/auth-token-2.4.5.tgz#568ccfb8cb46f36441fac094ce34f7a875b197f3" + integrity sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA== + dependencies: + "@octokit/types" "^6.0.3" + +"@octokit/core@^3.5.1": + version "3.5.1" + resolved "http://bnpm.byted.org/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b" + integrity sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw== + dependencies: + "@octokit/auth-token" "^2.4.4" + "@octokit/graphql" "^4.5.8" + "@octokit/request" "^5.6.0" + "@octokit/request-error" "^2.0.5" + "@octokit/types" "^6.0.3" + before-after-hook "^2.2.0" + universal-user-agent "^6.0.0" + +"@octokit/endpoint@^6.0.1": + version "6.0.12" + resolved "http://bnpm.byted.org/@octokit/endpoint/-/endpoint-6.0.12.tgz#3b4d47a4b0e79b1027fb8d75d4221928b2d05658" + integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA== + dependencies: + "@octokit/types" "^6.0.3" + is-plain-object "^5.0.0" + universal-user-agent "^6.0.0" + +"@octokit/graphql@^4.5.8": + version "4.8.0" + resolved "http://bnpm.byted.org/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" + integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg== + dependencies: + "@octokit/request" "^5.6.0" + "@octokit/types" "^6.0.3" + universal-user-agent "^6.0.0" + +"@octokit/openapi-types@^10.1.0": + version "10.1.0" + resolved "http://bnpm.byted.org/@octokit/openapi-types/-/openapi-types-10.1.0.tgz#43c2ce1ad0ad711869f0a366dfa04d48e06f2fa2" + integrity sha512-Nq5TMBwijRXco+Bm/Rq1n5maxxXsHLwd/Cm3lyNeOxbjyzAOSD0qmr4TwKCD4TN4rHZ7lq/tARuqSv/WJHF7IA== + +"@octokit/plugin-paginate-rest@^2.16.0": + version "2.16.0" + resolved "http://bnpm.byted.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.0.tgz#09dbda2e5fbca022e3cdf76b63618f7b357c9f0c" + integrity sha512-8YYzALPMvEZ35kgy5pdYvQ22Roz+BIuEaedO575GwE2vb/ACDqQn0xQrTJR4tnZCJn7pi8+AWPVjrFDaERIyXQ== + dependencies: + "@octokit/types" "^6.26.0" + +"@octokit/plugin-request-log@^1.0.4": + version "1.0.4" + resolved "http://bnpm.byted.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" + integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== + +"@octokit/plugin-rest-endpoint-methods@^5.9.0": + version "5.10.0" + resolved "http://bnpm.byted.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.10.0.tgz#8058acf408d518defa2dc59a46777adbcd7ee8e8" + integrity sha512-HiUZliq5wNg15cevJlTo9zDnPXAD0BMRhLxbRNPnq9J3HELKesDTOiou56ax2jC/rECUkK/uJTugrizYKSo/jg== + dependencies: + "@octokit/types" "^6.27.0" + deprecation "^2.3.1" + +"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": + version "2.1.0" + resolved "http://bnpm.byted.org/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677" + integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg== + dependencies: + "@octokit/types" "^6.0.3" + deprecation "^2.0.0" + once "^1.4.0" + +"@octokit/request@^5.6.0": + version "5.6.1" + resolved "http://bnpm.byted.org/@octokit/request/-/request-5.6.1.tgz#f97aff075c37ab1d427c49082fefeef0dba2d8ce" + integrity sha512-Ls2cfs1OfXaOKzkcxnqw5MR6drMA/zWX/LIS/p8Yjdz7QKTPQLMsB3R+OvoxE6XnXeXEE2X7xe4G4l4X0gRiKQ== + dependencies: + "@octokit/endpoint" "^6.0.1" + "@octokit/request-error" "^2.1.0" + "@octokit/types" "^6.16.1" + is-plain-object "^5.0.0" + node-fetch "^2.6.1" + universal-user-agent "^6.0.0" + +"@octokit/rest@^18.10.0": + version "18.10.0" + resolved "http://bnpm.byted.org/@octokit/rest/-/rest-18.10.0.tgz#8a0add9611253e0e31d3ed5b4bc941a3795a7648" + integrity sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw== + dependencies: + "@octokit/core" "^3.5.1" + "@octokit/plugin-paginate-rest" "^2.16.0" + "@octokit/plugin-request-log" "^1.0.4" + "@octokit/plugin-rest-endpoint-methods" "^5.9.0" + +"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.26.0", "@octokit/types@^6.27.0": + version "6.27.0" + resolved "http://bnpm.byted.org/@octokit/types/-/types-6.27.0.tgz#2ffcd4d1cf344285f4151978c6fd36a2edcdf922" + integrity sha512-ha27f8DToxXBPEJdzHCCuqpw7AgKfjhWGdNf3yIlBAhAsaexBXTfWw36zNSsncALXGvJq4EjLy1p3Wz45Aqb4A== + dependencies: + "@octokit/openapi-types" "^10.1.0" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "http://registry.npm.taobao.org/@samverschueren/stream-to-observable/download/@samverschueren/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -2065,6 +2174,11 @@ array-filter@~0.0.0: version "0.0.1" resolved "http://registry.npm.taobao.org/array-filter/download/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" +array-find-index@^1.0.1: + version "1.0.2" + resolved "http://bnpm.byted.org/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + array-find@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8" @@ -2332,6 +2446,11 @@ bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: dependencies: tweetnacl "^0.14.3" +before-after-hook@^2.2.0: + version "2.2.2" + resolved "http://bnpm.byted.org/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" + integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== + bfj@^6.1.1: version "6.1.1" resolved "http://registry.npm.taobao.org/bfj/download/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48" @@ -2833,6 +2952,19 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "http://bnpm.byted.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "http://bnpm.byted.org/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + camelcase@^5.0.0: version "5.0.0" resolved "http://registry.npm.taobao.org/camelcase/download/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" @@ -3211,6 +3343,11 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.2" +colors@^1.1.2: + version "1.4.0" + resolved "http://bnpm.byted.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha1-xQSRR51MG9rtLJztMs98fcI2D3g= + colors@~1.1.2: version "1.1.2" resolved "http://registry.npm.taobao.org/colors/download/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -3763,6 +3900,13 @@ current-script-polyfill@^1.0.0: resolved "https://registry.yarnpkg.com/current-script-polyfill/-/current-script-polyfill-1.0.0.tgz#f31cf7e4f3e218b0726e738ca92a02d3488ef615" integrity sha1-8xz35PPiGLBybnOMqSoC00iO9hU= +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "http://bnpm.byted.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + custom-event-polyfill@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz#9bc993ddda937c1a30ccd335614c6c58c4f87aee" @@ -3816,9 +3960,10 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -decamelize@^1.2.0: +decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" - resolved "http://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + resolved "http://bnpm.byted.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decode-uri-component@^0.2.0: version "0.2.0" @@ -3953,6 +4098,11 @@ depd@~1.1.2: version "1.1.2" resolved "http://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" +deprecation@^2.0.0, deprecation@^2.3.1: + version "2.3.1" + resolved "http://bnpm.byted.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" + integrity sha1-Y2jL20Cr8zc7UlrIfkomDDpwCRk= + des.js@^1.0.0: version "1.0.0" resolved "http://registry.npm.taobao.org/des.js/download/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" @@ -5442,6 +5592,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "http://registry.npm.taobao.org/get-own-enumerable-property-symbols/download/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" integrity sha1-uHe0mlwWrvrDZV8u0upbaE340gM= +get-stdin@^4.0.1: + version "4.0.1" + resolved "http://bnpm.byted.org/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + get-stdin@^6.0.0: version "6.0.0" resolved "http://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -6087,6 +6242,13 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "http://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +indent-string@^2.1.0: + version "2.1.0" + resolved "http://bnpm.byted.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + indent-string@^3.0.0: version "3.2.0" resolved "http://registry.npm.taobao.org/indent-string/download/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -6356,6 +6518,11 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "http://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" +is-finite@^1.0.0: + version "1.1.0" + resolved "http://bnpm.byted.org/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "http://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -6470,6 +6637,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-plain-object@^5.0.0: + version "5.0.0" + resolved "http://bnpm.byted.org/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-promise@^2.1.0: version "2.1.0" resolved "http://registry.npm.taobao.org/is-promise/download/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -6521,6 +6693,11 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "http://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" +is-utf8@^0.2.0: + version "0.2.1" + resolved "http://bnpm.byted.org/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + is-windows@^1.0.2: version "1.0.2" resolved "http://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -6973,6 +7150,17 @@ listr@^0.14.2: p-map "^2.0.0" rxjs "^6.3.3" +load-json-file@^1.0.0: + version "1.1.0" + resolved "http://bnpm.byted.org/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" @@ -7138,6 +7326,14 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +loud-rejection@^1.0.0: + version "1.6.0" + resolved "http://bnpm.byted.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + lowdb@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowdb/-/lowdb-1.0.0.tgz#5243be6b22786ccce30e50c9a33eac36b20c8064" @@ -7180,6 +7376,15 @@ lru_map@^0.3.3: resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= +ls-all@^1.1.0: + version "1.1.0" + resolved "http://bnpm.byted.org/ls-all/-/ls-all-1.1.0.tgz#c3fd4f539cd84e0be6bc9de5bf41b8bd93b62786" + integrity sha1-w/1PU5zYTgvmvJ3lv0G4vZO2J4Y= + dependencies: + colors "^1.1.2" + meow "^3.7.0" + tree-flatten "^1.0.0" + luxon@^1.3.3: version "1.12.1" resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.12.1.tgz#924bd61404f70b0cc5168918cb0ac108e52aacc4" @@ -7221,6 +7426,11 @@ map-cache@^0.2.2: version "0.2.2" resolved "http://registry.npm.taobao.org/map-cache/download/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "http://bnpm.byted.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + map-visit@^1.0.0: version "1.0.0" resolved "http://registry.npm.taobao.org/map-visit/download/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -7350,6 +7560,22 @@ memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" +meow@^3.7.0: + version "3.7.0" + resolved "http://bnpm.byted.org/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + merge-descriptors@1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -7486,15 +7712,15 @@ minimist@0.0.8: version "0.0.8" resolved "http://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" +minimist@^1.1.3, minimist@^1.2.5: + version "1.2.5" + resolved "http://bnpm.byted.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI= + minimist@^1.2.0: version "1.2.0" resolved "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - minimisted@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/minimisted/-/minimisted-2.0.0.tgz#5e3295e74ed701b1cbeaa863a888181d6efbe8ce" @@ -7604,14 +7830,6 @@ monaco-editor@^0.17.1: resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.17.1.tgz#8fbe96ca54bfa75262706e044f8f780e904aa45c" integrity sha512-JAc0mtW7NeO+0SwPRcdkfDbWLgkqL9WfP1NbpP9wNASsW6oWqgZqNIWt4teymGjZIXTElx3dnQmUYHmVrJ7HxA== -monaco-markdown@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/monaco-markdown/-/monaco-markdown-0.0.6.tgz#1da655869fc3deeb3336c3076864a20e613b146e" - integrity sha512-y5gXvnyGfry6e8RsHUtQBiYjvSM7wU55qa0wrwmL2A2QMZMtzNVdZ3kMxw9lYGRbpB9a1LtsUys7zooi2MoeqQ== - dependencies: - monaco-editor "^0.17.1" - string-similarity "^3.0.0" - move-concurrently@^1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -7738,6 +7956,11 @@ node-emoji@^1.8.1: dependencies: lodash.toarray "^4.4.0" +node-fetch@^2.6.1: + version "2.6.1" + resolved "http://bnpm.byted.org/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -7913,9 +8136,9 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-package-data@^2.5.0: +normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + resolved "http://bnpm.byted.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -8481,6 +8704,15 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "http://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" +path-type@^1.0.0: + version "1.1.0" + resolved "http://bnpm.byted.org/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -9438,6 +9670,14 @@ read-config-file@5.0.1: json5 "^2.1.1" lazy-val "^1.0.4" +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "http://bnpm.byted.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -9446,6 +9686,15 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" +read-pkg@^1.0.0: + version "1.1.0" + resolved "http://bnpm.byted.org/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" @@ -9547,6 +9796,14 @@ readdirp@^3.1.1: dependencies: picomatch "^2.0.4" +redent@^1.0.0: + version "1.0.0" + resolved "http://bnpm.byted.org/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + reduce-css-calc@^2.1.6: version "2.1.7" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.7.tgz#1ace2e02c286d78abcd01fd92bfe8097ab0602c2" @@ -9700,6 +9957,13 @@ repeat-string@^1.6.1: version "1.6.1" resolved "http://registry.npm.taobao.org/repeat-string/download/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +repeating@^2.0.0: + version "2.0.1" + resolved "http://bnpm.byted.org/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + request-promise-core@1.1.2: version "1.1.2" resolved "http://registry.npm.taobao.org/request-promise-core/download/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" @@ -10777,6 +11041,13 @@ strip-bom-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" +strip-bom@^2.0.0: + version "2.0.0" + resolved "http://bnpm.byted.org/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -10791,6 +11062,13 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-indent@^1.0.1: + version "1.0.1" + resolved "http://bnpm.byted.org/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "http://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -11201,6 +11479,16 @@ transliteration@^1.6.6: dependencies: yargs "^12.0.1" +tree-flatten@^1.0.0: + version "1.0.0" + resolved "http://bnpm.byted.org/tree-flatten/-/tree-flatten-1.0.0.tgz#b5d4096c62775bceac8489937cfbe20dec756b5d" + integrity sha1-tdQJbGJ3W86shImTfPviDex1a10= + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "http://bnpm.byted.org/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + trim-right@^1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/trim-right/download/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -11407,6 +11695,11 @@ unique-string@^1.0.0: dependencies: crypto-random-string "^1.0.0" +universal-user-agent@^6.0.0: + version "6.0.0" + resolved "http://bnpm.byted.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" + integrity sha1-M4H4UDslHA2c0hvB3pOeyd9UgO4= + universalify@^0.1.0: version "0.1.2" resolved "http://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"