@gaoding/gd-tracker
Version:
Gaoding tracker for sensorsdata(sa), baidu(_hmt), Growing.IO(gio)
404 lines (403 loc) • 15.1 kB
JavaScript
;
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, {
createApi: function() {
return createApi;
},
default: function() {
return _default;
},
createApiIndex: function() {
return createApiIndex;
}
});
var _mergeDeep = /*#__PURE__*/ _interopRequireDefault(require("merge-deep"));
var _changeCase = require("change-case");
var _isObject = require("../utils/is-object");
var _first2Up = require("../utils/first-2-up");
var _index = require("../constants/index");
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 _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
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 _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
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);
}
// trackerWind.trackEvent 方法的 scopeObject 参数
// 参数 参数类型 参数说明
// scope basic/common/event 无垠数据层级对象
// scopeObject.basic Object 基础公共数据层,对应设置埋点 最外层字段下的数据
// scopeObject.common Object 公共业务数据层,对应设置埋点 data 字段下的数据
// scopeObject.event Object 业务事件数据层,对应设置埋点 attributes 字段下的数据
var DATA_THEIRS = {
"basic": "/",
"common": "/data",
"event": "/data/attributes",
"detail": "/data/attributes/detail" // 业务数据层,对应设置埋点 detail 字段下的数据
};
// 当前字段是否属于 Detail 层
var isDetailData = function(field) {
var path = field.path || "";
var result = path.startsWith(DATA_THEIRS.detail);
return result;
};
// 当前字段是否属于 Event 层
var isEventData = function(field) {
var path = field.path || "";
var result = path.startsWith(DATA_THEIRS.event) && !path.startsWith(DATA_THEIRS.detail);
return result;
};
// 当前字段是否属于 Common 层
var isCommonData = function(field) {
var path = field.path || "";
var result = path.startsWith(DATA_THEIRS.common) && !path.startsWith(DATA_THEIRS.event);
return result;
};
// 当前字段是否属于 Basic 层
var isBasicData = function(field) {
var path = field.path || "";
var result = path.startsWith(DATA_THEIRS.basic) && !path.startsWith(DATA_THEIRS.common);
return result;
};
// 当前字段是否必要的
var isRequired = function(field) {
var required = String(field.required);
var result = required === "1";
return result;
};
// 是否可选字段
var isOptionalField = function(data) {
var prepare = Object.assign({}, data);
var keys = Object.keys(prepare);
var result = keys.every(function(item) {
return item.endsWith("?");
});
return result;
};
// 创建文本
var createText = function(list) {
var result = list.filter(Boolean).join("\n");
return result;
};
// 为可选择字段加上 "?"
var shimOptionalField = function(data) {
var prepare = Object.assign({}, data);
return Object.keys(prepare).map(function(key) {
return {
key: key,
value: prepare[key]
};
}).map(function(param) {
var key = param.key, value = param.value;
return {
key: key,
value: !(0, _isObject.isObject)(value) ? value : shimOptionalField(value),
isOptional: !(0, _isObject.isObject)(value) ? key.endsWith("?") : isOptionalField(value),
newKey: !(0, _isObject.isObject)(value) ? key : !isOptionalField(value) ? key : "".concat(key, "?")
};
}).reduce(function(prev, cur, index) {
prev[cur.newKey] = cur.value;
return prev;
}, {});
};
// 根据路径创建一个 PathField 对象
var createPathField = function(field) {
var str = typeof field.path === "string" ? field.path : "";
var list = str.split("/").filter(Boolean);
var result = {};
var temp = result;
list.forEach(function(item, index) {
if (index === list.length - 1) {
var key = isRequired(field) ? item : "".concat(item, "?");
temp[key] = "".concat(_index.TYPE_TO_TYPE[field.type], "; // ").concat(field.meaning);
} else {
temp[item] = {};
temp = temp[item];
}
});
return result;
};
var createMetaCode = function() {
var result = "import { trackerWind } from '@gaoding/gd-tracker';\n";
return result;
};
// 创建 interface IBasic/ICommon/IEvent/IDetail
var createSubType = function(event, filter, name, path) {
var fields = event.fields.filter(function(item) {
return filter(item);
});
if (fields.length <= 0) return {
code: null,
isOptional: true
};
var merger = {};
var list = fields.map(function(item) {
return createPathField(item);
});
list.forEach(function(item) {
return merger = (0, _mergeDeep.default)(merger, item);
});
if (path === DATA_THEIRS.basic && merger.data) delete merger.data;
if (path === DATA_THEIRS.common && merger.data.attributes) delete merger.data.attributes;
if (path === DATA_THEIRS.event && merger.data.attributes.detail) delete merger.data.attributes.detail;
var execute = "merger".concat(path.replace(/\//g, "."));
var schema = path === DATA_THEIRS.basic ? merger : eval(execute);
var shape = shimOptionalField(schema);
var lines = JSON.stringify(shape, null, 4).replace(/"/g, "").replace(/,/g, "").split("\n").map(function(item, index) {
return index !== 0 ? item : "export interface ".concat(name, " {");
}).map(function(item) {
return Array(8).fill(" ").join("") + item;
});
var code = createText(lines);
var isOptional = isOptionalField(shape);
var result = {
code: code + "\n",
isOptional: isOptional
};
return result;
};
// 创建 interface IScope
var createScopeType = function(basic, common, event) {
if (!basic.code && !common.code && !event.code) return {
code: null,
isOptional: true
};
var code = createText([
"export interface IScope {"
].concat(_toConsumableArray([
basic.code && "".concat(!basic.isOptional ? "basic" : "basic?", ": IBasic;"),
common.code && "".concat(!common.isOptional ? "common" : "common?", ": ICommon;"),
event.code && "".concat(!event.isOptional ? "event" : "event?", ": IEvent;")
].filter(Boolean).map(function(item) {
return Array(4).fill(" ").join("") + item;
})), [
"}"
]).filter(Boolean).map(function(item) {
return Array(8).fill(" ").join("") + item;
}));
var isOptional = basic.isOptional && common.isOptional && event.isOptional;
var result = {
code: code + "\n",
isOptional: isOptional
};
return result;
};
// 创建 interface Api
var createApiType = function(detail, scope) {
var detailCode = !detail.code ? "detail?: null | undefined" : !detail.isOptional ? "detail: IDetail" : "detail?: IDetail";
var callbackCode = "(result: null | Error) => any";
var sepce = Array(4).fill(" ").join("");
return createText([
"export interface Api {",
(!scope.code || scope.isOptional) && sepce + "(".concat(detailCode, ", callback?: ").concat(callbackCode, "): void;"),
scope.code && scope.isOptional && sepce + "(".concat(detailCode, ", scope?: IScope, callback?: ").concat(callbackCode, "): void;"),
scope.code && !scope.isOptional && sepce + "(".concat(detailCode, ", scope: IScope, callback?: ").concat(callbackCode, "): void;"),
"}"
].filter(Boolean).map(function(item) {
return Array(8).fill(" ").join("") + item;
}));
};
// 创建函数参数接口的名字
var createTypeName = function(event) {
var name = event.name;
var result = (0, _changeCase.camelCase)(name);
return result;
};
// 创建函数参数接口的代码
var createTypeCode = function(event) {
var fnName = createFnName(event);
var name = createTypeName(event);
var basicType = createSubType(event, isBasicData, "IBasic", DATA_THEIRS.basic);
var commonType = createSubType(event, isCommonData, "ICommon", DATA_THEIRS.common);
var eventType = createSubType(event, isEventData, "IEvent", DATA_THEIRS.event);
var detailType = createSubType(event, isDetailData, "IDetail", DATA_THEIRS.detail);
var scopeType = createScopeType(basicType, commonType, eventType);
var apiCode = createApiType(detailType, scopeType);
return createText([
"\n// ".concat(fnName, " 的类型定义"),
"export declare namespace Tracker {\n",
" export namespace ".concat((0, _first2Up.first2Up)(name), " {\n"),
basicType.code,
commonType.code,
eventType.code,
detailType.code,
scopeType.code,
apiCode,
" }",
"}"
]);
};
// 创建函数类型的名字
var createFnTypeName = function(event) {
var name = createTypeName(event);
var result = [
"Tracker",
(0, _first2Up.first2Up)(name),
"Api"
].join(".");
return result;
};
// 创建函数的名字
var createFnName = function(event) {
var name = event.name;
var result = (0, _changeCase.camelCase)([
"track",
name
].join("_"));
return result;
};
// 创建函数的代码
var createFnCode = function(event, hasScope) {
var fnName = createFnName(event);
var fnTypeName = createFnTypeName(event);
return hasScope ? createText([
"\n// ".concat(event.meaning),
"export const ".concat(fnName, ": ").concat(fnTypeName, " = (option, ...args) => {"),
" const detail = Object.assign({}, option, { event_id: ".concat(event.id, " });"),
" const scope = typeof args[0] === 'function' ? {} : args[0];",
" const callback = typeof args[0] === 'function' ? args[0] : args[1];",
" return trackerWind.trackEvent('".concat(event.name, "', detail, scope, callback);"),
"};"
]) : createText([
"\n// ".concat(event.meaning),
"export const ".concat(fnName, ": ").concat(fnTypeName, " = (option, callback) => {"),
" const detail = Object.assign({}, option, { event_id: ".concat(event.id, " });"),
" return trackerWind.trackEvent('".concat(event.name, "', detail, callback);"),
"};"
]);
};
// 创建 Api 接口的代码
var createApiCode = function(event) {
var typeCode = createTypeCode(event);
var hasScope = typeCode.includes("IScope");
var fnCode = createFnCode(event, hasScope);
return createText([
typeCode,
fnCode
]);
};
// 创建一个字段对象
var createField = function(option) {
var data = Object.assign({}, option);
return Object.freeze({
name: data.fn,
type: data.tp,
meaning: data.meaning,
their: data.dt,
path: data.windDataPath,
desc: data.description,
required: data.rq
});
};
// 创建一个事件对象
var createEvent = function(option) {
var data = Object.assign({}, option);
var list = Array.isArray(data.d) ? data.d : [];
return Object.freeze({
id: data.id,
name: data.n,
meaning: data.meaning,
fields: list.map(function(item) {
return createField(item);
})
});
};
var createApi = function(params) {
var list = Array.isArray(params) ? params : [];
var events = list.map(function(item) {
return createEvent(item);
});
var meta = createMetaCode();
var apis = events.map(function(item) {
return createApiCode(item);
});
var result = meta + createText(apis) + "\n";
return result;
};
var _default = createApi;
var createApiIndex = function(names) {
var list = names.map(function(item) {
return {
name: item,
variate: (0, _changeCase.camelCase)(item),
type: (0, _first2Up.first2Up)((0, _changeCase.camelCase)(item))
};
});
var metas = list.map(function(item) {
return "import * as ".concat(item.variate, " from './").concat(item.name, "';");
});
var metaTexts = createText(metas);
var types = list.map(function(item) {
return "export type ".concat(item.type, " = typeof ").concat(item.variate, ";");
});
var typeTexts = createText(types);
var unionWind = createText([
"export type UnionWind = {"
].concat(_toConsumableArray(list.map(function(item) {
return " ".concat(item.variate, ": ").concat(item.type, ";");
})), [
"};"
]));
var prototype = createText([
"export const prototype: UnionWind = {"
].concat(_toConsumableArray(list.map(function(item) {
return " ".concat(item.variate, ",");
})), [
"};"
]));
var overloads = list.map(function(item) {
return "export function createWindAPI(name: '".concat(item.name, "'): UnionWind['").concat(item.variate, "'] & UnionWind;");
});
var overloadTexts = createText(overloads);
var createWindAPI = createText([
"export function createWindAPI(name: ".concat(list.map(function(item) {
return "'".concat(item.name, "'");
}).join(" | "), ") {"),
" const underline = /([^_])(?:_+([^_]))/g;",
" const camelCase = (str: string) => str.replace(underline, ($0, $1, $2) => $1 + $2.toUpperCase());",
" const self = prototype[camelCase(name) as keyof UnionWind];",
" const result = Object.assign(prototype, self);",
" return result;",
"};"
]);
var result = [
metaTexts,
typeTexts,
unionWind,
prototype,
overloadTexts,
createWindAPI
].join("\n\n");
return result;
};