UNPKG

@gaoding/gd-tracker

Version:

Gaoding tracker for sensorsdata(sa), baidu(_hmt), Growing.IO(gio)

450 lines (449 loc) 18.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { server: function() { return server; }, default: function() { return _default; } }); var _express = /*#__PURE__*/ _interopRequireDefault(require("express")); var _cliColor = /*#__PURE__*/ _interopRequireDefault(require("cli-color")); var _bodyParser = /*#__PURE__*/ _interopRequireDefault(require("body-parser")); var _cors = /*#__PURE__*/ _interopRequireDefault(require("cors")); var _lodash = /*#__PURE__*/ _interopRequireWildcard(require("lodash")); var _isEmpty = require("../utils/is-empty"); var _changeCase = require("change-case"); var _first2Up = require("../utils/first-2-up"); var _index = require("../constants/index"); var _axios = /*#__PURE__*/ _interopRequireDefault(require("axios")); function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i]; return arr2; } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for(var key in obj){ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _objectSpread(target) { for(var i = 1; i < arguments.length; i++){ var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty(target, key, source[key]); }); } return target; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function(sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpreadProps(target, source) { source = source != null ? source : {}; if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function(key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for(i = 0; i < sourceSymbolKeys.length; i++){ key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for(i = 0; i < sourceKeys.length; i++){ key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } var _typeof = function(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }; function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } var VALIDATE_TYPE = { EVENT_VALIDATE: "EVENT_VALIDATE", PROPS_VALIDATE: "PROPS_VALIDATE", USER_VALIDATE: "USER_VALIDATE" }; var DEFAULT_OPTION = { port: _index.DEFAULT_VALIDATOR_SERVER_PORT, schemas: [] }; var createError = function(param) { var field = param.field, event = param.event, event_id = param.event_id, func_name = param.func_name, type_name = param.type_name, _event_desc = param.event_desc, event_desc = _event_desc === void 0 ? null : _event_desc, _field_desc = param.field_desc, field_desc = _field_desc === void 0 ? null : _field_desc, isError = param.isError, path = param.path, validateType = param.validateType, _detail_url = param.detail_url, detail_url = _detail_url === void 0 ? "" : _detail_url, _message = param.message, message = _message === void 0 ? [] : _message; return { event: event, func_name: func_name, type_name: type_name, event_desc: event_desc, field_desc: field_desc, event_id: event_id, field: field, isError: isError, path: path, validateType: validateType, detail_url: detail_url, message: message ? message : [] }; }; // 计算事件的必要信息 var calcEventInfo = function(option, schema) { var event_id = _lodash.default.get(option, "data.event_id", null); var event = _lodash.default.get(option, "data.event", null); var is_void_event_id = !schema.find(function(item) { return event_id === item.id; }); var is_void_event = !schema.find(function(item) { return event === item.n; }); return { event_id: event_id, event: event, is_void_event_id: is_void_event_id, is_void_event: is_void_event }; }; // 验证字段类型 var validateType = function(field, type, value) { var RAW_TYPE = _index.TYPE_TO_TYPE[field.tp]; var isArrayType = type === "array"; if (!isArrayType) return RAW_TYPE === type; var isStrings = field.tp === _index.TYPE_TO_TYPE["array/string"]; var isNumbers = field.tp === _index.TYPE_TO_TYPE["array/integer"]; if (value.length === 0) return true; if (isStrings) return value.every(function(item) { return typeof item === "string"; }); if (isNumbers) return value.every(function(item) { return typeof item === "number"; }); }; // 验证事件信息是否有效: 验证事件 ID 和 事件名 var validateEvent = function(data, schema) { var ref = calcEventInfo(data, schema), event_id = ref.event_id, event = ref.event, is_void_event_id = ref.is_void_event_id, is_void_event = ref.is_void_event; return [ createError({ event: event, event_id: event_id, field: "event_id", path: "/data/event_id", isError: is_void_event_id, validateType: VALIDATE_TYPE.EVENT_VALIDATE, func_name: "unknown", type_name: "unknown", event_desc: null, field_desc: null, detail_url: "", message: is_void_event_id ? [ "[事件参数错误] 无效的 事件 ID: ".concat(event_id) ] : [] }), createError({ event: event, event_id: event_id, field: "event", path: "/data/event", isError: is_void_event, validateType: VALIDATE_TYPE.EVENT_VALIDATE, func_name: "unknown", type_name: "unknown", event_desc: null, field_desc: null, detail_url: "", message: is_void_event ? [ "[事件参数错误] 无效的 事件名称: ".concat(event) ] : [] }) ]; }; // 验证用户参数是否有效 var validateUser = function(data, schema) { var ref = calcEventInfo(data, schema), event_id = ref.event_id, event = ref.event; var basic = Object.assign({}, data); var common = Object.assign({}, basic.data); var is_void_user_id = (0, _isEmpty.isEmpty)(common.user_id); var is_void_is_login = (0, _isEmpty.isEmpty)(common.is_login); var user_id = _lodash.default.get(basic, "data.user_id"); var is_login = _lodash.default.get(basic, "data.is_login"); var user_id_type = typeof user_id === "undefined" ? "undefined" : _typeof(user_id); var is_login_type = typeof is_login === "undefined" ? "undefined" : _typeof(is_login); var is_user_id_type_error = user_id_type !== "string"; var is_is_login_type_error = is_login_type !== "number"; return [ createError({ event: event, event_id: event_id, field: "user_id", path: "/data/user_id", isError: is_void_user_id || is_user_id_type_error, validateType: VALIDATE_TYPE.USER_VALIDATE, func_name: "unknown", type_name: "unknown", event_desc: null, field_desc: null, detail_url: "", message: !is_void_user_id && !is_user_id_type_error ? [] : [ is_void_user_id && "[用户参数错误] 无效的 user_id: ".concat(user_id), is_user_id_type_error && "[用户参数错误] user_id 期望类型为: string; 实际类型为: ".concat(user_id_type) ].filter(Boolean) }), createError({ event: event, event_id: event_id, field: "event", path: "/data/is_login", isError: is_void_is_login || is_is_login_type_error, validateType: VALIDATE_TYPE.USER_VALIDATE, func_name: "unknown", type_name: "unknown", event_desc: null, field_desc: null, detail_url: "", message: !is_void_is_login && !is_is_login_type_error ? [] : [ is_void_is_login && "[用户参数错误] is_login 是无效的登录状态: ".concat(is_login), is_is_login_type_error && "[用户参数错误] is_login 登录状态的期望类型为: number; 实际类型为: ".concat(is_login_type) ].filter(Boolean) }) ]; }; // 验证传过来的其他参数是否有效 var validateProps = function(data, schema) { var ref = calcEventInfo(data, schema), event_id = ref.event_id, event = ref.event; var eventSchema = schema.find(function(item) { return event_id === item.id && event === item.n; }); if (!eventSchema) return []; var list = Array.isArray(eventSchema.d) ? eventSchema.d : []; return list.map(function(item) { var path = item.windDataPath.replace(/^\//, "").replace(/\//g, "."); var value = _lodash.default.get(data, path); var type = typeof value === "undefined" ? "undefined" : _typeof(value); var isRequiredError = item.rq === 1 && (0, _isEmpty.isEmpty)(value); var isLegalType = !isRequiredError && (0, _isEmpty.isEmpty)(value) || validateType(item, type, value); var isArrayType = Array.isArray(value); var isError = isRequiredError || !isLegalType; var message = [ !isRequiredError ? null : "[字段缺少错误] 缺少必要的字段或字段的值为空: ".concat(item.fn, ",字段的值: ").concat(JSON.stringify(value)), isLegalType ? null : "[字段类型错误] 字段 ".concat(item.fn, " 期望类型为: ").concat(_index.TYPE_TO_TYPE[item.tp], "; 实际类型为: ").concat(isArrayType ? "any[]" : type) ].filter(Boolean); return createError({ event: event, event_id: event_id, func_name: (0, _changeCase.camelCase)("track_".concat(event)), type_name: "Tracker.".concat((0, _first2Up.first2Up)((0, _changeCase.camelCase)(event)), ".Api"), event_desc: eventSchema, field_desc: item, field: item.fn, path: item.windDataPath, isError: isError, validateType: VALIDATE_TYPE.PROPS_VALIDATE, detail_url: "".concat(_index.SCHEMA_DETAIL_URL, "?id=").concat(eventSchema.iid, "&eventName=").concat(eventSchema.meaning), message: message }); }); }; // 验证数据 var validate = function(data, schema) { var events = validateEvent(data, schema); var hasEventError = events.some(function(item) { return item.isError; }); if (hasEventError) return events; var users = validateUser(data, schema); var props = validateProps(data, schema); return _toConsumableArray(events).concat(_toConsumableArray(users), _toConsumableArray(props)); }; // 验证单个数据 var validateSingle = function(data, schema) { var errors = validate(data, schema); return errors; }; // 验证批量数据 var validateBatch = function(data, schema) { var list = data.list, rest = _objectWithoutProperties(data, [ "list" ]); var arr = Array.isArray(list) ? list : []; var datas = arr.map(function(item) { return _objectSpreadProps(_objectSpread({}, rest), { data: item }); }); var errors = datas.map(function(item) { return validate(item, schema); }); return errors.flat(); }; // 验证器 var validator = function(app, option) { app.post("/wind", function(request, response) { var data = Object.assign({}, request.body); var isBatch = Object.prototype.hasOwnProperty.call(data, "list"); _axios.default.get("http://localhost:".concat(option.port, "/schemas/").concat(data.project)).then(function(res) { var schema = Array.isArray(res.data) ? res.data : []; var errors = isBatch ? validateBatch(data, schema) : validateSingle(data, schema); var result = errors.filter(function(item) { return item.isError; }).map(function(item) { return _objectSpreadProps(_objectSpread({}, item), { project: data.project }); }); return response.send(JSON.stringify(result)); }); }); return app; }; var server = function(params) { var option = Object.assign({}, DEFAULT_OPTION, params); var schemas = (0, _lodash.isArray)(option.schemas) ? option.schemas : []; var app = (0, _express.default)(); app.use((0, _cors.default)()); app.use(_bodyParser.default.json()); app.use(_bodyParser.default.urlencoded({ extended: false })); schemas.forEach(function(list) { var arr = Array.isArray(list) ? list : []; var first = arr[0]; if (!first) return; app.get("/schemas/".concat(first.project), function(request, response) { var result = list.map(function(item) { var _ = item.project, rest = _objectWithoutProperties(item, [ "project" ]); return rest; }); response.send(JSON.stringify(result)); }); var SCHEMA_MESSAGE = "[gd-tracker-cli] You can get the project schema by: http://localhost:".concat(option.port, "/schemas/").concat(first.project); console.log(_cliColor.default.green(SCHEMA_MESSAGE)); }); validator(app, option); app.listen(option.port, function() { var RUN_MESSAGE = "[gd-tracker-cli] Validator server is run in http://localhost:".concat(option.port, "."); var VALIDATE_URL_MESSAGE = "[gd-tracker-cli] The validateURL is http://localhost:".concat(option.port, "/wind"); console.log(_cliColor.default.green(RUN_MESSAGE)); console.log(_cliColor.default.green(VALIDATE_URL_MESSAGE)); }); return app; }; var _default = server;