diff --git a/package.json b/package.json index 8d258fcf4f7..2f3e7828731 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,15 @@ "description": "", "main": "index.js", "dependencies": { + "@types/node": "^10.12.12", "chalk": "^2.4.1", - "pngjs": "^3.3.3" + "pngjs": "^3.3.3", + "ts-lint": "^4.5.1", + "ts-node": "^7.0.1", + "typescript": "^3.2.2" }, "scripts": { - "test": "node ./test/index.js" + "test": "ts-node ./test/index.ts" }, "repository": { "type": "git", diff --git a/test/index.js b/test/index.ts similarity index 71% rename from test/index.js rename to test/index.ts index 397918dcda2..228e87459e8 100644 --- a/test/index.js +++ b/test/index.ts @@ -1,6 +1,6 @@ -const fs = require('fs') -const PNG = require('pngjs').PNG -const chalk = require('chalk') +import * as fs from 'fs' +import * as pngjs from 'pngjs' +import chalk from 'chalk' const dateExp = /^\d{4}-\d{2}(-\d{2})?$/ @@ -44,73 +44,11 @@ const notice = (msg) => { console.log(chalk.yellow(msg)) } -const jsonFileNames = fs.readdirSync('./erc20') -const eosJsonFileNames = fs.readdirSync('./eos-token') -const imageFileNames = fs.readdirSync('./images') -const imageAddrs = imageFileNames.map(n => n.slice(0, 42)).filter(n => n.startsWith('0x')) -const lowerCaseImageAddrs =imageAddrs.map(x => x.toLowerCase()) -const jsonFileCheck = (jsonFileName, type) => { - const addr = jsonFileName.replace(jsonExp, '') - let prepath = '' - - if ( - (type === 'ETHEREUM' && !isEthAddress(addr)) || - (type === 'EOS' && !isEosToken(addr)) - ) { - exitWithMsg(`ERROR! json file name ${jsonFileName} is not like a ${type} address.json`) - } - - if (type === 'ETHEREUM') { - prepath = './erc20/' - } else if (type === 'EOS') { - prepath = './eos-token/' - } - - const content = fs.readFileSync(`${prepath}${addr}.json`).toString() - let obj = null - let parseErr = null - - if (content.indexOf('�') !== -1) { - exitWithMsg(`ERROR! json file name ${jsonFileName} must be utf-8 encoding`) - } - - try { - obj = JSON.parse(content) - } catch (e) { - parseErr = e - } - - if (parseErr) { - exitWithMsg(`ERROR! json file name ${jsonFileName} parse error, please check first (maybe has some unnecessary space or comma symbol like ",")`) - } - - if (!lowerCaseImageAddrs.includes(addr.toLowerCase())) { - notice(`Warning! dose not have ${addr + '.png'} in images dir, please check first`) - } else if (!imageAddrs.includes(obj.address)) { - const imgAddr = imageAddrs.find(imgad => { - return imgad.toLowerCase() === addr.toLowerCase() - }) - exitWithMsg(`Warning! ${imgAddr + '.png'} in images dir, that capital and small letter isn't quite the same with ${addr}`) - } - +const commonFieldCheck = (jsonFileName, obj) => { if (!obj.symbol) { exitWithMsg(`ERROR! json file ${jsonFileName} content must have symbol field`) } - if (!obj.address) { - exitWithMsg(`ERROR! json file ${jsonFileName} content must have address field`) - } - - if (!isEthAddress(obj.address)) { - exitWithMsg(`ERROR! json file ${jsonFileName} address field must be an ethereum address`) - } - - if (obj.address.toLowerCase() !== addr.toLowerCase()) { - exitWithMsg(`ERROR! json file ${jsonFileName} should be the same with address field ${obj.address}`) - } else if (obj.address !== addr) { - // exitWithMsg(`Warning! json file ${jsonFileName}, that capital and small letter isn't quite the same with object.address ${obj.address}`) - } - if (obj.published_on !== undefined) { if (obj.published_on.search(dateExp) === -1) { exitWithMsg(`ERROR! json file ${jsonFileName}'s published_on field ${obj.published_on} must be format of YYYY-MM-DD or YYYY-MM-DD`) @@ -124,7 +62,7 @@ const jsonFileCheck = (jsonFileName, type) => { } if (obj.overview !== undefined) { - if (!['zh', 'en'].some(k => isStringWithCharacter(obj.overview[k]))) { + if (!['zh', 'en'].some(k => !!isStringWithCharacter(obj.overview[k]))) { exitWithMsg(`ERROR! json file ${jsonFileName}'s overview field must have zh and en field, and must be a string (not empty)`) } } @@ -143,8 +81,8 @@ const jsonFileCheck = (jsonFileName, type) => { if (obj.initial_price !== undefined) { const keys = Object.keys(obj.initial_price) - if (keys.some(k => !['BTC', 'ETH', 'USD'].includes(k))) { - exitWithMsg(`ERROR! json file ${jsonFileName}'s initial_price field ${JSON.stringify(obj.initial_price)} only support BTC ETH USD`) + if (keys.some(k => !['BTC', 'ETH', 'USD', 'EOS'].includes(k))) { + exitWithMsg(`ERROR! json file ${jsonFileName}'s initial_price field ${JSON.stringify(obj.initial_price)} only support BTC ETH USD EOS`) } keys.forEach(k => { @@ -163,6 +101,101 @@ const jsonFileCheck = (jsonFileName, type) => { }) } +const getObjIfNoError = (jsonFileName, type) => { + const addr = jsonFileName.replace(jsonExp, '') + let prepath = '' + let parseErr = null + + if (type === 'ETHEREUM') { + prepath = './erc20/' + + if (!isEthAddress(addr)) { + exitWithMsg(`ERROR! json file name ${jsonFileName} is not like a ${type} address.json`) + } + } else if (type === 'EOS') { + prepath = './eos-token/' + + if (!isEosToken(addr)) { + exitWithMsg(`ERROR! json file name ${jsonFileName} is not like a ${type} account_name.json`) + } + } + + const content = fs.readFileSync(`${prepath}${addr}.json`).toString() + + if (content.indexOf('�') !== -1) { + exitWithMsg(`ERROR! json file name ${jsonFileName} must be utf-8 encoding`) + } + + try { + return JSON.parse(content) + } catch (e) { + parseErr = e + } + + if (parseErr) { + exitWithMsg(`ERROR! json file name ${jsonFileName} parse error, please check first (maybe has some unnecessary space or comma symbol like ",")`) + } +} + +const jsonFileNames = fs.readdirSync('./erc20') +const eosJsonFileNames = fs.readdirSync('./eos-token') +const imageFileNames = fs.readdirSync('./images') + +const jsonFileCheck = (jsonFileName, type) => { + const addr = jsonFileName.replace(jsonExp, '') + const imageAddrs = imageFileNames.map(n => n.slice(0, 42)).filter(n => { + return type === 'ETHEREUM' ? n.startsWith('0x') : (n.indexOf('@') !== -1) + }) + const lowerCaseImageAddrs =imageAddrs.map(x => x.toLowerCase()) + + let addressOrAccountname = '' + let obj = getObjIfNoError(jsonFileName, type) + + + if (type === 'ETHEREUM') { + addressOrAccountname = obj.address + } else if (type === 'EOS') { + addressOrAccountname = obj.account_name + } + + if (!lowerCaseImageAddrs.includes(addr.toLowerCase())) { + notice(`Warning! dose not have ${addr + '.png'} in images dir, please check first`) + } else if (!imageAddrs.includes(addressOrAccountname)) { + const imgAddr = imageAddrs.find(imgad => { + return imgad.toLowerCase() === addr.toLowerCase() + }) + exitWithMsg(`Warning! ${imgAddr + '.png'} in images dir, that capital and small letter isn't quite the same with ${addr}`) + } + + if (type === 'ETHEREUM') { + if (!addressOrAccountname) { + exitWithMsg(`ERROR! json file ${jsonFileName} content must have address field`) + } + if (!isEthAddress(addressOrAccountname)) { + exitWithMsg(`ERROR! json file ${jsonFileName} address field must be an ethereum address`) + } + if (addressOrAccountname.toLowerCase() !== addr.toLowerCase()) { + exitWithMsg(`ERROR! json file ${jsonFileName} should be the same with address field ${addressOrAccountname}`) + } else if (addressOrAccountname !== addr) { + // exitWithMsg(`Warning! json file ${jsonFileName}, that capital and small letter isn't quite the same with object.address ${obj.address}`) + } + } else if (type === 'EOS') { + if (!addressOrAccountname) { + exitWithMsg(`ERROR! json file ${jsonFileName} content must have acount_name field`) + } + if (!isEosToken(addressOrAccountname)) { + exitWithMsg(`ERROR! json file ${jsonFileName} account_name field must be an eos account name`) + } + if (addressOrAccountname.toLowerCase() !== addr.toLowerCase()) { + exitWithMsg(`ERROR! json file ${jsonFileName} should be the same with account_name field ${addressOrAccountname}`) + } else if (addressOrAccountname !== addr) { + // exitWithMsg(`Warning! json file ${jsonFileName}, that capital and small letter isn't quite the same with object.account_name ${obj.address}`) + } + } + + commonFieldCheck(jsonFileName, obj) +} + const jsonFileNameFilter = jsonFileName => { return jsonFileName !== '$template.json' && jsonFileName.endsWith('.json') } @@ -186,7 +219,7 @@ imageFileNames.forEach(n => { if (imgExp.test(n)) { fs.createReadStream(path) - .pipe(new PNG()).on('metadata', (metadata) => { + .pipe(new pngjs.PNG()).on('metadata', (metadata) => { if (metadata.width !== metadata.height) { notice(`${n} image width ${metadata.width} !== height ${metadata.height}`) } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..5bd89a298c3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es5", + "sourceMap": true, + "outDir": "lib", + "noImplicitThis": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "declaration": true, + "declarationDir": "lib", + "resolveJsonModule": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "baseUrl": "./", + "pretty": true, + "lib": [ + "es2017" + ] + }, + "include": [ + "./src/**/*" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000000..3079605e374 --- /dev/null +++ b/tslint.json @@ -0,0 +1,135 @@ +{ + "rules": { + "member-access": false, + "no-any": false, + "no-inferrable-types": [ + false + ], + "no-internal-module": true, + "no-var-requires": true, + "typedef": [ + false + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }, + { + "call-signature": "space", + "index-signature": "space", + "parameter": "space", + "property-declaration": "space", + "variable-declaration": "space" + } + ], + "ban": false, + "curly": false, + "forin": false, + "label-position": true, + "no-arg": true, + "no-bitwise": true, + "no-conditional-assignment": true, + "no-console": [ + false, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-eval": true, + "no-null-keyword": false, + "no-shadowed-variable": false, + "no-string-literal": true, + "no-switch-case-fall-through": true, + "no-unused-expression": [ + true, + "allow-fast-null-checks" + ], + "no-use-before-declare": true, + "no-var-keyword": true, + "radix": true, + "switch-default": true, + "triple-equals": [ + true, + "allow-undefined-check" + ], + "eofline": false, + "indent": [ + true, + "spaces" + ], + "max-line-length": [ + false, + 150 + ], + "no-require-imports": false, + "no-trailing-whitespace": true, + "object-literal-sort-keys": false, + "trailing-comma": [ + true, + { + "multiline": "always", + "singleline": "never" + } + ], + "align": [ + true + ], + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "interface-name": [ + false + ], + "jsdoc-format": false, + "no-consecutive-blank-lines": [ + true + ], + "no-parameter-properties": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-finally", + "check-whitespace" + ], + "quotemark": [ + true, + "single", + "jsx-double", + "avoid-escape" + ], + "semicolon": [ + true, + "never" + ], + "variable-name": [ + true, + "check-format", + "allow-pascal-case", + "allow-leading-underscore", + "ban-keywords" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} \ No newline at end of file