@thinkingai/ae-cli 6.0.46 → 6.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.zh.md +6 -0
- package/dist/{auth-ROB2EDYV.js → auth-QPEVVBKT.js} +13 -7
- package/dist/auth-UMJAA72O.js +15 -0
- package/dist/{capability-GQ47BCFI.js → capability-RUSV77CO.js} +11 -10
- package/dist/{chunk-UW5UN47B.js → chunk-533JK3YX.js} +2 -0
- package/dist/{chunk-4XXOWOTA.js → chunk-6QK7SYYY.js} +5 -4
- package/dist/{chunk-TUKQZTMI.js → chunk-7K24F7T2.js} +2 -0
- package/dist/{chunk-OO6XR6LK.js → chunk-AMBFK2K3.js} +2 -0
- package/dist/{sync-HKIOZXQE.js → chunk-B5HMQAOM.js} +31 -540
- package/dist/{chunk-DQRPU6EE.js → chunk-BVDST5YT.js} +5 -4
- package/dist/{chunk-VTWMIC5L.js → chunk-E2JKXMVO.js} +2 -0
- package/dist/{chunk-JHENBQ5B.js → chunk-FR2EDAQM.js} +1 -0
- package/dist/{chunk-ZQ47LWTI.js → chunk-GJXRF7Y6.js} +6 -5
- package/dist/{chunk-DWO43OIB.js → chunk-JQ3ENZZH.js} +2 -0
- package/dist/chunk-JYMGHGCE.js +191 -0
- package/dist/{chunk-BYYS3ANB.js → chunk-KEWVSO64.js} +5 -4
- package/dist/{chunk-3FY3RJ26.js → chunk-KZ6ZHF5J.js} +2 -1
- package/dist/{chunk-2MN54X6H.js → chunk-NSIVXKJH.js} +4 -3
- package/dist/{chunk-ZQKDZXDO.js → chunk-O6K2ODUE.js} +3 -2
- package/dist/chunk-QL6R6TSK.js +25215 -0
- package/dist/{chunk-J2DEBMRF.js → chunk-RWXIXOZG.js} +22 -9
- package/dist/{chunk-4NN5IWVN.js → chunk-T6OSFQZD.js} +2 -0
- package/dist/{chunk-3KWQYGYI.js → chunk-TKHSULJT.js} +2 -0
- package/dist/{chunk-6EIJSNBD.js → chunk-Y74WTIKJ.js} +2 -0
- package/dist/{client-L2YDMHQ6.js → client-N7NGZUNI.js} +4 -3
- package/dist/{community-report-client-C7WDGET3.js → community-report-client-6OL6GBQW.js} +3 -2
- package/dist/{config-BMYZX2UE.js → config-XNMACCKX.js} +8 -7
- package/dist/{data-integration-QEKDWQDY.js → data-integration-4NZGZ45E.js} +913 -92
- package/dist/index.js +36 -34
- package/dist/{local-data-upload-client-4YYHSYD6.js → local-data-upload-client-EFHDLXFG.js} +3 -2
- package/dist/{memory-3ORCR7JH.js → memory-HBJQ2GC5.js} +8 -7
- package/dist/{metadata-A6QLH3IS.js → metadata-PGDJE5RQ.js} +12 -11
- package/dist/{model-UGRDX4MW.js → model-BHLJ2QMT.js} +10 -9
- package/dist/{personal-semantic-preference-QZFAJWGE.js → personal-semantic-preference-E5NZ56DN.js} +11 -10
- package/dist/sync-MUWPRM5I.js +522 -0
- package/dist/{te-agent-BR6VDBNX.js → te-agent-WQZTMEK4.js} +10 -9
- package/dist/{te-analysis-MUKUXJL4.js → te-analysis-YWCSSLYL.js} +107 -20
- package/dist/{te-community-ISDQWJU7.js → te-community-BNE6KREL.js} +8 -7
- package/dist/{te-dataops-6P5IKWNJ.js → te-dataops-TXLKM2W6.js} +467 -67
- package/dist/{te-engage-ELA3C5BM.js → te-engage-VEW4CJHK.js} +26 -10
- package/dist/{te-kb-RCLSSH2Q.js → te-kb-BUD6N3NI.js} +311 -24
- package/dist/{te-system-FXITO2JG.js → te-system-44LZJDTQ.js} +573 -37
- package/dist/{te-team-ADOC2ROP.js → te-team-XMP47YXE.js} +10 -7
- package/dist/{update-YCYCKJOO.js → update-UODFOZ4P.js} +7 -6
- package/package.json +18 -9
- package/skills/ae-analysis/references/analysis_gateway_assets.md +1 -1
- package/skills/ae-analysis/references/audience_models.md +18 -0
- package/skills/ae-analysis/references/command_index.md +2 -2
- package/skills/ae-analysis/references/project_timezone_update.md +13 -4
- package/skills/ae-analysis/references/property_create.md +2 -0
- package/skills/ae-analysis/references/super_metadata_batch_create.md +2 -0
- package/skills/ae-analysis/references/user_cluster_models.md +2 -0
- package/skills/ae-analysis/references/user_cluster_update.md +8 -4
- package/skills/ae-analysis/references/user_tag_create.md +7 -1
- package/skills/ae-analysis/references/user_tag_models.md +8 -2
- package/skills/ae-data-integration/SKILL.md +1 -0
- package/skills/ae-data-integration/references/error-handling.md +54 -1
- package/skills/ae-data-integration/references/source-inspect.md +18 -2
- package/skills/ae-data-integration/references/transform.md +3 -1
- package/skills/ae-data-integration/references/ue-routing.md +23 -0
- package/skills/ae-dataops/SKILL.md +11 -1
- package/skills/ae-dataops/references/dataops-backfill.md +135 -0
- package/skills/ae-engage/SKILL.md +3 -0
- package/skills/ae-engage/references/build-task-save-guide.md +5 -1
- package/skills/ae-engage/references/save-task.md +6 -0
- package/skills/ae-kb/SKILL.md +120 -9
- package/skills/ae-system/SKILL.md +28 -30
- package/skills/ae-system/references/channel-management.md +303 -0
- package/dist/auth-GBMV6TEJ.js +0 -14
- package/dist/capability-IINANQJA.js +0 -349
- package/dist/chunk-GJLGIMAO.js +0 -556
- package/dist/chunk-OMPRXM3V.js +0 -349
- package/dist/chunk-QNOLN2LJ.js +0 -509
- package/dist/chunk-RJDU7NYP.js +0 -1198
- package/dist/chunk-RNAALWJK.js +0 -98
- package/dist/chunk-SERWF6G5.js +0 -13
- package/dist/chunk-XNVMVIUI.js +0 -71
- package/dist/memory-I2WXDTV2.js +0 -893
- package/dist/metadata-HC7GBTTD.js +0 -339
- package/dist/model-HLHIEFMU.js +0 -139
- package/dist/personal-semantic-preference-YXAZBFVW.js +0 -239
- package/dist/sync-TFHU2UTG.js +0 -10261
- package/dist/te-agent-VLYOV7S4.js +0 -3894
- package/dist/te-analysis-JECYCV6K.js +0 -9357
- package/dist/te-community-5DMNKJWY.js +0 -1859
- package/dist/te-dataops-CVULXNVB.js +0 -2209
- package/dist/te-engage-MC5IQZIU.js +0 -4898
- package/dist/te-system-K2GYMCTB.js +0 -2213
package/dist/chunk-RJDU7NYP.js
DELETED
|
@@ -1,1198 +0,0 @@
|
|
|
1
|
-
// src/tracking/xlsx/write.ts
|
|
2
|
-
import ExcelJS from "exceljs";
|
|
3
|
-
|
|
4
|
-
// src/tracking/i18n/locale.ts
|
|
5
|
-
var VALID_LOCALES = /* @__PURE__ */ new Set(["zh", "en", "ja", "ko"]);
|
|
6
|
-
function normalize(raw) {
|
|
7
|
-
const lower = raw.trim().toLowerCase();
|
|
8
|
-
if (lower.startsWith("zh") || lower.startsWith("cn")) return "zh";
|
|
9
|
-
if (lower.startsWith("ja") || lower.startsWith("jp")) return "ja";
|
|
10
|
-
if (lower.startsWith("ko") || lower.startsWith("kr")) return "ko";
|
|
11
|
-
if (lower.startsWith("en")) return "en";
|
|
12
|
-
if (VALID_LOCALES.has(lower)) return lower;
|
|
13
|
-
return "en";
|
|
14
|
-
}
|
|
15
|
-
var _cliLocale;
|
|
16
|
-
function detectCliLocale() {
|
|
17
|
-
if (_cliLocale) return _cliLocale;
|
|
18
|
-
if (process.env.AE_LANG) {
|
|
19
|
-
_cliLocale = normalize(process.env.AE_LANG);
|
|
20
|
-
return _cliLocale;
|
|
21
|
-
}
|
|
22
|
-
const sys = (process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || "").toLowerCase();
|
|
23
|
-
if (sys) {
|
|
24
|
-
_cliLocale = normalize(sys);
|
|
25
|
-
return _cliLocale;
|
|
26
|
-
}
|
|
27
|
-
_cliLocale = "en";
|
|
28
|
-
return _cliLocale;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// src/tracking/i18n/resources/xlsx/sheets.ts
|
|
32
|
-
var SHEET_NAMES = {
|
|
33
|
-
event_data: {
|
|
34
|
-
zh: "#\u4E8B\u4EF6\u6570\u636E",
|
|
35
|
-
en: "#event data",
|
|
36
|
-
ja: "#\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF",
|
|
37
|
-
ko: "#\uC774\uBCA4\uD2B8 \uB370\uC774\uD130"
|
|
38
|
-
},
|
|
39
|
-
common_props: {
|
|
40
|
-
zh: "#\u516C\u5171\u4E8B\u4EF6\u5C5E\u6027",
|
|
41
|
-
en: "#super property",
|
|
42
|
-
ja: "#\u30D1\u30D6\u30EA\u30C3\u30AF\u30A4\u30D9\u30F3\u30C8\u30D7\u30ED\u30D1\u30C6\u30A3",
|
|
43
|
-
ko: "#\uACF5\uD1B5 \uC774\uBCA4\uD2B8 \uC18D\uC131"
|
|
44
|
-
},
|
|
45
|
-
user_data: {
|
|
46
|
-
zh: "#\u7528\u6237\u6570\u636E",
|
|
47
|
-
en: "#user data",
|
|
48
|
-
ja: "#\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF",
|
|
49
|
-
ko: "#\uC720\uC800 \uB370\uC774\uD130"
|
|
50
|
-
},
|
|
51
|
-
user_id: {
|
|
52
|
-
zh: "#\u7528\u6237ID\u4F53\u7CFB",
|
|
53
|
-
en: "#ID mapping rule",
|
|
54
|
-
ja: "#\u30E6\u30FC\u30B6\u30FCID\u30B7\u30B9\u30C6\u30E0",
|
|
55
|
-
ko: "#\uC720\uC800 ID \uCCB4\uACC4"
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
function sheetName(key, locale) {
|
|
59
|
-
return SHEET_NAMES[key][locale];
|
|
60
|
-
}
|
|
61
|
-
function allSheetNames(key) {
|
|
62
|
-
return Object.values(SHEET_NAMES[key]);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// src/tracking/i18n/resources/xlsx/headers.ts
|
|
66
|
-
var HEADERS = {
|
|
67
|
-
// === #事件数据 (9 列) ===
|
|
68
|
-
event_name: {
|
|
69
|
-
zh: "\u4E8B\u4EF6\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
70
|
-
en: "Event Name",
|
|
71
|
-
ja: "\u30A4\u30D9\u30F3\u30C8\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
72
|
-
ko: "\uC774\uBCA4\uD2B8 \uC774\uB984 (\uD544\uC218)"
|
|
73
|
-
},
|
|
74
|
-
event_display_name: {
|
|
75
|
-
zh: "\u4E8B\u4EF6\u663E\u793A\u540D",
|
|
76
|
-
en: "Event Display Name",
|
|
77
|
-
ja: "\u30A4\u30D9\u30F3\u30C8\u8868\u793A\u540D",
|
|
78
|
-
ko: "\uC774\uBCA4\uD2B8 \uD45C\uC2DC \uC774\uB984"
|
|
79
|
-
},
|
|
80
|
-
event_desc: {
|
|
81
|
-
zh: "\u4E8B\u4EF6\u8BF4\u660E",
|
|
82
|
-
en: "Event Description",
|
|
83
|
-
ja: "\u30A4\u30D9\u30F3\u30C8\u8AAC\u660E",
|
|
84
|
-
ko: "\uC774\uBCA4\uD2B8 \uC124\uBA85"
|
|
85
|
-
},
|
|
86
|
-
event_tag: {
|
|
87
|
-
zh: "\u4E8B\u4EF6\u6807\u7B7E",
|
|
88
|
-
en: "Event Tag",
|
|
89
|
-
ja: "\u30AB\u30C6\u30B4\u30EA",
|
|
90
|
-
ko: "\uC774\uBCA4\uD2B8 \uD0DC\uADF8"
|
|
91
|
-
},
|
|
92
|
-
platform: {
|
|
93
|
-
zh: "\u91C7\u96C6\u7AEF",
|
|
94
|
-
en: "Platform",
|
|
95
|
-
ja: "\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0",
|
|
96
|
-
ko: "\uD50C\uB7AB\uD3FC"
|
|
97
|
-
},
|
|
98
|
-
prop_name: {
|
|
99
|
-
zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
100
|
-
en: "Property Name",
|
|
101
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
102
|
-
ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
|
|
103
|
-
},
|
|
104
|
-
prop_display_name: {
|
|
105
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
106
|
-
en: "Property Display Name",
|
|
107
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
|
|
108
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
109
|
-
},
|
|
110
|
-
prop_type: {
|
|
111
|
-
zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
|
|
112
|
-
en: "Data Type",
|
|
113
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
|
|
114
|
-
ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
|
|
115
|
-
},
|
|
116
|
-
prop_desc: {
|
|
117
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
118
|
-
en: "Property Description",
|
|
119
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
|
|
120
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
121
|
-
},
|
|
122
|
-
// === #公共事件属性 (4 列) ===
|
|
123
|
-
common_prop_name: {
|
|
124
|
-
zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
125
|
-
en: "Property Name",
|
|
126
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
127
|
-
ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
|
|
128
|
-
},
|
|
129
|
-
common_prop_display_name: {
|
|
130
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
131
|
-
en: "Property Display Name",
|
|
132
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
|
|
133
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
134
|
-
},
|
|
135
|
-
common_prop_type: {
|
|
136
|
-
zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
|
|
137
|
-
en: "Data Type",
|
|
138
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
|
|
139
|
-
ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
|
|
140
|
-
},
|
|
141
|
-
common_prop_desc: {
|
|
142
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
143
|
-
en: "Property Description",
|
|
144
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
|
|
145
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
146
|
-
},
|
|
147
|
-
// === #用户数据 (6 列) ===
|
|
148
|
-
user_prop_name: {
|
|
149
|
-
zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
150
|
-
en: "Property Name",
|
|
151
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
152
|
-
ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
|
|
153
|
-
},
|
|
154
|
-
user_prop_display_name: {
|
|
155
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
156
|
-
en: "Property Display Name",
|
|
157
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
|
|
158
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
159
|
-
},
|
|
160
|
-
user_prop_type: {
|
|
161
|
-
zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
|
|
162
|
-
en: "Data Type",
|
|
163
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
|
|
164
|
-
ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
|
|
165
|
-
},
|
|
166
|
-
update_type: {
|
|
167
|
-
zh: "\u66F4\u65B0\u65B9\u5F0F",
|
|
168
|
-
en: "Update Type",
|
|
169
|
-
ja: "\u66F4\u65B0\u65B9\u6CD5",
|
|
170
|
-
ko: "\uC5C5\uB370\uC774\uD2B8 \uBC29\uC2DD"
|
|
171
|
-
},
|
|
172
|
-
user_prop_desc: {
|
|
173
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
174
|
-
en: "Property Description",
|
|
175
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
|
|
176
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
177
|
-
},
|
|
178
|
-
prop_tag: {
|
|
179
|
-
zh: "\u5C5E\u6027\u6807\u7B7E",
|
|
180
|
-
en: "Property Tag",
|
|
181
|
-
ja: "\u30AB\u30C6\u30B4\u30EA",
|
|
182
|
-
ko: "\uC18D\uC131 \uD0DC\uADF8"
|
|
183
|
-
},
|
|
184
|
-
// === #用户ID体系 (4 列,不含"游戏类型"前置列) ===
|
|
185
|
-
user_id_prop_name: {
|
|
186
|
-
zh: "\u5C5E\u6027\u540D",
|
|
187
|
-
en: "Property",
|
|
188
|
-
ja: "\u5C5E\u6027\u540D",
|
|
189
|
-
ko: "\uC18D\uC131 \uC774\uB984"
|
|
190
|
-
},
|
|
191
|
-
user_id_display_name: {
|
|
192
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
193
|
-
en: "Display Name",
|
|
194
|
-
ja: "\u5C5E\u6027\u8868\u793A\u540D",
|
|
195
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
196
|
-
},
|
|
197
|
-
user_id_desc: {
|
|
198
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
199
|
-
en: "Description",
|
|
200
|
-
ja: "\u5C5E\u6027\u8AAC\u660E",
|
|
201
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
202
|
-
},
|
|
203
|
-
user_id_value_desc: {
|
|
204
|
-
zh: "\u8D4B\u503C\u8BF4\u660E",
|
|
205
|
-
en: "Value Description",
|
|
206
|
-
ja: "\u4EE3\u5165\u8AAC\u660E",
|
|
207
|
-
ko: "\uAC12 \uC124\uBA85"
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
function headerName(key, locale) {
|
|
211
|
-
return HEADERS[key][locale];
|
|
212
|
-
}
|
|
213
|
-
function allHeaderNames(key) {
|
|
214
|
-
return Object.values(HEADERS[key]);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// src/tracking/i18n/resources/xlsx/types.ts
|
|
218
|
-
var PROP_TYPE_DISPLAY = {
|
|
219
|
-
string: { zh: "\u6587\u672C", en: "String", ja: "\u30B9\u30C8\u30EA\u30F3\u30B0", ko: "String" },
|
|
220
|
-
number: { zh: "\u6570\u503C", en: "Number", ja: "\u6570\u5024", ko: "Number" },
|
|
221
|
-
bool: { zh: "\u5E03\u5C14", en: "Boolean", ja: "\u30D6\u30FC\u30EB\u5024", ko: "Boolean" },
|
|
222
|
-
datetime: { zh: "\u65F6\u95F4", en: "Date", ja: "\u6642\u9593", ko: "Date" },
|
|
223
|
-
object: { zh: "\u5BF9\u8C61", en: "Row", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8", ko: "Row" },
|
|
224
|
-
array_row: { zh: "\u5BF9\u8C61\u7EC4", en: "Array Row", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30B0\u30EB\u30FC\u30D7", ko: "Array Row" },
|
|
225
|
-
array_string: { zh: "\u5217\u8868", en: "List", ja: "\u30EA\u30B9\u30C8", ko: "List" }
|
|
226
|
-
};
|
|
227
|
-
function typeToDisplay(type, locale) {
|
|
228
|
-
return PROP_TYPE_DISPLAY[type][locale];
|
|
229
|
-
}
|
|
230
|
-
var ALL_DISPLAY_TO_TYPE = {};
|
|
231
|
-
for (const [canonical, locales] of Object.entries(PROP_TYPE_DISPLAY)) {
|
|
232
|
-
for (const val of Object.values(locales)) {
|
|
233
|
-
ALL_DISPLAY_TO_TYPE[val] = canonical;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
var ALIASES = {
|
|
237
|
-
// zh alias(行业模板)
|
|
238
|
-
"\u5B57\u7B26\u4E32": "string",
|
|
239
|
-
// en alias(旧值兼容 — 2026-07-15 前生成的老 xlsx)
|
|
240
|
-
"string": "string",
|
|
241
|
-
"number": "number",
|
|
242
|
-
"boolean": "bool",
|
|
243
|
-
"datetime": "datetime",
|
|
244
|
-
"object": "object",
|
|
245
|
-
"object[]": "array_row",
|
|
246
|
-
"string[]": "array_string",
|
|
247
|
-
// en 额外 alias
|
|
248
|
-
"Bool": "bool",
|
|
249
|
-
"DateTime": "datetime",
|
|
250
|
-
"Time": "datetime",
|
|
251
|
-
"Object": "object",
|
|
252
|
-
"Object Array": "array_row",
|
|
253
|
-
"String Array": "array_string",
|
|
254
|
-
// ja alias
|
|
255
|
-
"\u6587\u5B57\u5217": "string",
|
|
256
|
-
"\u30C6\u30AD\u30B9\u30C8": "string",
|
|
257
|
-
"\u30D6\u30FC\u30EB": "bool",
|
|
258
|
-
"\u65E5\u6642": "datetime",
|
|
259
|
-
// ja 旧值兼容
|
|
260
|
-
"\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u914D\u5217": "array_row",
|
|
261
|
-
"\u914D\u5217": "array_string",
|
|
262
|
-
// ko alias
|
|
263
|
-
"\uD14D\uC2A4\uD2B8": "string",
|
|
264
|
-
"\uBB38\uC790\uC5F4": "string",
|
|
265
|
-
"\uC22B\uC790": "number",
|
|
266
|
-
"\uBD80\uC6B8": "bool",
|
|
267
|
-
"\uB0A0\uC9DC\uC2DC\uAC04": "datetime",
|
|
268
|
-
"\uAC1D\uCCB4 \uBC30\uC5F4": "array_row",
|
|
269
|
-
"\uB9AC\uC2A4\uD2B8": "array_string",
|
|
270
|
-
// ko 旧值兼容
|
|
271
|
-
"time": "datetime",
|
|
272
|
-
"object_array": "array_row",
|
|
273
|
-
"string_array": "array_string"
|
|
274
|
-
};
|
|
275
|
-
Object.assign(ALL_DISPLAY_TO_TYPE, ALIASES);
|
|
276
|
-
function displayToType(raw) {
|
|
277
|
-
const trimmed = raw.trim();
|
|
278
|
-
return ALL_DISPLAY_TO_TYPE[trimmed] ?? null;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// src/tracking/i18n/translate.ts
|
|
282
|
-
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
283
|
-
import { join as join2 } from "path";
|
|
284
|
-
|
|
285
|
-
// src/tracking/paths.ts
|
|
286
|
-
import { existsSync, readFileSync } from "fs";
|
|
287
|
-
import { dirname, join } from "path";
|
|
288
|
-
import { fileURLToPath } from "url";
|
|
289
|
-
var AE_CLI_PACKAGE_NAMES = /* @__PURE__ */ new Set(["@tant/ae-cli", "@thinkingai/ae-cli"]);
|
|
290
|
-
function isAeCliPackageName(name) {
|
|
291
|
-
return typeof name === "string" && (AE_CLI_PACKAGE_NAMES.has(name) || name.endsWith("/ae-cli"));
|
|
292
|
-
}
|
|
293
|
-
function getPackageRoot() {
|
|
294
|
-
let cur = dirname(fileURLToPath(import.meta.url));
|
|
295
|
-
while (cur !== dirname(cur)) {
|
|
296
|
-
const pj = join(cur, "package.json");
|
|
297
|
-
if (existsSync(pj)) {
|
|
298
|
-
try {
|
|
299
|
-
const pkg = JSON.parse(readFileSync(pj, "utf8"));
|
|
300
|
-
if (isAeCliPackageName(pkg.name)) return cur;
|
|
301
|
-
} catch {
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
cur = dirname(cur);
|
|
305
|
-
}
|
|
306
|
-
throw new Error("Could not locate ae-cli package root");
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// src/tracking/i18n/translate.ts
|
|
310
|
-
var loaded = /* @__PURE__ */ new Map();
|
|
311
|
-
function i18nFile(locale) {
|
|
312
|
-
const root = getPackageRoot();
|
|
313
|
-
const candidates = [
|
|
314
|
-
join2(root, "dist", "tracking", "i18n", "resources", "cli", `${locale}.json`),
|
|
315
|
-
join2(root, "src", "tracking", "i18n", "resources", "cli", `${locale}.json`)
|
|
316
|
-
];
|
|
317
|
-
for (const p of candidates) {
|
|
318
|
-
if (existsSync2(p)) return p;
|
|
319
|
-
}
|
|
320
|
-
return candidates[candidates.length - 1];
|
|
321
|
-
}
|
|
322
|
-
function loadSync(locale) {
|
|
323
|
-
if (loaded.has(locale)) return loaded.get(locale);
|
|
324
|
-
try {
|
|
325
|
-
const raw = readFileSync2(i18nFile(locale), "utf8");
|
|
326
|
-
const tree = JSON.parse(raw);
|
|
327
|
-
loaded.set(locale, tree);
|
|
328
|
-
return tree;
|
|
329
|
-
} catch {
|
|
330
|
-
if (locale !== "en") {
|
|
331
|
-
return loadSync("en");
|
|
332
|
-
}
|
|
333
|
-
loaded.set("en", {});
|
|
334
|
-
return {};
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
function t(key, params, locale) {
|
|
338
|
-
const loc = locale ?? detectCliLocale();
|
|
339
|
-
const tree = loadSync(loc);
|
|
340
|
-
const parts = key.split(".");
|
|
341
|
-
let node = tree;
|
|
342
|
-
for (const part of parts) {
|
|
343
|
-
if (typeof node !== "object" || node === null) return key;
|
|
344
|
-
node = node[part];
|
|
345
|
-
}
|
|
346
|
-
if (typeof node !== "string") return key;
|
|
347
|
-
if (params) {
|
|
348
|
-
return node.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? `{${name}}`));
|
|
349
|
-
}
|
|
350
|
-
return node;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// src/tracking/xlsx/tag-priority.ts
|
|
354
|
-
var TAG_PRIORITY = {
|
|
355
|
-
// Account lifecycle
|
|
356
|
-
"Basic": 1,
|
|
357
|
-
// Core gameplay
|
|
358
|
-
"Battle": 10,
|
|
359
|
-
"Stage": 11,
|
|
360
|
-
"Dungeon": 12,
|
|
361
|
-
"Gacha": 13,
|
|
362
|
-
// Progression & economy
|
|
363
|
-
"Growth": 20,
|
|
364
|
-
"Resource": 21,
|
|
365
|
-
// Monetization
|
|
366
|
-
"Ads": 30,
|
|
367
|
-
"Payment": 31,
|
|
368
|
-
"Subscription": 32,
|
|
369
|
-
// Supporting systems
|
|
370
|
-
"Shop": 40,
|
|
371
|
-
"Quest": 41,
|
|
372
|
-
"Achievement": 42,
|
|
373
|
-
"Check-in": 43,
|
|
374
|
-
"Leaderboard": 44,
|
|
375
|
-
"Guild": 45,
|
|
376
|
-
"Social": 46,
|
|
377
|
-
// Genre-specific (game)
|
|
378
|
-
"Building": 50,
|
|
379
|
-
"Alliance": 51,
|
|
380
|
-
"Equipment": 52,
|
|
381
|
-
"Trade": 53,
|
|
382
|
-
"Revive": 54,
|
|
383
|
-
"Slots": 55,
|
|
384
|
-
"Lottery": 56,
|
|
385
|
-
"Reward": 57,
|
|
386
|
-
// Non-game
|
|
387
|
-
"Discovery": 60,
|
|
388
|
-
"Product": 61,
|
|
389
|
-
"Order": 62,
|
|
390
|
-
"After-sales": 63,
|
|
391
|
-
"Content": 64,
|
|
392
|
-
"Interaction": 65,
|
|
393
|
-
"Relationship": 66,
|
|
394
|
-
"Live": 67,
|
|
395
|
-
"Onboarding": 68,
|
|
396
|
-
"Course": 69,
|
|
397
|
-
"Enrollment": 70,
|
|
398
|
-
"Quiz": 71,
|
|
399
|
-
"Creation": 72,
|
|
400
|
-
"Material": 73,
|
|
401
|
-
"Export": 74,
|
|
402
|
-
"Playback": 75,
|
|
403
|
-
"Withdraw": 76
|
|
404
|
-
};
|
|
405
|
-
var DEFAULT_TAG_PRIORITY = 80;
|
|
406
|
-
var CANONICAL_TAG = {
|
|
407
|
-
// zh
|
|
408
|
-
"\u57FA\u7840\u4E8B\u4EF6": "Basic",
|
|
409
|
-
"\u6218\u6597": "Battle",
|
|
410
|
-
"\u5173\u5361": "Stage",
|
|
411
|
-
"\u526F\u672C": "Dungeon",
|
|
412
|
-
"\u62BD\u5361": "Gacha",
|
|
413
|
-
"\u517B\u6210": "Growth",
|
|
414
|
-
"\u6210\u957F": "Growth",
|
|
415
|
-
"\u8D44\u6E90": "Resource",
|
|
416
|
-
"\u5E7F\u544A": "Ads",
|
|
417
|
-
"\u652F\u4ED8": "Payment",
|
|
418
|
-
"\u8BA2\u9605": "Subscription",
|
|
419
|
-
"\u5546\u57CE": "Shop",
|
|
420
|
-
"\u4EFB\u52A1": "Quest",
|
|
421
|
-
"\u6210\u5C31": "Achievement",
|
|
422
|
-
"\u7B7E\u5230": "Check-in",
|
|
423
|
-
"\u6392\u884C\u699C": "Leaderboard",
|
|
424
|
-
"\u516C\u4F1A": "Guild",
|
|
425
|
-
"\u793E\u4EA4": "Social",
|
|
426
|
-
"\u5EFA\u7B51": "Building",
|
|
427
|
-
"\u8054\u76DF": "Alliance",
|
|
428
|
-
"\u88C5\u5907": "Equipment",
|
|
429
|
-
"\u4EA4\u6613": "Trade",
|
|
430
|
-
"\u590D\u6D3B": "Revive",
|
|
431
|
-
"\u62BD\u5956": "Lottery",
|
|
432
|
-
"\u5956\u52B1": "Reward",
|
|
433
|
-
"\u63D0\u73B0": "Withdraw",
|
|
434
|
-
"\u53D1\u73B0": "Discovery",
|
|
435
|
-
"\u5546\u54C1": "Product",
|
|
436
|
-
"\u8BA2\u5355": "Order",
|
|
437
|
-
"\u552E\u540E": "After-sales",
|
|
438
|
-
"\u5185\u5BB9": "Content",
|
|
439
|
-
"\u4E92\u52A8": "Interaction",
|
|
440
|
-
"\u5173\u7CFB": "Relationship",
|
|
441
|
-
"\u76F4\u64AD": "Live",
|
|
442
|
-
"\u5F15\u5BFC": "Onboarding",
|
|
443
|
-
"\u8BFE\u7A0B": "Course",
|
|
444
|
-
"\u62A5\u540D": "Enrollment",
|
|
445
|
-
"\u6D4B\u9A8C": "Quiz",
|
|
446
|
-
"\u521B\u4F5C": "Creation",
|
|
447
|
-
"\u7D20\u6750": "Material",
|
|
448
|
-
"\u5BFC\u51FA": "Export",
|
|
449
|
-
"\u5185\u5BB9\u64AD\u653E": "Playback",
|
|
450
|
-
// ja
|
|
451
|
-
"\u57FA\u672C\u30A4\u30D9\u30F3\u30C8": "Basic",
|
|
452
|
-
"\u6226\u95D8": "Battle",
|
|
453
|
-
"\u30B9\u30C6\u30FC\u30B8": "Stage",
|
|
454
|
-
"\u30C0\u30F3\u30B8\u30E7\u30F3": "Dungeon",
|
|
455
|
-
"\u30AC\u30C1\u30E3": "Gacha",
|
|
456
|
-
"\u80B2\u6210": "Growth",
|
|
457
|
-
"\u30EA\u30BD\u30FC\u30B9": "Resource",
|
|
458
|
-
"\u5E83\u544A": "Ads",
|
|
459
|
-
"\u652F\u6255\u3044": "Payment",
|
|
460
|
-
"\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3": "Subscription",
|
|
461
|
-
"\u30B7\u30E7\u30C3\u30D7": "Shop",
|
|
462
|
-
"\u30AF\u30A8\u30B9\u30C8": "Quest",
|
|
463
|
-
"\u5B9F\u7E3E": "Achievement",
|
|
464
|
-
"\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3": "Check-in",
|
|
465
|
-
"\u30E9\u30F3\u30AD\u30F3\u30B0": "Leaderboard",
|
|
466
|
-
"\u30AE\u30EB\u30C9": "Guild",
|
|
467
|
-
"\u30BD\u30FC\u30B7\u30E3\u30EB": "Social",
|
|
468
|
-
"\u5EFA\u7BC9": "Building",
|
|
469
|
-
"\u540C\u76DF": "Alliance",
|
|
470
|
-
"\u88C5\u5099": "Equipment",
|
|
471
|
-
"\u30C8\u30EC\u30FC\u30C9": "Trade",
|
|
472
|
-
"\u5FA9\u6D3B": "Revive",
|
|
473
|
-
"\u30B9\u30ED\u30C3\u30C8": "Slots",
|
|
474
|
-
"\u62BD\u9078": "Lottery",
|
|
475
|
-
"\u5831\u916C": "Reward",
|
|
476
|
-
"\u5F15\u304D\u51FA\u3057": "Withdraw",
|
|
477
|
-
"\u767A\u898B": "Discovery",
|
|
478
|
-
"\u6CE8\u6587": "Order",
|
|
479
|
-
"\u30A2\u30D5\u30BF\u30FC\u30B5\u30FC\u30D3\u30B9": "After-sales",
|
|
480
|
-
"\u30B3\u30F3\u30C6\u30F3\u30C4": "Content",
|
|
481
|
-
"\u30A4\u30F3\u30BF\u30E9\u30AF\u30B7\u30E7\u30F3": "Interaction",
|
|
482
|
-
"\u95A2\u4FC2": "Relationship",
|
|
483
|
-
"\u30E9\u30A4\u30D6": "Live",
|
|
484
|
-
"\u30AA\u30F3\u30DC\u30FC\u30C7\u30A3\u30F3\u30B0": "Onboarding",
|
|
485
|
-
"\u30B3\u30FC\u30B9": "Course",
|
|
486
|
-
"\u7533\u3057\u8FBC\u307F": "Enrollment",
|
|
487
|
-
"\u30AF\u30A4\u30BA": "Quiz",
|
|
488
|
-
"\u5275\u4F5C": "Creation",
|
|
489
|
-
"\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8": "Export",
|
|
490
|
-
"\u518D\u751F": "Playback",
|
|
491
|
-
// ko
|
|
492
|
-
"\uAE30\uBCF8 \uC774\uBCA4\uD2B8": "Basic",
|
|
493
|
-
"\uC804\uD22C": "Battle",
|
|
494
|
-
"\uC2A4\uD14C\uC774\uC9C0": "Stage",
|
|
495
|
-
"\uB358\uC804": "Dungeon",
|
|
496
|
-
"\uAC00\uCC60": "Gacha",
|
|
497
|
-
"\uC721\uC131": "Growth",
|
|
498
|
-
"\uB9AC\uC18C\uC2A4": "Resource",
|
|
499
|
-
"\uAD11\uACE0": "Ads",
|
|
500
|
-
"\uACB0\uC81C": "Payment",
|
|
501
|
-
"\uAD6C\uB3C5": "Subscription",
|
|
502
|
-
"\uC0C1\uC810": "Shop",
|
|
503
|
-
"\uD018\uC2A4\uD2B8": "Quest",
|
|
504
|
-
"\uC5C5\uC801": "Achievement",
|
|
505
|
-
"\uCD9C\uC11D\uCCB4\uD06C": "Check-in",
|
|
506
|
-
"\uB9AC\uB354\uBCF4\uB4DC": "Leaderboard",
|
|
507
|
-
"\uAE38\uB4DC": "Guild",
|
|
508
|
-
"\uC18C\uC15C": "Social",
|
|
509
|
-
"\uAC74\uC124": "Building",
|
|
510
|
-
"\uC5F0\uB9F9": "Alliance",
|
|
511
|
-
"\uC7A5\uBE44": "Equipment",
|
|
512
|
-
"\uAC70\uB798": "Trade",
|
|
513
|
-
"\uBD80\uD65C": "Revive",
|
|
514
|
-
"\uC2AC\uB86F": "Slots",
|
|
515
|
-
"\uCD94\uCCA8": "Lottery",
|
|
516
|
-
"\uBCF4\uC0C1": "Reward",
|
|
517
|
-
"\uCD9C\uAE08": "Withdraw",
|
|
518
|
-
"\uBC1C\uACAC": "Discovery",
|
|
519
|
-
"\uC0C1\uD488": "Product",
|
|
520
|
-
"\uC8FC\uBB38": "Order",
|
|
521
|
-
"A/S": "After-sales",
|
|
522
|
-
"\uCF58\uD150\uCE20": "Content",
|
|
523
|
-
"\uC778\uD130\uB799\uC158": "Interaction",
|
|
524
|
-
"\uAD00\uACC4": "Relationship",
|
|
525
|
-
"\uB77C\uC774\uBE0C": "Live",
|
|
526
|
-
"\uC628\uBCF4\uB529": "Onboarding",
|
|
527
|
-
"\uCF54\uC2A4": "Course",
|
|
528
|
-
"\uC2E0\uCCAD": "Enrollment",
|
|
529
|
-
"\uD034\uC988": "Quiz",
|
|
530
|
-
"\uCC3D\uC791": "Creation",
|
|
531
|
-
"\uC18C\uC7AC": "Material",
|
|
532
|
-
"\uB0B4\uBCF4\uB0B4\uAE30": "Export",
|
|
533
|
-
"\uC7AC\uC0DD": "Playback"
|
|
534
|
-
};
|
|
535
|
-
function getTagPriority(tag) {
|
|
536
|
-
const canonical = CANONICAL_TAG[tag] ?? tag;
|
|
537
|
-
return TAG_PRIORITY[canonical] ?? DEFAULT_TAG_PRIORITY;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// src/tracking/xlsx/write.ts
|
|
541
|
-
var PLATFORM_TO_XLSX = {
|
|
542
|
-
"client": "client",
|
|
543
|
-
"server": "server",
|
|
544
|
-
"both": "client,server"
|
|
545
|
-
};
|
|
546
|
-
var VALID_PROP_TYPES = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
|
|
547
|
-
var VALID_UPDATE_TYPES = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
|
|
548
|
-
var SNAKE_CASE_RE = /^[a-z][a-z0-9_]*$/;
|
|
549
|
-
var PROP_NAME_RE = /^[a-zA-Z#][a-zA-Z0-9_.]*$/;
|
|
550
|
-
var MIN_COL_WIDTH = 10;
|
|
551
|
-
var PADDING = 3;
|
|
552
|
-
function isWideChar(code) {
|
|
553
|
-
return code >= 19968 && code <= 40959 || // CJK Unified Ideographs
|
|
554
|
-
code >= 13312 && code <= 19903 || // CJK Ext-A
|
|
555
|
-
code >= 12352 && code <= 12447 || // Hiragana
|
|
556
|
-
code >= 12448 && code <= 12543 || // Katakana
|
|
557
|
-
code >= 44032 && code <= 55215 || // Hangul
|
|
558
|
-
code >= 65280 && code <= 65519;
|
|
559
|
-
}
|
|
560
|
-
function displayWidth(s) {
|
|
561
|
-
let w = 0;
|
|
562
|
-
for (const ch of s) {
|
|
563
|
-
w += isWideChar(ch.charCodeAt(0)) ? 2 : 1;
|
|
564
|
-
}
|
|
565
|
-
return w;
|
|
566
|
-
}
|
|
567
|
-
function autoFitSheet(ws, maxWidth = 55) {
|
|
568
|
-
const colCount = ws.columnCount;
|
|
569
|
-
if (colCount === 0) return;
|
|
570
|
-
for (let i = 1; i <= colCount; i++) {
|
|
571
|
-
const col = ws.getColumn(i);
|
|
572
|
-
let maxDisplay = 0;
|
|
573
|
-
let needsWrap = false;
|
|
574
|
-
col.eachCell({ includeEmpty: false }, (cell) => {
|
|
575
|
-
const text = String(cell.value ?? "");
|
|
576
|
-
if (!text) return;
|
|
577
|
-
const dw = displayWidth(text);
|
|
578
|
-
if (dw > maxDisplay) maxDisplay = dw;
|
|
579
|
-
});
|
|
580
|
-
if (maxDisplay === 0) {
|
|
581
|
-
col.width = MIN_COL_WIDTH;
|
|
582
|
-
continue;
|
|
583
|
-
}
|
|
584
|
-
const capped = maxDisplay + PADDING > maxWidth;
|
|
585
|
-
col.width = Math.max(MIN_COL_WIDTH, Math.min(maxWidth, maxDisplay + PADDING));
|
|
586
|
-
if (capped) {
|
|
587
|
-
col.eachCell({ includeEmpty: false }, (cell) => {
|
|
588
|
-
cell.alignment = { ...cell.alignment, wrapText: true };
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
function validateDraft(d) {
|
|
594
|
-
const errors = [];
|
|
595
|
-
const eventNames = /* @__PURE__ */ new Set();
|
|
596
|
-
for (const evt of d.events) {
|
|
597
|
-
if (!SNAKE_CASE_RE.test(evt.event_name)) {
|
|
598
|
-
errors.push(`Event name "${evt.event_name}" does not match snake_case pattern`);
|
|
599
|
-
}
|
|
600
|
-
if (eventNames.has(evt.event_name)) {
|
|
601
|
-
errors.push(`Duplicate event_name: "${evt.event_name}"`);
|
|
602
|
-
}
|
|
603
|
-
eventNames.add(evt.event_name);
|
|
604
|
-
}
|
|
605
|
-
const eventProps = d.event_properties ?? d.common_properties ?? [];
|
|
606
|
-
const eventPropNames = /* @__PURE__ */ new Set();
|
|
607
|
-
const compositeProps = new Set(
|
|
608
|
-
eventProps.filter((p) => p.type === "array_row" || p.type === "object").map((p) => p.name)
|
|
609
|
-
);
|
|
610
|
-
for (const prop of eventProps) {
|
|
611
|
-
if (!PROP_NAME_RE.test(prop.name)) {
|
|
612
|
-
errors.push(`Event property name "${prop.name}" has invalid characters`);
|
|
613
|
-
}
|
|
614
|
-
if (prop.name.includes(".")) {
|
|
615
|
-
const parent = prop.name.split(".")[0];
|
|
616
|
-
if (!compositeProps.has(parent)) {
|
|
617
|
-
errors.push(`Nested property "${prop.name}" references non-composite parent "${parent}"`);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
if (!VALID_PROP_TYPES.has(prop.type)) {
|
|
621
|
-
errors.push(`Event property "${prop.name}" has invalid type: "${prop.type}"`);
|
|
622
|
-
}
|
|
623
|
-
if (eventPropNames.has(prop.name)) {
|
|
624
|
-
errors.push(`Duplicate event property name: "${prop.name}"`);
|
|
625
|
-
}
|
|
626
|
-
eventPropNames.add(prop.name);
|
|
627
|
-
}
|
|
628
|
-
const commonProps = d.common_event_properties ?? d.common_properties ?? [];
|
|
629
|
-
const commonPropNames = /* @__PURE__ */ new Set();
|
|
630
|
-
for (const prop of commonProps) {
|
|
631
|
-
if (!VALID_PROP_TYPES.has(prop.type)) {
|
|
632
|
-
errors.push(`Common event property "${prop.name}" has invalid type: "${prop.type}"`);
|
|
633
|
-
}
|
|
634
|
-
if (commonPropNames.has(prop.name)) {
|
|
635
|
-
errors.push(`Duplicate common event property name: "${prop.name}"`);
|
|
636
|
-
}
|
|
637
|
-
commonPropNames.add(prop.name);
|
|
638
|
-
}
|
|
639
|
-
const userPropNames = /* @__PURE__ */ new Set();
|
|
640
|
-
for (const prop of d.user_properties) {
|
|
641
|
-
if (!VALID_PROP_TYPES.has(prop.type)) {
|
|
642
|
-
errors.push(`User property "${prop.name}" has invalid type: "${prop.type}"`);
|
|
643
|
-
}
|
|
644
|
-
if (prop.update_type && !VALID_UPDATE_TYPES.has(prop.update_type)) {
|
|
645
|
-
errors.push(`User property "${prop.name}" has invalid update_type: "${prop.update_type}"`);
|
|
646
|
-
}
|
|
647
|
-
if (userPropNames.has(prop.name)) {
|
|
648
|
-
errors.push(`Duplicate user property name: "${prop.name}"`);
|
|
649
|
-
}
|
|
650
|
-
userPropNames.add(prop.name);
|
|
651
|
-
}
|
|
652
|
-
for (const evt of d.events) {
|
|
653
|
-
if (!evt.prop_names) continue;
|
|
654
|
-
for (const propName of evt.prop_names) {
|
|
655
|
-
if (propName.startsWith("#")) continue;
|
|
656
|
-
if (!eventPropNames.has(propName)) {
|
|
657
|
-
errors.push(`Event "${evt.event_name}" references unknown event property "${propName}"`);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
const eventDisplayNames = /* @__PURE__ */ new Map();
|
|
662
|
-
for (const prop of eventProps) {
|
|
663
|
-
if (prop.display_name) {
|
|
664
|
-
const names = eventDisplayNames.get(prop.display_name) || [];
|
|
665
|
-
names.push(prop.name);
|
|
666
|
-
eventDisplayNames.set(prop.display_name, names);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
for (const [displayName, names] of eventDisplayNames) {
|
|
670
|
-
if (names.length > 1) {
|
|
671
|
-
errors.push(`Display name "${displayName}" is used by multiple event properties: ${names.join(", ")}`);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
const commonDisplayNames = /* @__PURE__ */ new Map();
|
|
675
|
-
for (const prop of commonProps) {
|
|
676
|
-
if (prop.display_name) {
|
|
677
|
-
const names = commonDisplayNames.get(prop.display_name) || [];
|
|
678
|
-
names.push(prop.name);
|
|
679
|
-
commonDisplayNames.set(prop.display_name, names);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
for (const [displayName, names] of commonDisplayNames) {
|
|
683
|
-
if (names.length > 1) {
|
|
684
|
-
errors.push(`Display name "${displayName}" is used by multiple common properties: ${names.join(", ")}`);
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
const userDisplayNames = /* @__PURE__ */ new Map();
|
|
688
|
-
for (const prop of d.user_properties) {
|
|
689
|
-
if (prop.display_name) {
|
|
690
|
-
const names = userDisplayNames.get(prop.display_name) || [];
|
|
691
|
-
names.push(prop.name);
|
|
692
|
-
userDisplayNames.set(prop.display_name, names);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
for (const [displayName, names] of userDisplayNames) {
|
|
696
|
-
if (names.length > 1) {
|
|
697
|
-
errors.push(`Display name "${displayName}" is used by multiple user properties: ${names.join(", ")}`);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
const compositeChildren = /* @__PURE__ */ new Map();
|
|
701
|
-
for (const prop of eventProps) {
|
|
702
|
-
if (prop.type === "array_row" || prop.type === "object") {
|
|
703
|
-
compositeChildren.set(prop.name, /* @__PURE__ */ new Set());
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
for (const prop of eventProps) {
|
|
707
|
-
if (prop.name.includes(".")) {
|
|
708
|
-
const parent = prop.name.split(".")[0];
|
|
709
|
-
const children = compositeChildren.get(parent);
|
|
710
|
-
if (children) {
|
|
711
|
-
children.add(prop.name);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
for (const evt of d.events) {
|
|
716
|
-
if (!evt.prop_names) continue;
|
|
717
|
-
for (const parentName of compositeProps) {
|
|
718
|
-
if (evt.prop_names.includes(parentName)) {
|
|
719
|
-
const eventChildren = evt.prop_names.filter((p) => p.startsWith(parentName + "."));
|
|
720
|
-
const expectedChildren = compositeChildren.get(parentName);
|
|
721
|
-
if (expectedChildren && eventChildren.length > 0) {
|
|
722
|
-
for (const child of expectedChildren) {
|
|
723
|
-
if (!eventChildren.includes(child)) {
|
|
724
|
-
errors.push(`Event "${evt.event_name}" uses "${parentName}" but missing child "${child}"`);
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
const childPropTypes = /* @__PURE__ */ new Map();
|
|
732
|
-
for (const prop of eventProps) {
|
|
733
|
-
if (prop.name.includes(".")) {
|
|
734
|
-
const childName = prop.name;
|
|
735
|
-
const existing = childPropTypes.get(childName);
|
|
736
|
-
if (existing) {
|
|
737
|
-
if (existing.type !== prop.type) {
|
|
738
|
-
errors.push(`Child property "${childName}" has inconsistent types: "${existing.type}" vs "${prop.type}" (used in events: ${existing.events.join(", ")})`);
|
|
739
|
-
}
|
|
740
|
-
} else {
|
|
741
|
-
childPropTypes.set(childName, { type: prop.type, events: [] });
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
validateCompositeRules(eventProps, "Event property", errors);
|
|
746
|
-
validateCompositeRules(d.user_properties, "User property", errors);
|
|
747
|
-
if (errors.length > 0) {
|
|
748
|
-
throw new Error(`Draft validation failed:
|
|
749
|
-
${errors.map((e) => " - " + e).join("\n")}`);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
function validateCompositeRules(props, poolLabel, errors) {
|
|
753
|
-
const composite = new Set(
|
|
754
|
-
props.filter((prop) => prop.type === "array_row" || prop.type === "object").map((prop) => prop.name)
|
|
755
|
-
);
|
|
756
|
-
for (const parent of composite) {
|
|
757
|
-
if (!props.some((prop) => prop.name.startsWith(`${parent}.`))) {
|
|
758
|
-
errors.push(`${poolLabel} "${parent}" has no child properties (object/array_row require at least one child).`);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
for (const prop of props) {
|
|
762
|
-
if (!prop.name.includes(".")) continue;
|
|
763
|
-
const parent = prop.name.split(".")[0];
|
|
764
|
-
if (composite.has(parent) && (prop.type === "object" || prop.type === "array_row")) {
|
|
765
|
-
errors.push(`${poolLabel} "${prop.name}" has type "${prop.type}"; composite children must be scalar or array_string (flatten nested objects/arrays further).`);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
async function writeDraftXlsx(d, outPath, locale = "zh") {
|
|
770
|
-
validateDraft(d);
|
|
771
|
-
const workbook = new ExcelJS.Workbook();
|
|
772
|
-
const eventSheet = workbook.addWorksheet(sheetName("event_data", locale));
|
|
773
|
-
eventSheet.addRow([
|
|
774
|
-
headerName("event_name", locale),
|
|
775
|
-
headerName("event_display_name", locale),
|
|
776
|
-
headerName("event_desc", locale),
|
|
777
|
-
headerName("event_tag", locale),
|
|
778
|
-
headerName("platform", locale),
|
|
779
|
-
headerName("prop_name", locale),
|
|
780
|
-
headerName("prop_display_name", locale),
|
|
781
|
-
headerName("prop_type", locale),
|
|
782
|
-
headerName("prop_desc", locale)
|
|
783
|
-
]);
|
|
784
|
-
const propByName = new Map(d.event_properties.map((p) => [p.name, p]));
|
|
785
|
-
const autotrackEvents = d.events.filter((e) => e.source === "autotrack");
|
|
786
|
-
const businessEvents = d.events.filter((e) => e.source !== "autotrack");
|
|
787
|
-
const tagGroups = /* @__PURE__ */ new Map();
|
|
788
|
-
const tagOrder = [];
|
|
789
|
-
for (const evt of businessEvents) {
|
|
790
|
-
const tag = evt.event_tag || "";
|
|
791
|
-
if (!tagGroups.has(tag)) {
|
|
792
|
-
tagGroups.set(tag, []);
|
|
793
|
-
tagOrder.push(tag);
|
|
794
|
-
}
|
|
795
|
-
tagGroups.get(tag).push(evt);
|
|
796
|
-
}
|
|
797
|
-
tagOrder.sort((a, b) => getTagPriority(a) - getTagPriority(b));
|
|
798
|
-
const sorted = [...autotrackEvents];
|
|
799
|
-
for (const tag of tagOrder) {
|
|
800
|
-
for (const evt of tagGroups.get(tag)) {
|
|
801
|
-
sorted.push(evt);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
for (const evt of sorted) {
|
|
805
|
-
const startRow = eventSheet.rowCount + 1;
|
|
806
|
-
const platformStr = evt.platform ? PLATFORM_TO_XLSX[evt.platform] : "";
|
|
807
|
-
if (evt.prop_names.length === 0) {
|
|
808
|
-
eventSheet.addRow([
|
|
809
|
-
evt.event_name,
|
|
810
|
-
evt.display_name ?? "",
|
|
811
|
-
evt.event_desc ?? "",
|
|
812
|
-
evt.event_tag ?? "",
|
|
813
|
-
platformStr,
|
|
814
|
-
"",
|
|
815
|
-
"",
|
|
816
|
-
"",
|
|
817
|
-
""
|
|
818
|
-
]);
|
|
819
|
-
} else {
|
|
820
|
-
for (const propName of evt.prop_names) {
|
|
821
|
-
const prop = propByName.get(propName);
|
|
822
|
-
eventSheet.addRow([
|
|
823
|
-
evt.event_name,
|
|
824
|
-
evt.display_name ?? "",
|
|
825
|
-
evt.event_desc ?? "",
|
|
826
|
-
evt.event_tag ?? "",
|
|
827
|
-
platformStr,
|
|
828
|
-
prop?.name ?? propName,
|
|
829
|
-
prop?.display_name ?? "",
|
|
830
|
-
prop ? typeToDisplay(prop.type, locale) : "",
|
|
831
|
-
prop?.desc ?? ""
|
|
832
|
-
]);
|
|
833
|
-
}
|
|
834
|
-
const endRow = eventSheet.rowCount;
|
|
835
|
-
if (endRow > startRow) {
|
|
836
|
-
for (const col of ["A", "B", "C", "D", "E"]) {
|
|
837
|
-
eventSheet.mergeCells(`${col}${startRow}:${col}${endRow}`);
|
|
838
|
-
}
|
|
839
|
-
for (let r = startRow; r <= endRow; r++) {
|
|
840
|
-
const row = eventSheet.getRow(r);
|
|
841
|
-
for (const col of ["A", "B", "C", "D", "E"]) {
|
|
842
|
-
const cell = row.getCell(col);
|
|
843
|
-
cell.alignment = { ...cell.alignment, vertical: "middle" };
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
autoFitSheet(eventSheet, 50);
|
|
850
|
-
const commonSheet = workbook.addWorksheet(sheetName("common_props", locale));
|
|
851
|
-
commonSheet.addRow([
|
|
852
|
-
headerName("common_prop_name", locale),
|
|
853
|
-
headerName("common_prop_display_name", locale),
|
|
854
|
-
headerName("common_prop_type", locale),
|
|
855
|
-
headerName("common_prop_desc", locale)
|
|
856
|
-
]);
|
|
857
|
-
for (const prop of d.common_event_properties) {
|
|
858
|
-
commonSheet.addRow([
|
|
859
|
-
prop.name,
|
|
860
|
-
prop.display_name ?? "",
|
|
861
|
-
typeToDisplay(prop.type, locale),
|
|
862
|
-
prop.desc ?? ""
|
|
863
|
-
]);
|
|
864
|
-
}
|
|
865
|
-
autoFitSheet(commonSheet, 50);
|
|
866
|
-
const userSheet = workbook.addWorksheet(sheetName("user_data", locale));
|
|
867
|
-
userSheet.addRow([
|
|
868
|
-
headerName("user_prop_name", locale),
|
|
869
|
-
headerName("user_prop_display_name", locale),
|
|
870
|
-
headerName("user_prop_type", locale),
|
|
871
|
-
headerName("update_type", locale),
|
|
872
|
-
headerName("user_prop_desc", locale),
|
|
873
|
-
headerName("prop_tag", locale)
|
|
874
|
-
]);
|
|
875
|
-
for (const prop of d.user_properties) {
|
|
876
|
-
userSheet.addRow([
|
|
877
|
-
prop.name,
|
|
878
|
-
prop.display_name ?? "",
|
|
879
|
-
typeToDisplay(prop.type, locale),
|
|
880
|
-
prop.update_type ?? "user_set",
|
|
881
|
-
// 默认 user_set
|
|
882
|
-
prop.desc ?? "",
|
|
883
|
-
prop.prop_tag ?? ""
|
|
884
|
-
]);
|
|
885
|
-
}
|
|
886
|
-
autoFitSheet(userSheet, 50);
|
|
887
|
-
const userIdSheet = workbook.addWorksheet(sheetName("user_id", locale));
|
|
888
|
-
userIdSheet.addRow([
|
|
889
|
-
headerName("user_id_prop_name", locale),
|
|
890
|
-
headerName("user_id_display_name", locale),
|
|
891
|
-
headerName("user_id_desc", locale),
|
|
892
|
-
headerName("user_id_value_desc", locale)
|
|
893
|
-
]);
|
|
894
|
-
userIdSheet.addRow(["#account_id", t("user_id.account_id_display", {}, locale), t("user_id.system_property", {}, locale), t("user_id.set_to", { field: d.meta.user_identity?.account_id_field ?? "account ID" }, locale)]);
|
|
895
|
-
userIdSheet.addRow(["#distinct_id", t("user_id.distinct_id_display", {}, locale), t("user_id.system_property", {}, locale), t("user_id.auto_generated", {}, locale)]);
|
|
896
|
-
autoFitSheet(userIdSheet, 50);
|
|
897
|
-
await workbook.xlsx.writeFile(outPath);
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
// src/tracking/plan/fix.ts
|
|
901
|
-
function extractErrors(response) {
|
|
902
|
-
const errors = [];
|
|
903
|
-
if (response.data?.eventErrorMap) {
|
|
904
|
-
for (const [errorType, items] of Object.entries(response.data.eventErrorMap)) {
|
|
905
|
-
for (const item of items) {
|
|
906
|
-
errors.push({ ...item, errorType });
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
if (response.data?.userErrorMap) {
|
|
911
|
-
for (const [errorType, items] of Object.entries(response.data.userErrorMap)) {
|
|
912
|
-
for (const item of items) {
|
|
913
|
-
errors.push({ ...item, errorType });
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
return errors;
|
|
918
|
-
}
|
|
919
|
-
function fixDisplayDuplicate(draft, errors) {
|
|
920
|
-
const duplicateDisplayNames = /* @__PURE__ */ new Map();
|
|
921
|
-
for (const error of errors) {
|
|
922
|
-
if (error.errorType === "event_prop_display_duplicate") {
|
|
923
|
-
const names = duplicateDisplayNames.get(error.value) || [];
|
|
924
|
-
names.push(error.value);
|
|
925
|
-
duplicateDisplayNames.set(error.value, names);
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
for (const prop of draft.event_properties) {
|
|
929
|
-
if (duplicateDisplayNames.has(prop.display_name || "")) {
|
|
930
|
-
const eventsUsingProp = draft.events.filter((e) => e.prop_names.includes(prop.name));
|
|
931
|
-
if (prop.name.includes(".")) {
|
|
932
|
-
prop.display_name = `\u660E\u7EC6${prop.display_name}`;
|
|
933
|
-
} else if (eventsUsingProp.length > 0) {
|
|
934
|
-
prop.display_name = `${prop.display_name}${t("fix.detail_suffix")}`;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
function fixArrayRowConsistency(draft, errors) {
|
|
940
|
-
const compositeChildren = /* @__PURE__ */ new Map();
|
|
941
|
-
const evProps = draft.event_properties ?? draft.common_properties ?? [];
|
|
942
|
-
for (const prop of evProps) {
|
|
943
|
-
if (prop.type === "array_row" || prop.type === "object") {
|
|
944
|
-
compositeChildren.set(prop.name, []);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
for (const prop of evProps) {
|
|
948
|
-
if (prop.name.includes(".")) {
|
|
949
|
-
const parent = prop.name.split(".")[0];
|
|
950
|
-
const children = compositeChildren.get(parent);
|
|
951
|
-
if (children) {
|
|
952
|
-
children.push(prop.name);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
for (const event of draft.events) {
|
|
957
|
-
if (!event.prop_names) continue;
|
|
958
|
-
const propNamesSet = new Set(event.prop_names);
|
|
959
|
-
for (const [parentName, children] of compositeChildren) {
|
|
960
|
-
if (propNamesSet.has(parentName)) {
|
|
961
|
-
for (const child of children) {
|
|
962
|
-
if (!propNamesSet.has(child)) {
|
|
963
|
-
event.prop_names.push(child);
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
const parentProps = event.prop_names.filter(
|
|
967
|
-
(p) => p === parentName || p.startsWith(parentName + ".")
|
|
968
|
-
);
|
|
969
|
-
const sorted = [parentName, ...children.filter((c) => event.prop_names.includes(c))];
|
|
970
|
-
event.prop_names = event.prop_names.filter(
|
|
971
|
-
(p) => !p.startsWith(parentName) || p === parentName
|
|
972
|
-
);
|
|
973
|
-
const idx = event.prop_names.indexOf(parentName);
|
|
974
|
-
if (idx >= 0) {
|
|
975
|
-
event.prop_names.splice(idx, 1, ...sorted);
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
function fixUnknownPropRefs(draft) {
|
|
982
|
-
const fixed = [];
|
|
983
|
-
const props = draft.event_properties ?? draft.common_properties ?? [];
|
|
984
|
-
const eventPropNames = new Set(props.map((p) => p.name));
|
|
985
|
-
for (const event of draft.events) {
|
|
986
|
-
if (!event.prop_names) continue;
|
|
987
|
-
const removed = [];
|
|
988
|
-
event.prop_names = event.prop_names.filter((pn) => {
|
|
989
|
-
if (pn.startsWith("#")) return true;
|
|
990
|
-
if (eventPropNames.has(pn)) return true;
|
|
991
|
-
removed.push(pn);
|
|
992
|
-
return false;
|
|
993
|
-
});
|
|
994
|
-
if (removed.length > 0) {
|
|
995
|
-
fixed.push(...removed.map((r) => `Removed unknown prop "${r}" from event "${event.event_name}"`));
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return fixed;
|
|
999
|
-
}
|
|
1000
|
-
function fixDisplayNameDuplicates(draft) {
|
|
1001
|
-
const fixed = [];
|
|
1002
|
-
const pools = [
|
|
1003
|
-
{ name: "event_properties", items: draft.event_properties ?? draft.common_properties ?? [] },
|
|
1004
|
-
{ name: "common_event_properties", items: draft.common_event_properties ?? draft.common_properties ?? [] },
|
|
1005
|
-
{ name: "user_properties", items: draft.user_properties ?? [] }
|
|
1006
|
-
];
|
|
1007
|
-
for (const pool of pools) {
|
|
1008
|
-
const displayMap = /* @__PURE__ */ new Map();
|
|
1009
|
-
for (let i = 0; i < pool.items.length; i++) {
|
|
1010
|
-
const dn = pool.items[i].display_name;
|
|
1011
|
-
if (!dn) continue;
|
|
1012
|
-
const list = displayMap.get(dn) || [];
|
|
1013
|
-
list.push(i);
|
|
1014
|
-
displayMap.set(dn, list);
|
|
1015
|
-
}
|
|
1016
|
-
for (const [displayName, indices] of displayMap) {
|
|
1017
|
-
if (indices.length <= 1) continue;
|
|
1018
|
-
for (let j = 1; j < indices.length; j++) {
|
|
1019
|
-
const prop = pool.items[indices[j]];
|
|
1020
|
-
const newDisplayName = `${displayName} (${prop.name})`;
|
|
1021
|
-
prop.display_name = newDisplayName;
|
|
1022
|
-
fixed.push(`Disambiguated display name "${displayName}" \u2192 "${newDisplayName}" in ${pool.name}`);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
return fixed;
|
|
1027
|
-
}
|
|
1028
|
-
function fixCrossPoolDisplayNameInconsistency(draft) {
|
|
1029
|
-
const fixed = [];
|
|
1030
|
-
const commonProps = draft.common_event_properties ?? [];
|
|
1031
|
-
const eventProps = draft.event_properties ?? [];
|
|
1032
|
-
for (const cp of commonProps) {
|
|
1033
|
-
if (!cp.display_name) continue;
|
|
1034
|
-
const ep = eventProps.find((p) => p.name === cp.name);
|
|
1035
|
-
if (!ep) continue;
|
|
1036
|
-
if (ep.display_name && ep.display_name !== cp.display_name) {
|
|
1037
|
-
const oldName = ep.display_name;
|
|
1038
|
-
ep.display_name = cp.display_name;
|
|
1039
|
-
fixed.push(
|
|
1040
|
-
`Aligned display_name for "${cp.name}" in event_properties: "${oldName}" \u2192 "${cp.display_name}" (from common_event_properties)`
|
|
1041
|
-
);
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
return fixed;
|
|
1045
|
-
}
|
|
1046
|
-
function fixEventPlatforms(draft) {
|
|
1047
|
-
const fixed = [];
|
|
1048
|
-
const mode = draft.meta.sdk_integration_mode;
|
|
1049
|
-
if (mode !== "client_only" && mode !== "server_only") return fixed;
|
|
1050
|
-
const targetPlatform = mode === "client_only" ? "client" : "server";
|
|
1051
|
-
let count = 0;
|
|
1052
|
-
for (const event of draft.events) {
|
|
1053
|
-
if (!event.platform) {
|
|
1054
|
-
event.platform = targetPlatform;
|
|
1055
|
-
count++;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
if (count > 0) {
|
|
1059
|
-
fixed.push(
|
|
1060
|
-
`Auto-filled platform="${targetPlatform}" for ${count} event(s) based on sdk_integration_mode="${mode}"`
|
|
1061
|
-
);
|
|
1062
|
-
}
|
|
1063
|
-
return fixed;
|
|
1064
|
-
}
|
|
1065
|
-
function fixEventPropNameInvalid(draft, errors) {
|
|
1066
|
-
const invalidNames = /* @__PURE__ */ new Set();
|
|
1067
|
-
for (const error of errors) {
|
|
1068
|
-
if (error.errorType === "event_prop_name_invalid") {
|
|
1069
|
-
invalidNames.add(error.value);
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
for (const prop of draft.event_properties) {
|
|
1073
|
-
if (invalidNames.has(prop.name)) {
|
|
1074
|
-
const fixedName = prop.name.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase();
|
|
1075
|
-
const oldName = prop.name;
|
|
1076
|
-
prop.name = fixedName;
|
|
1077
|
-
for (const event of draft.events) {
|
|
1078
|
-
const idx = event.prop_names.indexOf(oldName);
|
|
1079
|
-
if (idx >= 0) {
|
|
1080
|
-
event.prop_names[idx] = fixedName;
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
if (prop.display_name && !prop.display_name.includes("(")) {
|
|
1084
|
-
prop.display_name = `${prop.display_name}${t("fix.auto_fix_suffix")}`;
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
function fixEventNameDuplicate(draft, errors) {
|
|
1090
|
-
const duplicateEvents = /* @__PURE__ */ new Set();
|
|
1091
|
-
for (const error of errors) {
|
|
1092
|
-
if (error.errorType === "event_name_duplicate") {
|
|
1093
|
-
duplicateEvents.add(error.value);
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1097
|
-
draft.events = draft.events.filter((event) => {
|
|
1098
|
-
if (duplicateEvents.has(event.event_name)) {
|
|
1099
|
-
if (seen.has(event.event_name)) {
|
|
1100
|
-
return false;
|
|
1101
|
-
}
|
|
1102
|
-
seen.add(event.event_name);
|
|
1103
|
-
}
|
|
1104
|
-
return true;
|
|
1105
|
-
});
|
|
1106
|
-
}
|
|
1107
|
-
function fixDraft(draft, response) {
|
|
1108
|
-
const errors = extractErrors(response);
|
|
1109
|
-
const fixed = [];
|
|
1110
|
-
if (errors.length === 0) {
|
|
1111
|
-
return fixed;
|
|
1112
|
-
}
|
|
1113
|
-
const errorTypes = new Set(errors.map((e) => e.errorType));
|
|
1114
|
-
if (errorTypes.has("event_prop_display_duplicate")) {
|
|
1115
|
-
fixDisplayDuplicate(draft, errors);
|
|
1116
|
-
fixed.push(t("fix.display_name_dedup"));
|
|
1117
|
-
}
|
|
1118
|
-
if (errorTypes.has("complex_event_property_should_has_same_child_property")) {
|
|
1119
|
-
fixArrayRowConsistency(draft, errors);
|
|
1120
|
-
fixed.push(t("fix.array_row_consistency"));
|
|
1121
|
-
}
|
|
1122
|
-
if (errorTypes.has("event_prop_name_invalid")) {
|
|
1123
|
-
fixEventPropNameInvalid(draft, errors);
|
|
1124
|
-
fixed.push(t("fix.event_prop_name_invalid"));
|
|
1125
|
-
}
|
|
1126
|
-
if (errorTypes.has("event_name_duplicate")) {
|
|
1127
|
-
fixEventNameDuplicate(draft, errors);
|
|
1128
|
-
fixed.push(t("fix.event_name_duplicate"));
|
|
1129
|
-
}
|
|
1130
|
-
return fixed;
|
|
1131
|
-
}
|
|
1132
|
-
function validateAndFix(draft) {
|
|
1133
|
-
const fixed = [];
|
|
1134
|
-
const unknownFixes = fixUnknownPropRefs(draft);
|
|
1135
|
-
if (unknownFixes.length > 0) {
|
|
1136
|
-
fixed.push(t("fix.unknown_prop_ref"));
|
|
1137
|
-
}
|
|
1138
|
-
const displayFixes = fixDisplayNameDuplicates(draft);
|
|
1139
|
-
if (displayFixes.length > 0) {
|
|
1140
|
-
fixed.push(t("fix.display_name_dedup"));
|
|
1141
|
-
}
|
|
1142
|
-
const crossPoolFixes = fixCrossPoolDisplayNameInconsistency(draft);
|
|
1143
|
-
if (crossPoolFixes.length > 0) {
|
|
1144
|
-
fixed.push(`Cross-pool display_name consistency: ${crossPoolFixes.length} property(s) aligned`);
|
|
1145
|
-
}
|
|
1146
|
-
const platformFixes = fixEventPlatforms(draft);
|
|
1147
|
-
if (platformFixes.length > 0) {
|
|
1148
|
-
fixed.push(...platformFixes);
|
|
1149
|
-
}
|
|
1150
|
-
const compositeChildren = /* @__PURE__ */ new Map();
|
|
1151
|
-
const evProps = draft.event_properties ?? draft.common_properties ?? [];
|
|
1152
|
-
for (const prop of evProps) {
|
|
1153
|
-
if (prop.type === "array_row" || prop.type === "object") {
|
|
1154
|
-
compositeChildren.set(prop.name, []);
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
for (const prop of evProps) {
|
|
1158
|
-
if (prop.name.includes(".")) {
|
|
1159
|
-
const parent = prop.name.split(".")[0];
|
|
1160
|
-
const children = compositeChildren.get(parent);
|
|
1161
|
-
if (children) {
|
|
1162
|
-
children.push(prop.name);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
let needFix = false;
|
|
1167
|
-
for (const event of draft.events) {
|
|
1168
|
-
if (!event.prop_names) continue;
|
|
1169
|
-
for (const [parentName, children] of compositeChildren) {
|
|
1170
|
-
if (event.prop_names.includes(parentName)) {
|
|
1171
|
-
for (const child of children) {
|
|
1172
|
-
if (!event.prop_names.includes(child)) {
|
|
1173
|
-
needFix = true;
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
if (needFix) {
|
|
1180
|
-
fixArrayRowConsistency(draft, []);
|
|
1181
|
-
fixed.push(t("fix.array_row_consistency"));
|
|
1182
|
-
}
|
|
1183
|
-
return fixed;
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
export {
|
|
1187
|
-
detectCliLocale,
|
|
1188
|
-
allSheetNames,
|
|
1189
|
-
allHeaderNames,
|
|
1190
|
-
displayToType,
|
|
1191
|
-
getPackageRoot,
|
|
1192
|
-
t,
|
|
1193
|
-
validateDraft,
|
|
1194
|
-
writeDraftXlsx,
|
|
1195
|
-
extractErrors,
|
|
1196
|
-
fixDraft,
|
|
1197
|
-
validateAndFix
|
|
1198
|
-
};
|