diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7f555378bc70b2cc3babcca2b80d8e6d65efabd8..0000000000000000000000000000000000000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: node_js - -node_js: - - "8" - -env: - matrix: - - TEST_TYPE=lint - - TEST_TYPE=build - - TEST_TYPE=test-all - - TEST_TYPE=test-dist - -addons: - apt: - packages: - - xvfb - -install: - - export DISPLAY=':99.0' - - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - - npm install - -script: - - | - if [ "$TEST_TYPE" = lint ]; then - npm run lint - elif [ "$TEST_TYPE" = build ]; then - npm run build - elif [ "$TEST_TYPE" = test-all ]; then - npm run test:all - elif [ "$TEST_TYPE" = test-dist ]; then - npm run site - mv dist/* ./ - php -S localhost:8000 & - DEBUG=* npm test .e2e.js - fi diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 22ae1886fd47d6336b59621b4060f1803c295582..0000000000000000000000000000000000000000 --- a/appveyor.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Test against the latest version of this Node.js version -environment: - nodejs_version: "8" - -# this is how to allow failing jobs in the matrix -matrix: - fast_finish: true # set this flag to immediately finish build once one of the jobs fails. - -# Install scripts. (runs after repo cloning) -install: - # Get the latest stable version of Node.js or io.js - - ps: Install-Product node $env:nodejs_version - # install modules - - npm install - # Output useful info for debugging. - - node --version - - npm --version - -# Post-install test scripts. -test_script: - - npm run lint - - npm run test:all - - npm run build - -# Don't actually build. -build: off diff --git a/functions/index.js b/functions/index.js index 2cc917cef640090f54b3941df832a35599c8db0c..f4c65f902973e024bc6cff8edf9a6c34a9ca4310 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1,44 +1,9 @@ // [START functionsimport] const functions = require('firebase-functions'); const express = require('express'); -const mock = require('./mock/index'); - +const matchMock = require('./matchMock'); const app = express(); -const sendData = (body, req, res) => { - if (!body) { - res.send('test'); - return ''; - } - if (typeof body === 'function') { - body(req, res); - } - res.send(body); -}; -app.get('/api', (req, res) => { - const html = Object.keys(mock).map(url => { - const href = url.split(' /')[1]; - return `
  • ${url}
  • `; - }); - res.send(``); -}); -app.get('/', (req, res) => { - res.send(``); -}); - -Object.keys(mock).forEach(url => { - const body = mock[url]; - const urlParams = url.split(' '); - const path = urlParams[1]; - const send = (req, res) => { - sendData(body, req, res); - }; - if (urlParams[0] === 'GET') { - app.get(path, send); - } - if (urlParams[0] === 'POST') { - app.post(path, send); - } -}); +app.use(matchMock); exports.api = functions.https.onRequest(app); diff --git a/functions/matchMock.js b/functions/matchMock.js new file mode 100644 index 0000000000000000000000000000000000000000..4ef7ae890c89a6233a145c127587c9bef7d86078 --- /dev/null +++ b/functions/matchMock.js @@ -0,0 +1,117 @@ +const mockFile = require('./mock/index'); +const pathToRegexp = require('path-to-regexp'); +const debug = console.log; +const bodyParser = require('body-parser'); + +const BODY_PARSED_METHODS = ['post', 'put', 'patch']; + +function parseKey(key) { + let method = 'get'; + let path = key; + if (key.indexOf(' ') > -1) { + const splited = key.split(' '); + method = splited[0].toLowerCase(); + path = splited[1]; // eslint-disable-line + } + return { + method, + path, + }; +} + +function createHandler(method, path, handler) { + return function(req, res, next) { + if (BODY_PARSED_METHODS.includes(method)) { + bodyParser.json({ limit: '5mb', strict: false })(req, res, () => { + bodyParser.urlencoded({ limit: '5mb', extended: true })(req, res, () => { + sendData(); + }); + }); + } else { + sendData(); + } + + function sendData() { + if (typeof handler === 'function') { + handler(req, res, next); + } else { + res.json(handler); + } + } + }; +} + +function normalizeConfig(config) { + return Object.keys(config).reduce((memo, key) => { + const handler = config[key]; + const { method, path } = parseKey(key); + const keys = []; + const re = pathToRegexp(path, keys); + memo.push({ + method, + path, + re, + keys, + handler: createHandler(method, path, handler), + }); + return memo; + }, []); +} + +const mockData = normalizeConfig(mockFile); + +function matchMock(req) { + const { path: exceptPath } = req; + const exceptMethod = req.method.toLowerCase(); + for (const mock of mockData) { + const { method, re, keys } = mock; + if (method === exceptMethod) { + const match = re.exec(req.path); + if (match) { + const params = {}; + + for (let i = 1; i < match.length; i = i + 1) { + const key = keys[i - 1]; + const prop = key.name; + const val = decodeParam(match[i]); + + if (val !== undefined || !hasOwnProperty.call(params, prop)) { + params[prop] = val; + } + } + req.params = params; + return mock; + } + } + } + + function decodeParam(val) { + if (typeof val !== 'string' || val.length === 0) { + return val; + } + + try { + return decodeURIComponent(val); + } catch (err) { + if (err instanceof URIError) { + err.message = `Failed to decode param ' ${val} '`; + err.status = err.statusCode = 400; + } + + throw err; + } + } + + return mockData.filter(({ method, re }) => { + return method === exceptMethod && re.test(exceptPath); + })[0]; +} +module.exports = (req, res, next) => { + const match = matchMock(req); + if (match) { + debug(`mock matched: [${match.method}] ${match.path}`); + return match.handler(req, res, next); + } else { + return next(); + } +}; diff --git a/functions/package.json b/functions/package.json index aaa103a4ed9a0be3cc0c6dd8d01dfe2d6a33dfa6..48fc22d5e62f3cef79f78206844c4c441e78dc86 100644 --- a/functions/package.json +++ b/functions/package.json @@ -2,19 +2,22 @@ "name": "functions", "description": "Cloud Functions for Firebase", "scripts": { - "serve": "firebase serve --only functions", + "serve": "npm run mock && firebase serve --only functions", "shell": "firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", - "mock": "cd ../scripts && rollup -c" + "mock": "node ../scripts/generateMock.js" }, "dependencies": { + "body-parser": "^1.18.3", "express": "^4.16.3", "firebase-admin": "^5.12.1", "firebase-functions": "^1.1.0", "mockjs": "^1.0.1-beta3", - "moment": "^2.22.2" + "moment": "^2.22.2", + "path-to-regexp": "^2.2.1", + "@babel/runtime": "7.0.0-beta.46" }, "private": true } diff --git a/package.json b/package.json index f18cc60d15646dab0b2ac19d7a3bf0b1ac3875ec..36258d7bc6a0707ede7177b1947caf39000534bb 100755 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "precommit": "npm run lint-staged", - "presite": "cd functions && npm install", + "presite": "npm run generate-mock && cd functions && npm install", "start": "cross-env ESLINT=none umi dev", "start:no-mock": "cross-env MOCK=none ESLINT=none umi dev", "build": "cross-env ESLINT=none umi build", @@ -17,6 +17,7 @@ "lint-staged": "lint-staged", "lint-staged:js": "eslint --ext .js", "test": "umi test", + "generate-mock": "node ./scripts/generateMock.js", "test:component": "umi test ./src/components", "test:all": "node ./tests/run-tests.js", "prettier": "prettier --write ./src/**/**/**/*" @@ -24,7 +25,6 @@ "dependencies": { "@antv/data-set": "^0.8.0", "antd": "^3.7.0", - "antd-pro-merge-less": "^0.0.1", "bizcharts": "^3.1.10", "bizcharts-plugin-slider": "^2.0.3", "classnames": "^2.2.6", @@ -43,8 +43,6 @@ "react-document-title": "^2.0.3", "react-fittext": "^1.0.0", "rollbar": "^2.4.2", - "rollup": "^0.62.0", - "rollup-plugin-json": "^3.0.0", "setprototypeof": "^1.1.0", "umi-plugin-locale": "^1.0.1", "url-polyfill": "^1.0.13" @@ -53,6 +51,7 @@ "@babel/polyfill": "^7.0.0-beta.53", "@types/react": "^16.4.4", "@types/react-dom": "^16.0.6", + "antd-pro-merge-less": "^0.0.1", "antd-theme-webpack-plugin": "^1.0.8", "babel-eslint": "^8.2.6", "babel-plugin-dva-hmr": "^0.4.1", @@ -78,6 +77,7 @@ "husky": "^0.14.3", "lint-staged": "^7.2.0", "mockjs": "^1.0.1-beta3", + "merge-umi-mock-data": "^0.0.2", "prettier": "1.13.7", "pro-download": "^1.0.1", "redbox-react": "^1.5.0", diff --git a/scripts/all_mock.js b/scripts/all_mock.js deleted file mode 100644 index 98975684d319f6dda91d082de177d2cb1844021e..0000000000000000000000000000000000000000 --- a/scripts/all_mock.js +++ /dev/null @@ -1,33 +0,0 @@ -import api from '../mock/api'; -import chart from '../mock/chart'; -import geographic from '../mock/geographic'; -import notices from '../mock/notices'; -import profile from '../mock/profile'; -import rule from '../mock/rule'; -import user from '../mock/user'; - -const data = {}; -Object.keys(api).forEach(key => { - data[key] = api[key]; -}); -Object.keys(chart).forEach(key => { - data[key] = chart[key]; -}); - -Object.keys(geographic).forEach(key => { - data[key] = geographic[key]; -}); -Object.keys(notices).forEach(key => { - data[key] = notices[key]; -}); -Object.keys(profile).forEach(key => { - data[key] = profile[key]; -}); -Object.keys(rule).forEach(key => { - data[key] = rule[key]; -}); -Object.keys(user).forEach(key => { - data[key] = user[key]; -}); - -export default data; diff --git a/scripts/generateMock.js b/scripts/generateMock.js new file mode 100644 index 0000000000000000000000000000000000000000..54c7d6d624fcefd98cec3600538284a5056910a7 --- /dev/null +++ b/scripts/generateMock.js @@ -0,0 +1,3 @@ +const generateMock = require('merge-umi-mock-data'); +const path = require('path'); +generateMock(path.join(__dirname, '../mock'), path.join(__dirname, '../functions/mock/index.js')); diff --git a/scripts/rollup.config.js b/scripts/rollup.config.js deleted file mode 100644 index 98d49541b277b67697de4f52a2e8b04aee0a12c8..0000000000000000000000000000000000000000 --- a/scripts/rollup.config.js +++ /dev/null @@ -1,16 +0,0 @@ -import json from 'rollup-plugin-json'; -// rollup.config.js -export default { - input: './all_mock.js', - output: { - file: '../functions/mock/index.js', - format: 'umd', - name: 'mock', - }, - plugins: [ - json({ - preferConst: true, // Default: false - indent: ' ', - }), - ], -}; diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.js index bff034a92926dad016ad86e241fc158ea132541d..9cc347fe4242f4736ac81f8422c40ae4da8453fc 100644 --- a/src/components/GlobalHeader/RightContent.js +++ b/src/components/GlobalHeader/RightContent.js @@ -98,7 +98,7 @@ export default class GlobalHeaderRight extends PureComponent { Ant Design Pro - + +
    - +