@thinkingai/ae-cli 6.1.17 → 6.1.19
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-77BUFLGC.js → auth-QPEVVBKT.js} +20 -15
- package/dist/auth-UMJAA72O.js +15 -0
- package/dist/{capability-72DTW5M2.js → capability-ASI62I4A.js} +53 -15
- package/dist/{chunk-UW5UN47B.js → chunk-533JK3YX.js} +2 -0
- package/dist/{chunk-UOUS37JQ.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-DAVKYVMW.js → chunk-B5HMQAOM.js} +31 -540
- package/dist/{chunk-VR3LCBHW.js → chunk-DKEXH6Q5.js} +6 -5
- package/dist/{chunk-VTWMIC5L.js → chunk-E2JKXMVO.js} +2 -0
- package/dist/{chunk-LYVNONC4.js → chunk-FR2EDAQM.js} +36 -0
- package/dist/{chunk-ILIU36SU.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-GT46FPXN.js → chunk-KEWVSO64.js} +18 -8
- package/dist/chunk-KZ6ZHF5J.js +294 -0
- package/dist/chunk-O6K2ODUE.js +318 -0
- package/dist/chunk-QL6R6TSK.js +25215 -0
- package/dist/{chunk-4SGZG4XY.js → chunk-RWXIXOZG.js} +28 -13
- package/dist/{chunk-YA6SMTXG.js → chunk-S5PONFBM.js} +5 -4
- package/dist/{chunk-4NN5IWVN.js → chunk-T6OSFQZD.js} +2 -0
- package/dist/{chunk-PTE56QPL.js → chunk-TKHSULJT.js} +6 -0
- package/dist/{chunk-6EIJSNBD.js → chunk-Y74WTIKJ.js} +2 -0
- package/dist/{client-TKG4WBHN.js → client-N7NGZUNI.js} +6 -4
- package/dist/{community-report-client-FI4LNVYS.js → community-report-client-6OL6GBQW.js} +3 -3
- package/dist/{config-RE6CMGPK.js → config-XNMACCKX.js} +10 -8
- package/dist/{data-integration-XQYB4X4F.js → data-integration-4NZGZ45E.js} +2502 -272
- package/dist/index.js +137 -1245
- package/dist/{local-data-upload-client-BWHSUQQK.js → local-data-upload-client-EFHDLXFG.js} +3 -3
- package/dist/{memory-YK33G4T7.js → memory-HBJQ2GC5.js} +8 -7
- package/dist/{metadata-UILXHBWF.js → metadata-62EWBEIG.js} +12 -11
- package/dist/{model-NR3JHFSJ.js → model-BHLJ2QMT.js} +10 -9
- package/dist/personal-semantic-preference-JBVMAI7L.js +240 -0
- package/dist/project-semantic-BQ4MPUS5.js +1115 -0
- package/dist/sync-MUWPRM5I.js +522 -0
- package/dist/{te-agent-4BKBODMF.js → te-agent-WQZTMEK4.js} +12 -10
- package/dist/{te-analysis-O6DCO6BS.js → te-analysis-MNCG65LU.js} +534 -48
- package/dist/{te-community-HLC43QKH.js → te-community-BNE6KREL.js} +8 -7
- package/dist/{te-dataops-EJP56W3K.js → te-dataops-TXLKM2W6.js} +469 -68
- package/dist/{te-engage-FGBGQ4IY.js → te-engage-TPKLRVTL.js} +84 -10
- package/dist/{te-experiment-SO5MPDMJ.js → te-experiment-6BYKTCY7.js} +303 -12
- package/dist/{te-kb-SQCLHG6X.js → te-kb-BUD6N3NI.js} +312 -25
- package/dist/{te-system-YARIK4S5.js → te-system-44LZJDTQ.js} +573 -37
- package/dist/{te-team-EFKWYKMK.js → te-team-XMP47YXE.js} +10 -7
- package/dist/{update-OGPSZM5A.js → update-UODFOZ4P.js} +9 -7
- package/package.json +18 -9
- package/skills/ae-agent/SKILL.md +3 -4
- package/skills/ae-agent/references/edit-skill.md +3 -0
- package/skills/ae-agent/references/get-skill-content.md +1 -1
- package/skills/ae-agent/references/rescan-skills.md +15 -13
- package/skills/ae-agent/references/upload-skill.md +7 -4
- package/skills/ae-analysis/SKILL.md +45 -4
- package/skills/ae-analysis/metadata_resolution.md +38 -4
- package/skills/ae-analysis/references/analysis_data_retrieval.md +29 -0
- package/skills/ae-analysis/references/analysis_gateway_assets.md +1 -1
- package/skills/ae-analysis/references/asset_authentication_export.md +22 -0
- package/skills/ae-analysis/references/asset_authentication_list.md +18 -14
- package/skills/ae-analysis/references/asset_authentication_update.md +29 -14
- package/skills/ae-analysis/references/audience_models.md +18 -0
- package/skills/ae-analysis/references/command_index.md +19 -11
- package/skills/ae-analysis/references/dashboard_get.md +18 -1
- package/skills/ae-analysis/references/dashboard_update.md +3 -0
- package/skills/ae-analysis/references/personal_semantic_preference_add.md +23 -0
- package/skills/ae-analysis/references/personal_semantic_preference_delete.md +17 -0
- package/skills/ae-analysis/references/personal_semantic_preference_get.md +19 -0
- package/skills/ae-analysis/references/personal_semantic_preference_list.md +21 -0
- package/skills/ae-analysis/references/personal_semantic_preference_update.md +19 -0
- 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 +24 -4
- package/skills/ae-data-integration/references/custom-layer.md +93 -0
- package/skills/ae-data-integration/references/error-handling.md +145 -0
- package/skills/ae-data-integration/references/handoff.md +77 -18
- package/skills/ae-data-integration/references/local-analysis.md +1 -1
- package/skills/ae-data-integration/references/reuse.md +9 -5
- package/skills/ae-data-integration/references/sink-upload.md +1 -1
- package/skills/ae-data-integration/references/source-inspect.md +35 -13
- package/skills/ae-data-integration/references/tracking-plan.md +7 -5
- package/skills/ae-data-integration/references/transform.md +12 -10
- package/skills/ae-data-integration/references/ue-mapping.md +33 -11
- 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 +5 -0
- package/skills/ae-engage/references/build-task-save-guide.md +14 -1
- package/skills/ae-engage/references/save-flow.md +37 -1
- package/skills/ae-engage/references/save-task.md +88 -0
- package/skills/ae-experiment/SKILL.md +14 -4
- package/skills/ae-experiment/references/manage_feature_whitelist.md +66 -0
- package/skills/ae-experiment/references/manage_guardrail_metrics.md +26 -0
- package/skills/ae-experiment/references/save_experiment.md +1 -1
- package/skills/ae-experiment/references/save_metric.md +20 -8
- package/skills/ae-kb/SKILL.md +121 -10
- package/skills/ae-project-semantic/SKILL.md +193 -0
- package/skills/ae-project-semantic/references/query-routing-v5.md +165 -0
- package/skills/ae-project-semantic/references/recommendation-quality.md +68 -0
- package/skills/ae-system/SKILL.md +28 -30
- package/skills/ae-system/references/channel-management.md +303 -0
- package/dist/auth-2WTQOP77.js +0 -14
- package/dist/capability-PJHNI4GJ.js +0 -315
- package/dist/chunk-4KVPKXFX.js +0 -98
- package/dist/chunk-C4MGVGJW.js +0 -13
- package/dist/chunk-P3FGXJTU.js +0 -349
- package/dist/chunk-QGM4M3NI.js +0 -37
- package/dist/chunk-RGKJGKT7.js +0 -71
- package/dist/chunk-SAU3QFIQ.js +0 -556
- package/dist/chunk-VPKZ7I72.js +0 -509
- package/dist/chunk-ZZUOD757.js +0 -598
- package/dist/memory-CHRU2F7W.js +0 -893
- package/dist/metadata-XXR34N5P.js +0 -339
- package/dist/model-K3KLWIW6.js +0 -139
- package/dist/sync-FCKOVWWS.js +0 -10261
- package/dist/te-agent-HLW4VTQK.js +0 -3893
- package/dist/te-analysis-ZMNGOVNW.js +0 -8958
- package/dist/te-community-6HPBWJUZ.js +0 -1859
- package/dist/te-dataops-HDRUXY4K.js +0 -2208
- package/dist/te-engage-RAK5PESW.js +0 -4898
- package/dist/te-experiment-VZF7BT6G.js +0 -770
- package/dist/te-system-Z77IKZFN.js +0 -2213
package/dist/index.js
CHANGED
|
@@ -1,46 +1,62 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
allHeaderNames,
|
|
4
|
+
allSheetNames,
|
|
5
|
+
detectCliLocale,
|
|
6
|
+
displayToType,
|
|
7
|
+
extractErrors,
|
|
8
|
+
fixDraft,
|
|
9
|
+
getPackageRoot,
|
|
10
|
+
t,
|
|
11
|
+
validateAndFix,
|
|
12
|
+
validateDraft,
|
|
13
|
+
writeDraftXlsx
|
|
14
|
+
} from "./chunk-QL6R6TSK.js";
|
|
1
15
|
import {
|
|
2
16
|
getLocalCliPackageInfo
|
|
3
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-E2JKXMVO.js";
|
|
4
18
|
import {
|
|
5
19
|
requiresConfirmation
|
|
6
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-AMBFK2K3.js";
|
|
21
|
+
import "./chunk-B5HMQAOM.js";
|
|
7
22
|
import {
|
|
8
23
|
TeAgentApiError,
|
|
9
24
|
TeAgentCredentialsError
|
|
10
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-6QK7SYYY.js";
|
|
11
26
|
import {
|
|
12
27
|
formatCapabilityMissCompatHint,
|
|
13
28
|
printError,
|
|
14
29
|
printOutput,
|
|
15
30
|
runHostCompatCheck
|
|
16
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-KEWVSO64.js";
|
|
17
32
|
import {
|
|
18
33
|
CapabilityGatewayError,
|
|
19
34
|
executeCapability,
|
|
20
35
|
uploadInputFileBytes
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-GJXRF7Y6.js";
|
|
37
|
+
import "./chunk-Y74WTIKJ.js";
|
|
23
38
|
import {
|
|
24
39
|
clearCliToken,
|
|
25
40
|
getCliToken
|
|
26
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-RWXIXOZG.js";
|
|
27
42
|
import {
|
|
28
43
|
SecureStoreAuthError,
|
|
44
|
+
resolveHost
|
|
45
|
+
} from "./chunk-O6K2ODUE.js";
|
|
46
|
+
import {
|
|
29
47
|
getActiveHost,
|
|
30
48
|
getConfigDir,
|
|
31
|
-
resolveHost,
|
|
32
49
|
safeJsonParse
|
|
33
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-KZ6ZHF5J.js";
|
|
34
51
|
import {
|
|
35
52
|
CliValidationError,
|
|
36
53
|
CommunityReportError,
|
|
37
54
|
LocalDataUploadError,
|
|
38
55
|
PermissionError
|
|
39
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-533JK3YX.js";
|
|
40
57
|
import {
|
|
41
58
|
logger
|
|
42
|
-
} from "./chunk-
|
|
43
|
-
import "./chunk-QGM4M3NI.js";
|
|
59
|
+
} from "./chunk-FR2EDAQM.js";
|
|
44
60
|
|
|
45
61
|
// src/index.ts
|
|
46
62
|
import { Command as CommanderCommand } from "commander";
|
|
@@ -55,6 +71,31 @@ function missingRequiredFlagsError(cmdName, missing) {
|
|
|
55
71
|
const hint = hintParts.length > 0 ? hintParts.join(" ") : `Usage: ae-cli ${cmdName} ${names.map((name) => `${name} <value>`).join(" ")}`;
|
|
56
72
|
return { message, hint };
|
|
57
73
|
}
|
|
74
|
+
function readSkillCurrentVersion(body) {
|
|
75
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return void 0;
|
|
76
|
+
const currentVersion = body.currentVersion;
|
|
77
|
+
if (typeof currentVersion !== "string") return void 0;
|
|
78
|
+
return /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(currentVersion) ? currentVersion : void 0;
|
|
79
|
+
}
|
|
80
|
+
function teAgentApiErrorPresentation(err) {
|
|
81
|
+
if (err.code === "SKILL_VERSION_CONFLICT") {
|
|
82
|
+
const currentVersion = readSkillCurrentVersion(err.body);
|
|
83
|
+
return {
|
|
84
|
+
message: "The Skill content changed, and the new version must be greater than the current version.",
|
|
85
|
+
code: err.code,
|
|
86
|
+
hint: currentVersion ? `Retry with --version set to a major.minor version greater than ${currentVersion}.` : "Retry with --version set to a major.minor version greater than the current Skill version.",
|
|
87
|
+
...currentVersion ? { meta: { currentVersion } } : {}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (err.code === "SKILL_HISTORY_CONFLICT") {
|
|
91
|
+
return {
|
|
92
|
+
message: "The Skill cannot be safely updated right now.",
|
|
93
|
+
code: err.code,
|
|
94
|
+
hint: "The Skill cannot be safely updated right now. Please contact your administrator."
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
58
99
|
async function runCommand(cmd, opts, globalOpts) {
|
|
59
100
|
try {
|
|
60
101
|
const ctx = createRuntimeContext(cmd, opts, globalOpts);
|
|
@@ -203,7 +244,14 @@ async function runCommand(cmd, opts, globalOpts) {
|
|
|
203
244
|
} else if (err.status === 401) {
|
|
204
245
|
printError("auth", message, "Run: ae-cli auth login");
|
|
205
246
|
} else {
|
|
206
|
-
|
|
247
|
+
const presentation = teAgentApiErrorPresentation(err);
|
|
248
|
+
printError(
|
|
249
|
+
"api",
|
|
250
|
+
presentation.message ?? message,
|
|
251
|
+
presentation.hint,
|
|
252
|
+
presentation.code,
|
|
253
|
+
presentation.meta
|
|
254
|
+
);
|
|
207
255
|
}
|
|
208
256
|
} else if (looksLikeAuthFailure(message)) {
|
|
209
257
|
printError("auth", message, "Run: ae-cli auth login");
|
|
@@ -237,7 +285,7 @@ function capabilityGatewayHint(err) {
|
|
|
237
285
|
${compatExtra}` : base;
|
|
238
286
|
}
|
|
239
287
|
if (err.httpStatus === 404 && !err.code) {
|
|
240
|
-
const base = "The current host returned 404 for this capability route. Do not keep retrying the same command; verify the backend route/capability deployment.";
|
|
288
|
+
const base = "The current host returned 404 for this capability route. Do not keep retrying the same command; verify the backend route/capability deployment. If --host points directly to a local Common service instead of the deployed gateway, scope AE_CLI_CAPABILITY_GATEWAY_DOMAIN= to this command so it uses /api/cli/v1.";
|
|
241
289
|
return compatExtra ? `${base}
|
|
242
290
|
${compatExtra}` : base;
|
|
243
291
|
}
|
|
@@ -252,21 +300,21 @@ function createRuntimeContext(cmd, opts, globalOpts) {
|
|
|
252
300
|
let _clientModule = null;
|
|
253
301
|
async function getClient() {
|
|
254
302
|
if (!_clientModule) {
|
|
255
|
-
_clientModule = await import("./client-
|
|
303
|
+
_clientModule = await import("./client-N7NGZUNI.js");
|
|
256
304
|
}
|
|
257
305
|
return _clientModule;
|
|
258
306
|
}
|
|
259
307
|
let _communityReportModule = null;
|
|
260
308
|
async function getCommunityReportClient() {
|
|
261
309
|
if (!_communityReportModule) {
|
|
262
|
-
_communityReportModule = await import("./community-report-client-
|
|
310
|
+
_communityReportModule = await import("./community-report-client-6OL6GBQW.js");
|
|
263
311
|
}
|
|
264
312
|
return _communityReportModule;
|
|
265
313
|
}
|
|
266
314
|
let _localDataUploadModule = null;
|
|
267
315
|
async function getLocalDataUploadClient() {
|
|
268
316
|
if (!_localDataUploadModule) {
|
|
269
|
-
_localDataUploadModule = await import("./local-data-upload-client-
|
|
317
|
+
_localDataUploadModule = await import("./local-data-upload-client-EFHDLXFG.js");
|
|
270
318
|
}
|
|
271
319
|
return _localDataUploadModule;
|
|
272
320
|
}
|
|
@@ -328,7 +376,7 @@ function createRuntimeContext(cmd, opts, globalOpts) {
|
|
|
328
376
|
return client.localDataUpload(endpoint, rawBody, options);
|
|
329
377
|
},
|
|
330
378
|
async token() {
|
|
331
|
-
const { getToken } = await import("./auth-
|
|
379
|
+
const { getToken } = await import("./auth-UMJAA72O.js");
|
|
332
380
|
return getToken(ctx.host());
|
|
333
381
|
},
|
|
334
382
|
host() {
|
|
@@ -386,7 +434,7 @@ function registerCommands(program2, commands) {
|
|
|
386
434
|
parent = resourceCmd;
|
|
387
435
|
}
|
|
388
436
|
}
|
|
389
|
-
const sub = parent.command(cmd.command).description(cmd.description);
|
|
437
|
+
const sub = parent.command(cmd.command, { hidden: cmd.hidden === true }).description(cmd.description);
|
|
390
438
|
for (const flag of cmd.flags) {
|
|
391
439
|
const flagStr = buildFlagString(flag);
|
|
392
440
|
if (flag.variadic) {
|
|
@@ -460,886 +508,6 @@ function extractGlobalOptions(program2) {
|
|
|
460
508
|
import { readFile, writeFile, cp } from "fs/promises";
|
|
461
509
|
import path2, { resolve as resolve2 } from "path";
|
|
462
510
|
|
|
463
|
-
// src/tracking/xlsx/write.ts
|
|
464
|
-
import ExcelJS from "exceljs";
|
|
465
|
-
|
|
466
|
-
// src/tracking/i18n/locale.ts
|
|
467
|
-
var VALID_LOCALES = /* @__PURE__ */ new Set(["zh", "en", "ja", "ko"]);
|
|
468
|
-
function normalize(raw) {
|
|
469
|
-
const lower = raw.trim().toLowerCase();
|
|
470
|
-
if (lower.startsWith("zh") || lower.startsWith("cn")) return "zh";
|
|
471
|
-
if (lower.startsWith("ja") || lower.startsWith("jp")) return "ja";
|
|
472
|
-
if (lower.startsWith("ko") || lower.startsWith("kr")) return "ko";
|
|
473
|
-
if (lower.startsWith("en")) return "en";
|
|
474
|
-
if (VALID_LOCALES.has(lower)) return lower;
|
|
475
|
-
return "en";
|
|
476
|
-
}
|
|
477
|
-
var _cliLocale;
|
|
478
|
-
function detectCliLocale() {
|
|
479
|
-
if (_cliLocale) return _cliLocale;
|
|
480
|
-
if (process.env.AE_LANG) {
|
|
481
|
-
_cliLocale = normalize(process.env.AE_LANG);
|
|
482
|
-
return _cliLocale;
|
|
483
|
-
}
|
|
484
|
-
const sys = (process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || "").toLowerCase();
|
|
485
|
-
if (sys) {
|
|
486
|
-
_cliLocale = normalize(sys);
|
|
487
|
-
return _cliLocale;
|
|
488
|
-
}
|
|
489
|
-
_cliLocale = "en";
|
|
490
|
-
return _cliLocale;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// src/tracking/i18n/resources/xlsx/sheets.ts
|
|
494
|
-
var SHEET_NAMES = {
|
|
495
|
-
event_data: {
|
|
496
|
-
zh: "#\u4E8B\u4EF6\u6570\u636E",
|
|
497
|
-
en: "#event data",
|
|
498
|
-
ja: "#\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF",
|
|
499
|
-
ko: "#\uC774\uBCA4\uD2B8 \uB370\uC774\uD130"
|
|
500
|
-
},
|
|
501
|
-
common_props: {
|
|
502
|
-
zh: "#\u516C\u5171\u4E8B\u4EF6\u5C5E\u6027",
|
|
503
|
-
en: "#super property",
|
|
504
|
-
ja: "#\u30D1\u30D6\u30EA\u30C3\u30AF\u30A4\u30D9\u30F3\u30C8\u30D7\u30ED\u30D1\u30C6\u30A3",
|
|
505
|
-
ko: "#\uACF5\uD1B5 \uC774\uBCA4\uD2B8 \uC18D\uC131"
|
|
506
|
-
},
|
|
507
|
-
user_data: {
|
|
508
|
-
zh: "#\u7528\u6237\u6570\u636E",
|
|
509
|
-
en: "#user data",
|
|
510
|
-
ja: "#\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF",
|
|
511
|
-
ko: "#\uC720\uC800 \uB370\uC774\uD130"
|
|
512
|
-
},
|
|
513
|
-
user_id: {
|
|
514
|
-
zh: "#\u7528\u6237ID\u4F53\u7CFB",
|
|
515
|
-
en: "#ID mapping rule",
|
|
516
|
-
ja: "#\u30E6\u30FC\u30B6\u30FCID\u30B7\u30B9\u30C6\u30E0",
|
|
517
|
-
ko: "#\uC720\uC800 ID \uCCB4\uACC4"
|
|
518
|
-
}
|
|
519
|
-
};
|
|
520
|
-
function sheetName(key, locale) {
|
|
521
|
-
return SHEET_NAMES[key][locale];
|
|
522
|
-
}
|
|
523
|
-
function allSheetNames(key) {
|
|
524
|
-
return Object.values(SHEET_NAMES[key]);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// src/tracking/i18n/resources/xlsx/headers.ts
|
|
528
|
-
var HEADERS = {
|
|
529
|
-
// === #事件数据 (9 列) ===
|
|
530
|
-
event_name: {
|
|
531
|
-
zh: "\u4E8B\u4EF6\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
532
|
-
en: "Event Name",
|
|
533
|
-
ja: "\u30A4\u30D9\u30F3\u30C8\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
534
|
-
ko: "\uC774\uBCA4\uD2B8 \uC774\uB984 (\uD544\uC218)"
|
|
535
|
-
},
|
|
536
|
-
event_display_name: {
|
|
537
|
-
zh: "\u4E8B\u4EF6\u663E\u793A\u540D",
|
|
538
|
-
en: "Event Display Name",
|
|
539
|
-
ja: "\u30A4\u30D9\u30F3\u30C8\u8868\u793A\u540D",
|
|
540
|
-
ko: "\uC774\uBCA4\uD2B8 \uD45C\uC2DC \uC774\uB984"
|
|
541
|
-
},
|
|
542
|
-
event_desc: {
|
|
543
|
-
zh: "\u4E8B\u4EF6\u8BF4\u660E",
|
|
544
|
-
en: "Event Description",
|
|
545
|
-
ja: "\u30A4\u30D9\u30F3\u30C8\u8AAC\u660E",
|
|
546
|
-
ko: "\uC774\uBCA4\uD2B8 \uC124\uBA85"
|
|
547
|
-
},
|
|
548
|
-
event_tag: {
|
|
549
|
-
zh: "\u4E8B\u4EF6\u6807\u7B7E",
|
|
550
|
-
en: "Event Tag",
|
|
551
|
-
ja: "\u30AB\u30C6\u30B4\u30EA",
|
|
552
|
-
ko: "\uC774\uBCA4\uD2B8 \uD0DC\uADF8"
|
|
553
|
-
},
|
|
554
|
-
platform: {
|
|
555
|
-
zh: "\u91C7\u96C6\u7AEF",
|
|
556
|
-
en: "Platform",
|
|
557
|
-
ja: "\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0",
|
|
558
|
-
ko: "\uD50C\uB7AB\uD3FC"
|
|
559
|
-
},
|
|
560
|
-
prop_name: {
|
|
561
|
-
zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
562
|
-
en: "Property Name",
|
|
563
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
564
|
-
ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
|
|
565
|
-
},
|
|
566
|
-
prop_display_name: {
|
|
567
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
568
|
-
en: "Property Display Name",
|
|
569
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
|
|
570
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
571
|
-
},
|
|
572
|
-
prop_type: {
|
|
573
|
-
zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
|
|
574
|
-
en: "Data Type",
|
|
575
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
|
|
576
|
-
ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
|
|
577
|
-
},
|
|
578
|
-
prop_desc: {
|
|
579
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
580
|
-
en: "Property Description",
|
|
581
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
|
|
582
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
583
|
-
},
|
|
584
|
-
// === #公共事件属性 (4 列) ===
|
|
585
|
-
common_prop_name: {
|
|
586
|
-
zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
587
|
-
en: "Property Name",
|
|
588
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
589
|
-
ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
|
|
590
|
-
},
|
|
591
|
-
common_prop_display_name: {
|
|
592
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
593
|
-
en: "Property Display Name",
|
|
594
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
|
|
595
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
596
|
-
},
|
|
597
|
-
common_prop_type: {
|
|
598
|
-
zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
|
|
599
|
-
en: "Data Type",
|
|
600
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
|
|
601
|
-
ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
|
|
602
|
-
},
|
|
603
|
-
common_prop_desc: {
|
|
604
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
605
|
-
en: "Property Description",
|
|
606
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
|
|
607
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
608
|
-
},
|
|
609
|
-
// === #用户数据 (6 列) ===
|
|
610
|
-
user_prop_name: {
|
|
611
|
-
zh: "\u5C5E\u6027\u540D\uFF08\u5FC5\u586B\uFF09",
|
|
612
|
-
en: "Property Name",
|
|
613
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D\uFF08\u5FC5\u9808\uFF09",
|
|
614
|
-
ko: "\uC18D\uC131 \uC774\uB984 (\uD544\uC218)"
|
|
615
|
-
},
|
|
616
|
-
user_prop_display_name: {
|
|
617
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
618
|
-
en: "Property Display Name",
|
|
619
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8868\u793A\u540D",
|
|
620
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
621
|
-
},
|
|
622
|
-
user_prop_type: {
|
|
623
|
-
zh: "\u5C5E\u6027\u7C7B\u578B\uFF08\u5FC5\u586B\uFF09",
|
|
624
|
-
en: "Data Type",
|
|
625
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u30BF\u30A4\u30D7\uFF08\u5FC5\u9808\uFF09",
|
|
626
|
-
ko: "\uC18D\uC131 \uC720\uD615 (\uD544\uC218)"
|
|
627
|
-
},
|
|
628
|
-
update_type: {
|
|
629
|
-
zh: "\u66F4\u65B0\u65B9\u5F0F",
|
|
630
|
-
en: "Update Type",
|
|
631
|
-
ja: "\u66F4\u65B0\u65B9\u6CD5",
|
|
632
|
-
ko: "\uC5C5\uB370\uC774\uD2B8 \uBC29\uC2DD"
|
|
633
|
-
},
|
|
634
|
-
user_prop_desc: {
|
|
635
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
636
|
-
en: "Property Description",
|
|
637
|
-
ja: "\u30D7\u30ED\u30D1\u30C6\u30A3\u8AAC\u660E",
|
|
638
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
639
|
-
},
|
|
640
|
-
prop_tag: {
|
|
641
|
-
zh: "\u5C5E\u6027\u6807\u7B7E",
|
|
642
|
-
en: "Property Tag",
|
|
643
|
-
ja: "\u30AB\u30C6\u30B4\u30EA",
|
|
644
|
-
ko: "\uC18D\uC131 \uD0DC\uADF8"
|
|
645
|
-
},
|
|
646
|
-
// === #用户ID体系 (4 列,不含"游戏类型"前置列) ===
|
|
647
|
-
user_id_prop_name: {
|
|
648
|
-
zh: "\u5C5E\u6027\u540D",
|
|
649
|
-
en: "Property",
|
|
650
|
-
ja: "\u5C5E\u6027\u540D",
|
|
651
|
-
ko: "\uC18D\uC131 \uC774\uB984"
|
|
652
|
-
},
|
|
653
|
-
user_id_display_name: {
|
|
654
|
-
zh: "\u5C5E\u6027\u663E\u793A\u540D",
|
|
655
|
-
en: "Display Name",
|
|
656
|
-
ja: "\u5C5E\u6027\u8868\u793A\u540D",
|
|
657
|
-
ko: "\uC18D\uC131 \uD45C\uC2DC \uC774\uB984"
|
|
658
|
-
},
|
|
659
|
-
user_id_desc: {
|
|
660
|
-
zh: "\u5C5E\u6027\u8BF4\u660E",
|
|
661
|
-
en: "Description",
|
|
662
|
-
ja: "\u5C5E\u6027\u8AAC\u660E",
|
|
663
|
-
ko: "\uC18D\uC131 \uC124\uBA85"
|
|
664
|
-
},
|
|
665
|
-
user_id_value_desc: {
|
|
666
|
-
zh: "\u8D4B\u503C\u8BF4\u660E",
|
|
667
|
-
en: "Value Description",
|
|
668
|
-
ja: "\u4EE3\u5165\u8AAC\u660E",
|
|
669
|
-
ko: "\uAC12 \uC124\uBA85"
|
|
670
|
-
}
|
|
671
|
-
};
|
|
672
|
-
function headerName(key, locale) {
|
|
673
|
-
return HEADERS[key][locale];
|
|
674
|
-
}
|
|
675
|
-
function allHeaderNames(key) {
|
|
676
|
-
return Object.values(HEADERS[key]);
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
// src/tracking/i18n/resources/xlsx/types.ts
|
|
680
|
-
var PROP_TYPE_DISPLAY = {
|
|
681
|
-
string: { zh: "\u6587\u672C", en: "String", ja: "\u30B9\u30C8\u30EA\u30F3\u30B0", ko: "String" },
|
|
682
|
-
number: { zh: "\u6570\u503C", en: "Number", ja: "\u6570\u5024", ko: "Number" },
|
|
683
|
-
bool: { zh: "\u5E03\u5C14", en: "Boolean", ja: "\u30D6\u30FC\u30EB\u5024", ko: "Boolean" },
|
|
684
|
-
datetime: { zh: "\u65F6\u95F4", en: "Date", ja: "\u6642\u9593", ko: "Date" },
|
|
685
|
-
object: { zh: "\u5BF9\u8C61", en: "Row", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8", ko: "Row" },
|
|
686
|
-
array_row: { zh: "\u5BF9\u8C61\u7EC4", en: "Array Row", ja: "\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30B0\u30EB\u30FC\u30D7", ko: "Array Row" },
|
|
687
|
-
array_string: { zh: "\u5217\u8868", en: "List", ja: "\u30EA\u30B9\u30C8", ko: "List" }
|
|
688
|
-
};
|
|
689
|
-
function typeToDisplay(type, locale) {
|
|
690
|
-
return PROP_TYPE_DISPLAY[type][locale];
|
|
691
|
-
}
|
|
692
|
-
var ALL_DISPLAY_TO_TYPE = {};
|
|
693
|
-
for (const [canonical, locales] of Object.entries(PROP_TYPE_DISPLAY)) {
|
|
694
|
-
for (const val of Object.values(locales)) {
|
|
695
|
-
ALL_DISPLAY_TO_TYPE[val] = canonical;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
var ALIASES = {
|
|
699
|
-
// zh alias(行业模板)
|
|
700
|
-
"\u5B57\u7B26\u4E32": "string",
|
|
701
|
-
// en alias(旧值兼容 — 2026-07-15 前生成的老 xlsx)
|
|
702
|
-
"string": "string",
|
|
703
|
-
"number": "number",
|
|
704
|
-
"boolean": "bool",
|
|
705
|
-
"datetime": "datetime",
|
|
706
|
-
"object": "object",
|
|
707
|
-
"object[]": "array_row",
|
|
708
|
-
"string[]": "array_string",
|
|
709
|
-
// en 额外 alias
|
|
710
|
-
"Bool": "bool",
|
|
711
|
-
"DateTime": "datetime",
|
|
712
|
-
"Time": "datetime",
|
|
713
|
-
"Object": "object",
|
|
714
|
-
"Object Array": "array_row",
|
|
715
|
-
"String Array": "array_string",
|
|
716
|
-
// ja alias
|
|
717
|
-
"\u6587\u5B57\u5217": "string",
|
|
718
|
-
"\u30C6\u30AD\u30B9\u30C8": "string",
|
|
719
|
-
"\u30D6\u30FC\u30EB": "bool",
|
|
720
|
-
"\u65E5\u6642": "datetime",
|
|
721
|
-
// ja 旧值兼容
|
|
722
|
-
"\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u914D\u5217": "array_row",
|
|
723
|
-
"\u914D\u5217": "array_string",
|
|
724
|
-
// ko alias
|
|
725
|
-
"\uD14D\uC2A4\uD2B8": "string",
|
|
726
|
-
"\uBB38\uC790\uC5F4": "string",
|
|
727
|
-
"\uC22B\uC790": "number",
|
|
728
|
-
"\uBD80\uC6B8": "bool",
|
|
729
|
-
"\uB0A0\uC9DC\uC2DC\uAC04": "datetime",
|
|
730
|
-
"\uAC1D\uCCB4 \uBC30\uC5F4": "array_row",
|
|
731
|
-
"\uB9AC\uC2A4\uD2B8": "array_string",
|
|
732
|
-
// ko 旧值兼容
|
|
733
|
-
"time": "datetime",
|
|
734
|
-
"object_array": "array_row",
|
|
735
|
-
"string_array": "array_string"
|
|
736
|
-
};
|
|
737
|
-
Object.assign(ALL_DISPLAY_TO_TYPE, ALIASES);
|
|
738
|
-
function displayToType(raw) {
|
|
739
|
-
const trimmed = raw.trim();
|
|
740
|
-
return ALL_DISPLAY_TO_TYPE[trimmed] ?? null;
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
// src/tracking/i18n/translate.ts
|
|
744
|
-
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
745
|
-
import { join as join2 } from "path";
|
|
746
|
-
|
|
747
|
-
// src/tracking/paths.ts
|
|
748
|
-
import { existsSync, readFileSync } from "fs";
|
|
749
|
-
import { dirname, join } from "path";
|
|
750
|
-
import { fileURLToPath } from "url";
|
|
751
|
-
var AE_CLI_PACKAGE_NAMES = /* @__PURE__ */ new Set(["@tant/ae-cli", "@thinkingai/ae-cli"]);
|
|
752
|
-
function isAeCliPackageName(name) {
|
|
753
|
-
return typeof name === "string" && (AE_CLI_PACKAGE_NAMES.has(name) || name.endsWith("/ae-cli"));
|
|
754
|
-
}
|
|
755
|
-
function getPackageRoot() {
|
|
756
|
-
let cur = dirname(fileURLToPath(import.meta.url));
|
|
757
|
-
while (cur !== dirname(cur)) {
|
|
758
|
-
const pj = join(cur, "package.json");
|
|
759
|
-
if (existsSync(pj)) {
|
|
760
|
-
try {
|
|
761
|
-
const pkg2 = JSON.parse(readFileSync(pj, "utf8"));
|
|
762
|
-
if (isAeCliPackageName(pkg2.name)) return cur;
|
|
763
|
-
} catch {
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
cur = dirname(cur);
|
|
767
|
-
}
|
|
768
|
-
throw new Error("Could not locate ae-cli package root");
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
// src/tracking/i18n/translate.ts
|
|
772
|
-
var loaded = /* @__PURE__ */ new Map();
|
|
773
|
-
function i18nFile(locale) {
|
|
774
|
-
const root = getPackageRoot();
|
|
775
|
-
const candidates = [
|
|
776
|
-
join2(root, "dist", "tracking", "i18n", "resources", "cli", `${locale}.json`),
|
|
777
|
-
join2(root, "src", "tracking", "i18n", "resources", "cli", `${locale}.json`)
|
|
778
|
-
];
|
|
779
|
-
for (const p of candidates) {
|
|
780
|
-
if (existsSync2(p)) return p;
|
|
781
|
-
}
|
|
782
|
-
return candidates[candidates.length - 1];
|
|
783
|
-
}
|
|
784
|
-
function loadSync(locale) {
|
|
785
|
-
if (loaded.has(locale)) return loaded.get(locale);
|
|
786
|
-
try {
|
|
787
|
-
const raw = readFileSync2(i18nFile(locale), "utf8");
|
|
788
|
-
const tree = JSON.parse(raw);
|
|
789
|
-
loaded.set(locale, tree);
|
|
790
|
-
return tree;
|
|
791
|
-
} catch {
|
|
792
|
-
if (locale !== "en") {
|
|
793
|
-
return loadSync("en");
|
|
794
|
-
}
|
|
795
|
-
loaded.set("en", {});
|
|
796
|
-
return {};
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
function t(key, params, locale) {
|
|
800
|
-
const loc = locale ?? detectCliLocale();
|
|
801
|
-
const tree = loadSync(loc);
|
|
802
|
-
const parts = key.split(".");
|
|
803
|
-
let node = tree;
|
|
804
|
-
for (const part of parts) {
|
|
805
|
-
if (typeof node !== "object" || node === null) return key;
|
|
806
|
-
node = node[part];
|
|
807
|
-
}
|
|
808
|
-
if (typeof node !== "string") return key;
|
|
809
|
-
if (params) {
|
|
810
|
-
return node.replace(/\{(\w+)\}/g, (_, name) => String(params[name] ?? `{${name}}`));
|
|
811
|
-
}
|
|
812
|
-
return node;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// src/tracking/xlsx/tag-priority.ts
|
|
816
|
-
var TAG_PRIORITY = {
|
|
817
|
-
// Account lifecycle
|
|
818
|
-
"Basic": 1,
|
|
819
|
-
// Core gameplay
|
|
820
|
-
"Battle": 10,
|
|
821
|
-
"Stage": 11,
|
|
822
|
-
"Dungeon": 12,
|
|
823
|
-
"Gacha": 13,
|
|
824
|
-
// Progression & economy
|
|
825
|
-
"Growth": 20,
|
|
826
|
-
"Resource": 21,
|
|
827
|
-
// Monetization
|
|
828
|
-
"Ads": 30,
|
|
829
|
-
"Payment": 31,
|
|
830
|
-
"Subscription": 32,
|
|
831
|
-
// Supporting systems
|
|
832
|
-
"Shop": 40,
|
|
833
|
-
"Quest": 41,
|
|
834
|
-
"Achievement": 42,
|
|
835
|
-
"Check-in": 43,
|
|
836
|
-
"Leaderboard": 44,
|
|
837
|
-
"Guild": 45,
|
|
838
|
-
"Social": 46,
|
|
839
|
-
// Genre-specific (game)
|
|
840
|
-
"Building": 50,
|
|
841
|
-
"Alliance": 51,
|
|
842
|
-
"Equipment": 52,
|
|
843
|
-
"Trade": 53,
|
|
844
|
-
"Revive": 54,
|
|
845
|
-
"Slots": 55,
|
|
846
|
-
"Lottery": 56,
|
|
847
|
-
"Reward": 57,
|
|
848
|
-
// Non-game
|
|
849
|
-
"Discovery": 60,
|
|
850
|
-
"Product": 61,
|
|
851
|
-
"Order": 62,
|
|
852
|
-
"After-sales": 63,
|
|
853
|
-
"Content": 64,
|
|
854
|
-
"Interaction": 65,
|
|
855
|
-
"Relationship": 66,
|
|
856
|
-
"Live": 67,
|
|
857
|
-
"Onboarding": 68,
|
|
858
|
-
"Course": 69,
|
|
859
|
-
"Enrollment": 70,
|
|
860
|
-
"Quiz": 71,
|
|
861
|
-
"Creation": 72,
|
|
862
|
-
"Material": 73,
|
|
863
|
-
"Export": 74,
|
|
864
|
-
"Playback": 75,
|
|
865
|
-
"Withdraw": 76
|
|
866
|
-
};
|
|
867
|
-
var DEFAULT_TAG_PRIORITY = 80;
|
|
868
|
-
var CANONICAL_TAG = {
|
|
869
|
-
// zh
|
|
870
|
-
"\u57FA\u7840\u4E8B\u4EF6": "Basic",
|
|
871
|
-
"\u6218\u6597": "Battle",
|
|
872
|
-
"\u5173\u5361": "Stage",
|
|
873
|
-
"\u526F\u672C": "Dungeon",
|
|
874
|
-
"\u62BD\u5361": "Gacha",
|
|
875
|
-
"\u517B\u6210": "Growth",
|
|
876
|
-
"\u6210\u957F": "Growth",
|
|
877
|
-
"\u8D44\u6E90": "Resource",
|
|
878
|
-
"\u5E7F\u544A": "Ads",
|
|
879
|
-
"\u652F\u4ED8": "Payment",
|
|
880
|
-
"\u8BA2\u9605": "Subscription",
|
|
881
|
-
"\u5546\u57CE": "Shop",
|
|
882
|
-
"\u4EFB\u52A1": "Quest",
|
|
883
|
-
"\u6210\u5C31": "Achievement",
|
|
884
|
-
"\u7B7E\u5230": "Check-in",
|
|
885
|
-
"\u6392\u884C\u699C": "Leaderboard",
|
|
886
|
-
"\u516C\u4F1A": "Guild",
|
|
887
|
-
"\u793E\u4EA4": "Social",
|
|
888
|
-
"\u5EFA\u7B51": "Building",
|
|
889
|
-
"\u8054\u76DF": "Alliance",
|
|
890
|
-
"\u88C5\u5907": "Equipment",
|
|
891
|
-
"\u4EA4\u6613": "Trade",
|
|
892
|
-
"\u590D\u6D3B": "Revive",
|
|
893
|
-
"\u62BD\u5956": "Lottery",
|
|
894
|
-
"\u5956\u52B1": "Reward",
|
|
895
|
-
"\u63D0\u73B0": "Withdraw",
|
|
896
|
-
"\u53D1\u73B0": "Discovery",
|
|
897
|
-
"\u5546\u54C1": "Product",
|
|
898
|
-
"\u8BA2\u5355": "Order",
|
|
899
|
-
"\u552E\u540E": "After-sales",
|
|
900
|
-
"\u5185\u5BB9": "Content",
|
|
901
|
-
"\u4E92\u52A8": "Interaction",
|
|
902
|
-
"\u5173\u7CFB": "Relationship",
|
|
903
|
-
"\u76F4\u64AD": "Live",
|
|
904
|
-
"\u5F15\u5BFC": "Onboarding",
|
|
905
|
-
"\u8BFE\u7A0B": "Course",
|
|
906
|
-
"\u62A5\u540D": "Enrollment",
|
|
907
|
-
"\u6D4B\u9A8C": "Quiz",
|
|
908
|
-
"\u521B\u4F5C": "Creation",
|
|
909
|
-
"\u7D20\u6750": "Material",
|
|
910
|
-
"\u5BFC\u51FA": "Export",
|
|
911
|
-
"\u5185\u5BB9\u64AD\u653E": "Playback",
|
|
912
|
-
// ja
|
|
913
|
-
"\u57FA\u672C\u30A4\u30D9\u30F3\u30C8": "Basic",
|
|
914
|
-
"\u6226\u95D8": "Battle",
|
|
915
|
-
"\u30B9\u30C6\u30FC\u30B8": "Stage",
|
|
916
|
-
"\u30C0\u30F3\u30B8\u30E7\u30F3": "Dungeon",
|
|
917
|
-
"\u30AC\u30C1\u30E3": "Gacha",
|
|
918
|
-
"\u80B2\u6210": "Growth",
|
|
919
|
-
"\u30EA\u30BD\u30FC\u30B9": "Resource",
|
|
920
|
-
"\u5E83\u544A": "Ads",
|
|
921
|
-
"\u652F\u6255\u3044": "Payment",
|
|
922
|
-
"\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3": "Subscription",
|
|
923
|
-
"\u30B7\u30E7\u30C3\u30D7": "Shop",
|
|
924
|
-
"\u30AF\u30A8\u30B9\u30C8": "Quest",
|
|
925
|
-
"\u5B9F\u7E3E": "Achievement",
|
|
926
|
-
"\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3": "Check-in",
|
|
927
|
-
"\u30E9\u30F3\u30AD\u30F3\u30B0": "Leaderboard",
|
|
928
|
-
"\u30AE\u30EB\u30C9": "Guild",
|
|
929
|
-
"\u30BD\u30FC\u30B7\u30E3\u30EB": "Social",
|
|
930
|
-
"\u5EFA\u7BC9": "Building",
|
|
931
|
-
"\u540C\u76DF": "Alliance",
|
|
932
|
-
"\u88C5\u5099": "Equipment",
|
|
933
|
-
"\u30C8\u30EC\u30FC\u30C9": "Trade",
|
|
934
|
-
"\u5FA9\u6D3B": "Revive",
|
|
935
|
-
"\u30B9\u30ED\u30C3\u30C8": "Slots",
|
|
936
|
-
"\u62BD\u9078": "Lottery",
|
|
937
|
-
"\u5831\u916C": "Reward",
|
|
938
|
-
"\u5F15\u304D\u51FA\u3057": "Withdraw",
|
|
939
|
-
"\u767A\u898B": "Discovery",
|
|
940
|
-
"\u6CE8\u6587": "Order",
|
|
941
|
-
"\u30A2\u30D5\u30BF\u30FC\u30B5\u30FC\u30D3\u30B9": "After-sales",
|
|
942
|
-
"\u30B3\u30F3\u30C6\u30F3\u30C4": "Content",
|
|
943
|
-
"\u30A4\u30F3\u30BF\u30E9\u30AF\u30B7\u30E7\u30F3": "Interaction",
|
|
944
|
-
"\u95A2\u4FC2": "Relationship",
|
|
945
|
-
"\u30E9\u30A4\u30D6": "Live",
|
|
946
|
-
"\u30AA\u30F3\u30DC\u30FC\u30C7\u30A3\u30F3\u30B0": "Onboarding",
|
|
947
|
-
"\u30B3\u30FC\u30B9": "Course",
|
|
948
|
-
"\u7533\u3057\u8FBC\u307F": "Enrollment",
|
|
949
|
-
"\u30AF\u30A4\u30BA": "Quiz",
|
|
950
|
-
"\u5275\u4F5C": "Creation",
|
|
951
|
-
"\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8": "Export",
|
|
952
|
-
"\u518D\u751F": "Playback",
|
|
953
|
-
// ko
|
|
954
|
-
"\uAE30\uBCF8 \uC774\uBCA4\uD2B8": "Basic",
|
|
955
|
-
"\uC804\uD22C": "Battle",
|
|
956
|
-
"\uC2A4\uD14C\uC774\uC9C0": "Stage",
|
|
957
|
-
"\uB358\uC804": "Dungeon",
|
|
958
|
-
"\uAC00\uCC60": "Gacha",
|
|
959
|
-
"\uC721\uC131": "Growth",
|
|
960
|
-
"\uB9AC\uC18C\uC2A4": "Resource",
|
|
961
|
-
"\uAD11\uACE0": "Ads",
|
|
962
|
-
"\uACB0\uC81C": "Payment",
|
|
963
|
-
"\uAD6C\uB3C5": "Subscription",
|
|
964
|
-
"\uC0C1\uC810": "Shop",
|
|
965
|
-
"\uD018\uC2A4\uD2B8": "Quest",
|
|
966
|
-
"\uC5C5\uC801": "Achievement",
|
|
967
|
-
"\uCD9C\uC11D\uCCB4\uD06C": "Check-in",
|
|
968
|
-
"\uB9AC\uB354\uBCF4\uB4DC": "Leaderboard",
|
|
969
|
-
"\uAE38\uB4DC": "Guild",
|
|
970
|
-
"\uC18C\uC15C": "Social",
|
|
971
|
-
"\uAC74\uC124": "Building",
|
|
972
|
-
"\uC5F0\uB9F9": "Alliance",
|
|
973
|
-
"\uC7A5\uBE44": "Equipment",
|
|
974
|
-
"\uAC70\uB798": "Trade",
|
|
975
|
-
"\uBD80\uD65C": "Revive",
|
|
976
|
-
"\uC2AC\uB86F": "Slots",
|
|
977
|
-
"\uCD94\uCCA8": "Lottery",
|
|
978
|
-
"\uBCF4\uC0C1": "Reward",
|
|
979
|
-
"\uCD9C\uAE08": "Withdraw",
|
|
980
|
-
"\uBC1C\uACAC": "Discovery",
|
|
981
|
-
"\uC0C1\uD488": "Product",
|
|
982
|
-
"\uC8FC\uBB38": "Order",
|
|
983
|
-
"A/S": "After-sales",
|
|
984
|
-
"\uCF58\uD150\uCE20": "Content",
|
|
985
|
-
"\uC778\uD130\uB799\uC158": "Interaction",
|
|
986
|
-
"\uAD00\uACC4": "Relationship",
|
|
987
|
-
"\uB77C\uC774\uBE0C": "Live",
|
|
988
|
-
"\uC628\uBCF4\uB529": "Onboarding",
|
|
989
|
-
"\uCF54\uC2A4": "Course",
|
|
990
|
-
"\uC2E0\uCCAD": "Enrollment",
|
|
991
|
-
"\uD034\uC988": "Quiz",
|
|
992
|
-
"\uCC3D\uC791": "Creation",
|
|
993
|
-
"\uC18C\uC7AC": "Material",
|
|
994
|
-
"\uB0B4\uBCF4\uB0B4\uAE30": "Export",
|
|
995
|
-
"\uC7AC\uC0DD": "Playback"
|
|
996
|
-
};
|
|
997
|
-
function getTagPriority(tag) {
|
|
998
|
-
const canonical = CANONICAL_TAG[tag] ?? tag;
|
|
999
|
-
return TAG_PRIORITY[canonical] ?? DEFAULT_TAG_PRIORITY;
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
// src/tracking/xlsx/write.ts
|
|
1003
|
-
var PLATFORM_TO_XLSX = {
|
|
1004
|
-
"client": "client",
|
|
1005
|
-
"server": "server",
|
|
1006
|
-
"both": "client,server"
|
|
1007
|
-
};
|
|
1008
|
-
var VALID_PROP_TYPES = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
|
|
1009
|
-
var VALID_UPDATE_TYPES = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
|
|
1010
|
-
var SNAKE_CASE_RE = /^[a-z][a-z0-9_]*$/;
|
|
1011
|
-
var PROP_NAME_RE = /^[a-zA-Z#][a-zA-Z0-9_.]*$/;
|
|
1012
|
-
var MIN_COL_WIDTH = 10;
|
|
1013
|
-
var PADDING = 3;
|
|
1014
|
-
function isWideChar(code) {
|
|
1015
|
-
return code >= 19968 && code <= 40959 || // CJK Unified Ideographs
|
|
1016
|
-
code >= 13312 && code <= 19903 || // CJK Ext-A
|
|
1017
|
-
code >= 12352 && code <= 12447 || // Hiragana
|
|
1018
|
-
code >= 12448 && code <= 12543 || // Katakana
|
|
1019
|
-
code >= 44032 && code <= 55215 || // Hangul
|
|
1020
|
-
code >= 65280 && code <= 65519;
|
|
1021
|
-
}
|
|
1022
|
-
function displayWidth(s) {
|
|
1023
|
-
let w = 0;
|
|
1024
|
-
for (const ch of s) {
|
|
1025
|
-
w += isWideChar(ch.charCodeAt(0)) ? 2 : 1;
|
|
1026
|
-
}
|
|
1027
|
-
return w;
|
|
1028
|
-
}
|
|
1029
|
-
function autoFitSheet(ws, maxWidth = 55) {
|
|
1030
|
-
const colCount = ws.columnCount;
|
|
1031
|
-
if (colCount === 0) return;
|
|
1032
|
-
for (let i = 1; i <= colCount; i++) {
|
|
1033
|
-
const col = ws.getColumn(i);
|
|
1034
|
-
let maxDisplay = 0;
|
|
1035
|
-
let needsWrap = false;
|
|
1036
|
-
col.eachCell({ includeEmpty: false }, (cell) => {
|
|
1037
|
-
const text = String(cell.value ?? "");
|
|
1038
|
-
if (!text) return;
|
|
1039
|
-
const dw = displayWidth(text);
|
|
1040
|
-
if (dw > maxDisplay) maxDisplay = dw;
|
|
1041
|
-
});
|
|
1042
|
-
if (maxDisplay === 0) {
|
|
1043
|
-
col.width = MIN_COL_WIDTH;
|
|
1044
|
-
continue;
|
|
1045
|
-
}
|
|
1046
|
-
const capped = maxDisplay + PADDING > maxWidth;
|
|
1047
|
-
col.width = Math.max(MIN_COL_WIDTH, Math.min(maxWidth, maxDisplay + PADDING));
|
|
1048
|
-
if (capped) {
|
|
1049
|
-
col.eachCell({ includeEmpty: false }, (cell) => {
|
|
1050
|
-
cell.alignment = { ...cell.alignment, wrapText: true };
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
function validateDraft(d) {
|
|
1056
|
-
const errors = [];
|
|
1057
|
-
const eventNames = /* @__PURE__ */ new Set();
|
|
1058
|
-
for (const evt of d.events) {
|
|
1059
|
-
if (!SNAKE_CASE_RE.test(evt.event_name)) {
|
|
1060
|
-
errors.push(`Event name "${evt.event_name}" does not match snake_case pattern`);
|
|
1061
|
-
}
|
|
1062
|
-
if (eventNames.has(evt.event_name)) {
|
|
1063
|
-
errors.push(`Duplicate event_name: "${evt.event_name}"`);
|
|
1064
|
-
}
|
|
1065
|
-
eventNames.add(evt.event_name);
|
|
1066
|
-
}
|
|
1067
|
-
const eventProps = d.event_properties ?? d.common_properties ?? [];
|
|
1068
|
-
const eventPropNames = /* @__PURE__ */ new Set();
|
|
1069
|
-
const compositeProps = new Set(
|
|
1070
|
-
eventProps.filter((p) => p.type === "array_row" || p.type === "object").map((p) => p.name)
|
|
1071
|
-
);
|
|
1072
|
-
for (const prop of eventProps) {
|
|
1073
|
-
if (!PROP_NAME_RE.test(prop.name)) {
|
|
1074
|
-
errors.push(`Event property name "${prop.name}" has invalid characters`);
|
|
1075
|
-
}
|
|
1076
|
-
if (prop.name.includes(".")) {
|
|
1077
|
-
const parent = prop.name.split(".")[0];
|
|
1078
|
-
if (!compositeProps.has(parent)) {
|
|
1079
|
-
errors.push(`Nested property "${prop.name}" references non-composite parent "${parent}"`);
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
if (!VALID_PROP_TYPES.has(prop.type)) {
|
|
1083
|
-
errors.push(`Event property "${prop.name}" has invalid type: "${prop.type}"`);
|
|
1084
|
-
}
|
|
1085
|
-
if (eventPropNames.has(prop.name)) {
|
|
1086
|
-
errors.push(`Duplicate event property name: "${prop.name}"`);
|
|
1087
|
-
}
|
|
1088
|
-
eventPropNames.add(prop.name);
|
|
1089
|
-
}
|
|
1090
|
-
const commonProps = d.common_event_properties ?? d.common_properties ?? [];
|
|
1091
|
-
const commonPropNames = /* @__PURE__ */ new Set();
|
|
1092
|
-
for (const prop of commonProps) {
|
|
1093
|
-
if (!VALID_PROP_TYPES.has(prop.type)) {
|
|
1094
|
-
errors.push(`Common event property "${prop.name}" has invalid type: "${prop.type}"`);
|
|
1095
|
-
}
|
|
1096
|
-
if (commonPropNames.has(prop.name)) {
|
|
1097
|
-
errors.push(`Duplicate common event property name: "${prop.name}"`);
|
|
1098
|
-
}
|
|
1099
|
-
commonPropNames.add(prop.name);
|
|
1100
|
-
}
|
|
1101
|
-
const userPropNames = /* @__PURE__ */ new Set();
|
|
1102
|
-
for (const prop of d.user_properties) {
|
|
1103
|
-
if (!VALID_PROP_TYPES.has(prop.type)) {
|
|
1104
|
-
errors.push(`User property "${prop.name}" has invalid type: "${prop.type}"`);
|
|
1105
|
-
}
|
|
1106
|
-
if (prop.update_type && !VALID_UPDATE_TYPES.has(prop.update_type)) {
|
|
1107
|
-
errors.push(`User property "${prop.name}" has invalid update_type: "${prop.update_type}"`);
|
|
1108
|
-
}
|
|
1109
|
-
if (userPropNames.has(prop.name)) {
|
|
1110
|
-
errors.push(`Duplicate user property name: "${prop.name}"`);
|
|
1111
|
-
}
|
|
1112
|
-
userPropNames.add(prop.name);
|
|
1113
|
-
}
|
|
1114
|
-
for (const evt of d.events) {
|
|
1115
|
-
if (!evt.prop_names) continue;
|
|
1116
|
-
for (const propName of evt.prop_names) {
|
|
1117
|
-
if (propName.startsWith("#")) continue;
|
|
1118
|
-
if (!eventPropNames.has(propName)) {
|
|
1119
|
-
errors.push(`Event "${evt.event_name}" references unknown event property "${propName}"`);
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
const eventDisplayNames = /* @__PURE__ */ new Map();
|
|
1124
|
-
for (const prop of eventProps) {
|
|
1125
|
-
if (prop.display_name) {
|
|
1126
|
-
const names = eventDisplayNames.get(prop.display_name) || [];
|
|
1127
|
-
names.push(prop.name);
|
|
1128
|
-
eventDisplayNames.set(prop.display_name, names);
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
for (const [displayName, names] of eventDisplayNames) {
|
|
1132
|
-
if (names.length > 1) {
|
|
1133
|
-
errors.push(`Display name "${displayName}" is used by multiple event properties: ${names.join(", ")}`);
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
const commonDisplayNames = /* @__PURE__ */ new Map();
|
|
1137
|
-
for (const prop of commonProps) {
|
|
1138
|
-
if (prop.display_name) {
|
|
1139
|
-
const names = commonDisplayNames.get(prop.display_name) || [];
|
|
1140
|
-
names.push(prop.name);
|
|
1141
|
-
commonDisplayNames.set(prop.display_name, names);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
for (const [displayName, names] of commonDisplayNames) {
|
|
1145
|
-
if (names.length > 1) {
|
|
1146
|
-
errors.push(`Display name "${displayName}" is used by multiple common properties: ${names.join(", ")}`);
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
const userDisplayNames = /* @__PURE__ */ new Map();
|
|
1150
|
-
for (const prop of d.user_properties) {
|
|
1151
|
-
if (prop.display_name) {
|
|
1152
|
-
const names = userDisplayNames.get(prop.display_name) || [];
|
|
1153
|
-
names.push(prop.name);
|
|
1154
|
-
userDisplayNames.set(prop.display_name, names);
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
for (const [displayName, names] of userDisplayNames) {
|
|
1158
|
-
if (names.length > 1) {
|
|
1159
|
-
errors.push(`Display name "${displayName}" is used by multiple user properties: ${names.join(", ")}`);
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
const compositeChildren = /* @__PURE__ */ new Map();
|
|
1163
|
-
for (const prop of eventProps) {
|
|
1164
|
-
if (prop.type === "array_row" || prop.type === "object") {
|
|
1165
|
-
compositeChildren.set(prop.name, /* @__PURE__ */ new Set());
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
for (const prop of eventProps) {
|
|
1169
|
-
if (prop.name.includes(".")) {
|
|
1170
|
-
const parent = prop.name.split(".")[0];
|
|
1171
|
-
const children = compositeChildren.get(parent);
|
|
1172
|
-
if (children) {
|
|
1173
|
-
children.add(prop.name);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
for (const evt of d.events) {
|
|
1178
|
-
if (!evt.prop_names) continue;
|
|
1179
|
-
for (const parentName of compositeProps) {
|
|
1180
|
-
if (evt.prop_names.includes(parentName)) {
|
|
1181
|
-
const eventChildren = evt.prop_names.filter((p) => p.startsWith(parentName + "."));
|
|
1182
|
-
const expectedChildren = compositeChildren.get(parentName);
|
|
1183
|
-
if (expectedChildren && eventChildren.length > 0) {
|
|
1184
|
-
for (const child of expectedChildren) {
|
|
1185
|
-
if (!eventChildren.includes(child)) {
|
|
1186
|
-
errors.push(`Event "${evt.event_name}" uses "${parentName}" but missing child "${child}"`);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
const childPropTypes = /* @__PURE__ */ new Map();
|
|
1194
|
-
for (const prop of eventProps) {
|
|
1195
|
-
if (prop.name.includes(".")) {
|
|
1196
|
-
const childName = prop.name;
|
|
1197
|
-
const existing = childPropTypes.get(childName);
|
|
1198
|
-
if (existing) {
|
|
1199
|
-
if (existing.type !== prop.type) {
|
|
1200
|
-
errors.push(`Child property "${childName}" has inconsistent types: "${existing.type}" vs "${prop.type}" (used in events: ${existing.events.join(", ")})`);
|
|
1201
|
-
}
|
|
1202
|
-
} else {
|
|
1203
|
-
childPropTypes.set(childName, { type: prop.type, events: [] });
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
if (errors.length > 0) {
|
|
1208
|
-
throw new Error(`Draft validation failed:
|
|
1209
|
-
${errors.map((e) => " - " + e).join("\n")}`);
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
async function writeDraftXlsx(d, outPath, locale = "zh") {
|
|
1213
|
-
validateDraft(d);
|
|
1214
|
-
const workbook = new ExcelJS.Workbook();
|
|
1215
|
-
const eventSheet = workbook.addWorksheet(sheetName("event_data", locale));
|
|
1216
|
-
eventSheet.addRow([
|
|
1217
|
-
headerName("event_name", locale),
|
|
1218
|
-
headerName("event_display_name", locale),
|
|
1219
|
-
headerName("event_desc", locale),
|
|
1220
|
-
headerName("event_tag", locale),
|
|
1221
|
-
headerName("platform", locale),
|
|
1222
|
-
headerName("prop_name", locale),
|
|
1223
|
-
headerName("prop_display_name", locale),
|
|
1224
|
-
headerName("prop_type", locale),
|
|
1225
|
-
headerName("prop_desc", locale)
|
|
1226
|
-
]);
|
|
1227
|
-
const propByName = new Map(d.event_properties.map((p) => [p.name, p]));
|
|
1228
|
-
const autotrackEvents = d.events.filter((e) => e.source === "autotrack");
|
|
1229
|
-
const businessEvents = d.events.filter((e) => e.source !== "autotrack");
|
|
1230
|
-
const tagGroups = /* @__PURE__ */ new Map();
|
|
1231
|
-
const tagOrder = [];
|
|
1232
|
-
for (const evt of businessEvents) {
|
|
1233
|
-
const tag = evt.event_tag || "";
|
|
1234
|
-
if (!tagGroups.has(tag)) {
|
|
1235
|
-
tagGroups.set(tag, []);
|
|
1236
|
-
tagOrder.push(tag);
|
|
1237
|
-
}
|
|
1238
|
-
tagGroups.get(tag).push(evt);
|
|
1239
|
-
}
|
|
1240
|
-
tagOrder.sort((a, b) => getTagPriority(a) - getTagPriority(b));
|
|
1241
|
-
const sorted = [...autotrackEvents];
|
|
1242
|
-
for (const tag of tagOrder) {
|
|
1243
|
-
for (const evt of tagGroups.get(tag)) {
|
|
1244
|
-
sorted.push(evt);
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
for (const evt of sorted) {
|
|
1248
|
-
const startRow = eventSheet.rowCount + 1;
|
|
1249
|
-
const platformStr = evt.platform ? PLATFORM_TO_XLSX[evt.platform] : "";
|
|
1250
|
-
if (evt.prop_names.length === 0) {
|
|
1251
|
-
eventSheet.addRow([
|
|
1252
|
-
evt.event_name,
|
|
1253
|
-
evt.display_name ?? "",
|
|
1254
|
-
evt.event_desc ?? "",
|
|
1255
|
-
evt.event_tag ?? "",
|
|
1256
|
-
platformStr,
|
|
1257
|
-
"",
|
|
1258
|
-
"",
|
|
1259
|
-
"",
|
|
1260
|
-
""
|
|
1261
|
-
]);
|
|
1262
|
-
} else {
|
|
1263
|
-
for (const propName of evt.prop_names) {
|
|
1264
|
-
const prop = propByName.get(propName);
|
|
1265
|
-
eventSheet.addRow([
|
|
1266
|
-
evt.event_name,
|
|
1267
|
-
evt.display_name ?? "",
|
|
1268
|
-
evt.event_desc ?? "",
|
|
1269
|
-
evt.event_tag ?? "",
|
|
1270
|
-
platformStr,
|
|
1271
|
-
prop?.name ?? propName,
|
|
1272
|
-
prop?.display_name ?? "",
|
|
1273
|
-
prop ? typeToDisplay(prop.type, locale) : "",
|
|
1274
|
-
prop?.desc ?? ""
|
|
1275
|
-
]);
|
|
1276
|
-
}
|
|
1277
|
-
const endRow = eventSheet.rowCount;
|
|
1278
|
-
if (endRow > startRow) {
|
|
1279
|
-
for (const col of ["A", "B", "C", "D", "E"]) {
|
|
1280
|
-
eventSheet.mergeCells(`${col}${startRow}:${col}${endRow}`);
|
|
1281
|
-
}
|
|
1282
|
-
for (let r = startRow; r <= endRow; r++) {
|
|
1283
|
-
const row = eventSheet.getRow(r);
|
|
1284
|
-
for (const col of ["A", "B", "C", "D", "E"]) {
|
|
1285
|
-
const cell = row.getCell(col);
|
|
1286
|
-
cell.alignment = { ...cell.alignment, vertical: "middle" };
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
autoFitSheet(eventSheet, 50);
|
|
1293
|
-
const commonSheet = workbook.addWorksheet(sheetName("common_props", locale));
|
|
1294
|
-
commonSheet.addRow([
|
|
1295
|
-
headerName("common_prop_name", locale),
|
|
1296
|
-
headerName("common_prop_display_name", locale),
|
|
1297
|
-
headerName("common_prop_type", locale),
|
|
1298
|
-
headerName("common_prop_desc", locale)
|
|
1299
|
-
]);
|
|
1300
|
-
for (const prop of d.common_event_properties) {
|
|
1301
|
-
commonSheet.addRow([
|
|
1302
|
-
prop.name,
|
|
1303
|
-
prop.display_name ?? "",
|
|
1304
|
-
typeToDisplay(prop.type, locale),
|
|
1305
|
-
prop.desc ?? ""
|
|
1306
|
-
]);
|
|
1307
|
-
}
|
|
1308
|
-
autoFitSheet(commonSheet, 50);
|
|
1309
|
-
const userSheet = workbook.addWorksheet(sheetName("user_data", locale));
|
|
1310
|
-
userSheet.addRow([
|
|
1311
|
-
headerName("user_prop_name", locale),
|
|
1312
|
-
headerName("user_prop_display_name", locale),
|
|
1313
|
-
headerName("user_prop_type", locale),
|
|
1314
|
-
headerName("update_type", locale),
|
|
1315
|
-
headerName("user_prop_desc", locale),
|
|
1316
|
-
headerName("prop_tag", locale)
|
|
1317
|
-
]);
|
|
1318
|
-
for (const prop of d.user_properties) {
|
|
1319
|
-
userSheet.addRow([
|
|
1320
|
-
prop.name,
|
|
1321
|
-
prop.display_name ?? "",
|
|
1322
|
-
typeToDisplay(prop.type, locale),
|
|
1323
|
-
prop.update_type ?? "user_set",
|
|
1324
|
-
// 默认 user_set
|
|
1325
|
-
prop.desc ?? "",
|
|
1326
|
-
prop.prop_tag ?? ""
|
|
1327
|
-
]);
|
|
1328
|
-
}
|
|
1329
|
-
autoFitSheet(userSheet, 50);
|
|
1330
|
-
const userIdSheet = workbook.addWorksheet(sheetName("user_id", locale));
|
|
1331
|
-
userIdSheet.addRow([
|
|
1332
|
-
headerName("user_id_prop_name", locale),
|
|
1333
|
-
headerName("user_id_display_name", locale),
|
|
1334
|
-
headerName("user_id_desc", locale),
|
|
1335
|
-
headerName("user_id_value_desc", locale)
|
|
1336
|
-
]);
|
|
1337
|
-
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)]);
|
|
1338
|
-
userIdSheet.addRow(["#distinct_id", t("user_id.distinct_id_display", {}, locale), t("user_id.system_property", {}, locale), t("user_id.auto_generated", {}, locale)]);
|
|
1339
|
-
autoFitSheet(userIdSheet, 50);
|
|
1340
|
-
await workbook.xlsx.writeFile(outPath);
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
511
|
// src/core/tracking-client.ts
|
|
1344
512
|
var DEBUG_BASE = "/v1/ta/bury/manage/debug";
|
|
1345
513
|
var TRACK_LOCAL_HOST = "http://localhost:8992";
|
|
@@ -1572,9 +740,9 @@ async function fetchPlan({ projectId, host }) {
|
|
|
1572
740
|
if (!data) {
|
|
1573
741
|
throw new Error(t("error.fetch_no_data", { host }));
|
|
1574
742
|
}
|
|
1575
|
-
return
|
|
743
|
+
return normalize(data);
|
|
1576
744
|
}
|
|
1577
|
-
function
|
|
745
|
+
function normalize(data) {
|
|
1578
746
|
return {
|
|
1579
747
|
meta: { app_type: "unknown", sdk_integration_mode: "client_only", plan_name: "from-te" },
|
|
1580
748
|
events: (data.events ?? []).map((e) => ({
|
|
@@ -1821,292 +989,6 @@ function injectAutotrackEvents(draft, locale = "zh") {
|
|
|
1821
989
|
return draft;
|
|
1822
990
|
}
|
|
1823
991
|
|
|
1824
|
-
// src/tracking/plan/fix.ts
|
|
1825
|
-
function extractErrors(response) {
|
|
1826
|
-
const errors = [];
|
|
1827
|
-
if (response.data?.eventErrorMap) {
|
|
1828
|
-
for (const [errorType, items] of Object.entries(response.data.eventErrorMap)) {
|
|
1829
|
-
for (const item of items) {
|
|
1830
|
-
errors.push({ ...item, errorType });
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
if (response.data?.userErrorMap) {
|
|
1835
|
-
for (const [errorType, items] of Object.entries(response.data.userErrorMap)) {
|
|
1836
|
-
for (const item of items) {
|
|
1837
|
-
errors.push({ ...item, errorType });
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
return errors;
|
|
1842
|
-
}
|
|
1843
|
-
function fixDisplayDuplicate(draft, errors) {
|
|
1844
|
-
const duplicateDisplayNames = /* @__PURE__ */ new Map();
|
|
1845
|
-
for (const error of errors) {
|
|
1846
|
-
if (error.errorType === "event_prop_display_duplicate") {
|
|
1847
|
-
const names = duplicateDisplayNames.get(error.value) || [];
|
|
1848
|
-
names.push(error.value);
|
|
1849
|
-
duplicateDisplayNames.set(error.value, names);
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
for (const prop of draft.event_properties) {
|
|
1853
|
-
if (duplicateDisplayNames.has(prop.display_name || "")) {
|
|
1854
|
-
const eventsUsingProp = draft.events.filter((e) => e.prop_names.includes(prop.name));
|
|
1855
|
-
if (prop.name.includes(".")) {
|
|
1856
|
-
prop.display_name = `\u660E\u7EC6${prop.display_name}`;
|
|
1857
|
-
} else if (eventsUsingProp.length > 0) {
|
|
1858
|
-
prop.display_name = `${prop.display_name}${t("fix.detail_suffix")}`;
|
|
1859
|
-
}
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
function fixArrayRowConsistency(draft, errors) {
|
|
1864
|
-
const compositeChildren = /* @__PURE__ */ new Map();
|
|
1865
|
-
const evProps = draft.event_properties ?? draft.common_properties ?? [];
|
|
1866
|
-
for (const prop of evProps) {
|
|
1867
|
-
if (prop.type === "array_row" || prop.type === "object") {
|
|
1868
|
-
compositeChildren.set(prop.name, []);
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
for (const prop of evProps) {
|
|
1872
|
-
if (prop.name.includes(".")) {
|
|
1873
|
-
const parent = prop.name.split(".")[0];
|
|
1874
|
-
const children = compositeChildren.get(parent);
|
|
1875
|
-
if (children) {
|
|
1876
|
-
children.push(prop.name);
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
for (const event of draft.events) {
|
|
1881
|
-
if (!event.prop_names) continue;
|
|
1882
|
-
const propNamesSet = new Set(event.prop_names);
|
|
1883
|
-
for (const [parentName, children] of compositeChildren) {
|
|
1884
|
-
if (propNamesSet.has(parentName)) {
|
|
1885
|
-
for (const child of children) {
|
|
1886
|
-
if (!propNamesSet.has(child)) {
|
|
1887
|
-
event.prop_names.push(child);
|
|
1888
|
-
}
|
|
1889
|
-
}
|
|
1890
|
-
const parentProps = event.prop_names.filter(
|
|
1891
|
-
(p) => p === parentName || p.startsWith(parentName + ".")
|
|
1892
|
-
);
|
|
1893
|
-
const sorted = [parentName, ...children.filter((c) => event.prop_names.includes(c))];
|
|
1894
|
-
event.prop_names = event.prop_names.filter(
|
|
1895
|
-
(p) => !p.startsWith(parentName) || p === parentName
|
|
1896
|
-
);
|
|
1897
|
-
const idx = event.prop_names.indexOf(parentName);
|
|
1898
|
-
if (idx >= 0) {
|
|
1899
|
-
event.prop_names.splice(idx, 1, ...sorted);
|
|
1900
|
-
}
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
function fixUnknownPropRefs(draft) {
|
|
1906
|
-
const fixed = [];
|
|
1907
|
-
const props = draft.event_properties ?? draft.common_properties ?? [];
|
|
1908
|
-
const eventPropNames = new Set(props.map((p) => p.name));
|
|
1909
|
-
for (const event of draft.events) {
|
|
1910
|
-
if (!event.prop_names) continue;
|
|
1911
|
-
const removed = [];
|
|
1912
|
-
event.prop_names = event.prop_names.filter((pn) => {
|
|
1913
|
-
if (pn.startsWith("#")) return true;
|
|
1914
|
-
if (eventPropNames.has(pn)) return true;
|
|
1915
|
-
removed.push(pn);
|
|
1916
|
-
return false;
|
|
1917
|
-
});
|
|
1918
|
-
if (removed.length > 0) {
|
|
1919
|
-
fixed.push(...removed.map((r) => `Removed unknown prop "${r}" from event "${event.event_name}"`));
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
return fixed;
|
|
1923
|
-
}
|
|
1924
|
-
function fixDisplayNameDuplicates(draft) {
|
|
1925
|
-
const fixed = [];
|
|
1926
|
-
const pools = [
|
|
1927
|
-
{ name: "event_properties", items: draft.event_properties ?? draft.common_properties ?? [] },
|
|
1928
|
-
{ name: "common_event_properties", items: draft.common_event_properties ?? draft.common_properties ?? [] },
|
|
1929
|
-
{ name: "user_properties", items: draft.user_properties ?? [] }
|
|
1930
|
-
];
|
|
1931
|
-
for (const pool of pools) {
|
|
1932
|
-
const displayMap = /* @__PURE__ */ new Map();
|
|
1933
|
-
for (let i = 0; i < pool.items.length; i++) {
|
|
1934
|
-
const dn = pool.items[i].display_name;
|
|
1935
|
-
if (!dn) continue;
|
|
1936
|
-
const list = displayMap.get(dn) || [];
|
|
1937
|
-
list.push(i);
|
|
1938
|
-
displayMap.set(dn, list);
|
|
1939
|
-
}
|
|
1940
|
-
for (const [displayName, indices] of displayMap) {
|
|
1941
|
-
if (indices.length <= 1) continue;
|
|
1942
|
-
for (let j = 1; j < indices.length; j++) {
|
|
1943
|
-
const prop = pool.items[indices[j]];
|
|
1944
|
-
const newDisplayName = `${displayName} (${prop.name})`;
|
|
1945
|
-
prop.display_name = newDisplayName;
|
|
1946
|
-
fixed.push(`Disambiguated display name "${displayName}" \u2192 "${newDisplayName}" in ${pool.name}`);
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
return fixed;
|
|
1951
|
-
}
|
|
1952
|
-
function fixCrossPoolDisplayNameInconsistency(draft) {
|
|
1953
|
-
const fixed = [];
|
|
1954
|
-
const commonProps = draft.common_event_properties ?? [];
|
|
1955
|
-
const eventProps = draft.event_properties ?? [];
|
|
1956
|
-
for (const cp2 of commonProps) {
|
|
1957
|
-
if (!cp2.display_name) continue;
|
|
1958
|
-
const ep = eventProps.find((p) => p.name === cp2.name);
|
|
1959
|
-
if (!ep) continue;
|
|
1960
|
-
if (ep.display_name && ep.display_name !== cp2.display_name) {
|
|
1961
|
-
const oldName = ep.display_name;
|
|
1962
|
-
ep.display_name = cp2.display_name;
|
|
1963
|
-
fixed.push(
|
|
1964
|
-
`Aligned display_name for "${cp2.name}" in event_properties: "${oldName}" \u2192 "${cp2.display_name}" (from common_event_properties)`
|
|
1965
|
-
);
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
return fixed;
|
|
1969
|
-
}
|
|
1970
|
-
function fixEventPlatforms(draft) {
|
|
1971
|
-
const fixed = [];
|
|
1972
|
-
const mode = draft.meta.sdk_integration_mode;
|
|
1973
|
-
if (mode !== "client_only" && mode !== "server_only") return fixed;
|
|
1974
|
-
const targetPlatform = mode === "client_only" ? "client" : "server";
|
|
1975
|
-
let count = 0;
|
|
1976
|
-
for (const event of draft.events) {
|
|
1977
|
-
if (!event.platform) {
|
|
1978
|
-
event.platform = targetPlatform;
|
|
1979
|
-
count++;
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
if (count > 0) {
|
|
1983
|
-
fixed.push(
|
|
1984
|
-
`Auto-filled platform="${targetPlatform}" for ${count} event(s) based on sdk_integration_mode="${mode}"`
|
|
1985
|
-
);
|
|
1986
|
-
}
|
|
1987
|
-
return fixed;
|
|
1988
|
-
}
|
|
1989
|
-
function fixEventPropNameInvalid(draft, errors) {
|
|
1990
|
-
const invalidNames = /* @__PURE__ */ new Set();
|
|
1991
|
-
for (const error of errors) {
|
|
1992
|
-
if (error.errorType === "event_prop_name_invalid") {
|
|
1993
|
-
invalidNames.add(error.value);
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
for (const prop of draft.event_properties) {
|
|
1997
|
-
if (invalidNames.has(prop.name)) {
|
|
1998
|
-
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();
|
|
1999
|
-
const oldName = prop.name;
|
|
2000
|
-
prop.name = fixedName;
|
|
2001
|
-
for (const event of draft.events) {
|
|
2002
|
-
const idx = event.prop_names.indexOf(oldName);
|
|
2003
|
-
if (idx >= 0) {
|
|
2004
|
-
event.prop_names[idx] = fixedName;
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
if (prop.display_name && !prop.display_name.includes("(")) {
|
|
2008
|
-
prop.display_name = `${prop.display_name}${t("fix.auto_fix_suffix")}`;
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
function fixEventNameDuplicate(draft, errors) {
|
|
2014
|
-
const duplicateEvents = /* @__PURE__ */ new Set();
|
|
2015
|
-
for (const error of errors) {
|
|
2016
|
-
if (error.errorType === "event_name_duplicate") {
|
|
2017
|
-
duplicateEvents.add(error.value);
|
|
2018
|
-
}
|
|
2019
|
-
}
|
|
2020
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2021
|
-
draft.events = draft.events.filter((event) => {
|
|
2022
|
-
if (duplicateEvents.has(event.event_name)) {
|
|
2023
|
-
if (seen.has(event.event_name)) {
|
|
2024
|
-
return false;
|
|
2025
|
-
}
|
|
2026
|
-
seen.add(event.event_name);
|
|
2027
|
-
}
|
|
2028
|
-
return true;
|
|
2029
|
-
});
|
|
2030
|
-
}
|
|
2031
|
-
function fixDraft(draft, response) {
|
|
2032
|
-
const errors = extractErrors(response);
|
|
2033
|
-
const fixed = [];
|
|
2034
|
-
if (errors.length === 0) {
|
|
2035
|
-
return fixed;
|
|
2036
|
-
}
|
|
2037
|
-
const errorTypes = new Set(errors.map((e) => e.errorType));
|
|
2038
|
-
if (errorTypes.has("event_prop_display_duplicate")) {
|
|
2039
|
-
fixDisplayDuplicate(draft, errors);
|
|
2040
|
-
fixed.push(t("fix.display_name_dedup"));
|
|
2041
|
-
}
|
|
2042
|
-
if (errorTypes.has("complex_event_property_should_has_same_child_property")) {
|
|
2043
|
-
fixArrayRowConsistency(draft, errors);
|
|
2044
|
-
fixed.push(t("fix.array_row_consistency"));
|
|
2045
|
-
}
|
|
2046
|
-
if (errorTypes.has("event_prop_name_invalid")) {
|
|
2047
|
-
fixEventPropNameInvalid(draft, errors);
|
|
2048
|
-
fixed.push(t("fix.event_prop_name_invalid"));
|
|
2049
|
-
}
|
|
2050
|
-
if (errorTypes.has("event_name_duplicate")) {
|
|
2051
|
-
fixEventNameDuplicate(draft, errors);
|
|
2052
|
-
fixed.push(t("fix.event_name_duplicate"));
|
|
2053
|
-
}
|
|
2054
|
-
return fixed;
|
|
2055
|
-
}
|
|
2056
|
-
function validateAndFix(draft) {
|
|
2057
|
-
const fixed = [];
|
|
2058
|
-
const unknownFixes = fixUnknownPropRefs(draft);
|
|
2059
|
-
if (unknownFixes.length > 0) {
|
|
2060
|
-
fixed.push(t("fix.unknown_prop_ref"));
|
|
2061
|
-
}
|
|
2062
|
-
const displayFixes = fixDisplayNameDuplicates(draft);
|
|
2063
|
-
if (displayFixes.length > 0) {
|
|
2064
|
-
fixed.push(t("fix.display_name_dedup"));
|
|
2065
|
-
}
|
|
2066
|
-
const crossPoolFixes = fixCrossPoolDisplayNameInconsistency(draft);
|
|
2067
|
-
if (crossPoolFixes.length > 0) {
|
|
2068
|
-
fixed.push(`Cross-pool display_name consistency: ${crossPoolFixes.length} property(s) aligned`);
|
|
2069
|
-
}
|
|
2070
|
-
const platformFixes = fixEventPlatforms(draft);
|
|
2071
|
-
if (platformFixes.length > 0) {
|
|
2072
|
-
fixed.push(...platformFixes);
|
|
2073
|
-
}
|
|
2074
|
-
const compositeChildren = /* @__PURE__ */ new Map();
|
|
2075
|
-
const evProps = draft.event_properties ?? draft.common_properties ?? [];
|
|
2076
|
-
for (const prop of evProps) {
|
|
2077
|
-
if (prop.type === "array_row" || prop.type === "object") {
|
|
2078
|
-
compositeChildren.set(prop.name, []);
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
for (const prop of evProps) {
|
|
2082
|
-
if (prop.name.includes(".")) {
|
|
2083
|
-
const parent = prop.name.split(".")[0];
|
|
2084
|
-
const children = compositeChildren.get(parent);
|
|
2085
|
-
if (children) {
|
|
2086
|
-
children.push(prop.name);
|
|
2087
|
-
}
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
let needFix = false;
|
|
2091
|
-
for (const event of draft.events) {
|
|
2092
|
-
if (!event.prop_names) continue;
|
|
2093
|
-
for (const [parentName, children] of compositeChildren) {
|
|
2094
|
-
if (event.prop_names.includes(parentName)) {
|
|
2095
|
-
for (const child of children) {
|
|
2096
|
-
if (!event.prop_names.includes(child)) {
|
|
2097
|
-
needFix = true;
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
}
|
|
2103
|
-
if (needFix) {
|
|
2104
|
-
fixArrayRowConsistency(draft, []);
|
|
2105
|
-
fixed.push(t("fix.array_row_consistency"));
|
|
2106
|
-
}
|
|
2107
|
-
return fixed;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
992
|
// src/tracking/plan/conflict.ts
|
|
2111
993
|
function detectConflicts(newDraft, existingDraft) {
|
|
2112
994
|
const conflicts = [];
|
|
@@ -2203,11 +1085,11 @@ function formatConflictReport(result, existingSummary) {
|
|
|
2203
1085
|
}
|
|
2204
1086
|
|
|
2205
1087
|
// src/commands/tracking/plan.ts
|
|
2206
|
-
import { existsSync as
|
|
1088
|
+
import { existsSync as existsSync3 } from "fs";
|
|
2207
1089
|
|
|
2208
1090
|
// src/tracking/templates.ts
|
|
2209
1091
|
import { readdir } from "fs/promises";
|
|
2210
|
-
import { existsSync
|
|
1092
|
+
import { existsSync } from "fs";
|
|
2211
1093
|
import { resolve } from "path";
|
|
2212
1094
|
function getTemplateDirs() {
|
|
2213
1095
|
return [
|
|
@@ -2218,7 +1100,7 @@ function getTemplateDirs() {
|
|
|
2218
1100
|
async function listTrackingTemplates() {
|
|
2219
1101
|
const found = [];
|
|
2220
1102
|
for (const dir of getTemplateDirs()) {
|
|
2221
|
-
if (!
|
|
1103
|
+
if (!existsSync(dir)) continue;
|
|
2222
1104
|
let entries = [];
|
|
2223
1105
|
try {
|
|
2224
1106
|
entries = await readdir(dir);
|
|
@@ -2230,7 +1112,7 @@ async function listTrackingTemplates() {
|
|
|
2230
1112
|
const base = f.replace(/\.xlsx$/i, "");
|
|
2231
1113
|
const xlsxPath = resolve(dir, f);
|
|
2232
1114
|
const mdPath = resolve(dir, base + ".md");
|
|
2233
|
-
const hasMd =
|
|
1115
|
+
const hasMd = existsSync(mdPath);
|
|
2234
1116
|
found.push({
|
|
2235
1117
|
path: hasMd ? mdPath : xlsxPath,
|
|
2236
1118
|
xlsxPath,
|
|
@@ -2256,7 +1138,7 @@ async function resolveTrackingTemplateByName(name) {
|
|
|
2256
1138
|
}
|
|
2257
1139
|
|
|
2258
1140
|
// src/commands/tracking/shared.ts
|
|
2259
|
-
import { existsSync as
|
|
1141
|
+
import { existsSync as existsSync2, statSync } from "fs";
|
|
2260
1142
|
var HOST_OPTION_DESC = "Override active AE host URL";
|
|
2261
1143
|
function resolveTrackingHost(program2, opts) {
|
|
2262
1144
|
const root = program2.root ?? program2;
|
|
@@ -2269,7 +1151,7 @@ function resolveTrackingHost(program2, opts) {
|
|
|
2269
1151
|
return host;
|
|
2270
1152
|
}
|
|
2271
1153
|
function isExistingDirectory(path4) {
|
|
2272
|
-
if (!
|
|
1154
|
+
if (!existsSync2(path4)) return false;
|
|
2273
1155
|
try {
|
|
2274
1156
|
return statSync(path4).isDirectory();
|
|
2275
1157
|
} catch {
|
|
@@ -2285,7 +1167,7 @@ function assertOutputFilePath(path4, optionName = "--out") {
|
|
|
2285
1167
|
}
|
|
2286
1168
|
function assertInputFilePath(path4, optionName = "--in") {
|
|
2287
1169
|
const trimmed = path4.trim();
|
|
2288
|
-
if (!
|
|
1170
|
+
if (!existsSync2(trimmed)) {
|
|
2289
1171
|
console.error(t("error.input_path_not_found", { path: trimmed, option: optionName }));
|
|
2290
1172
|
process.exit(1);
|
|
2291
1173
|
}
|
|
@@ -2490,7 +1372,7 @@ function registerPlan(cmd, rootProgram) {
|
|
|
2490
1372
|
assertInputFilePath(opts.xlsx, "--xlsx");
|
|
2491
1373
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2492
1374
|
const dest = resolve2(opts.plansDir, `${stamp}-${opts.name}.xlsx`);
|
|
2493
|
-
if (
|
|
1375
|
+
if (existsSync3(dest)) {
|
|
2494
1376
|
console.error(t("plan.archive_exists", { path: dest }));
|
|
2495
1377
|
console.error(t("plan.remove_or_rename"));
|
|
2496
1378
|
return;
|
|
@@ -2539,11 +1421,11 @@ function registerPlan(cmd, rootProgram) {
|
|
|
2539
1421
|
|
|
2540
1422
|
// src/commands/tracking/code.ts
|
|
2541
1423
|
import { readFile as readFile4, writeFile as writeFile2, mkdir } from "fs/promises";
|
|
2542
|
-
import { dirname
|
|
1424
|
+
import { dirname } from "path";
|
|
2543
1425
|
|
|
2544
1426
|
// src/tracking/project-detect/detect.ts
|
|
2545
1427
|
import { readFile as readFile2, readdir as readdir2, stat } from "fs/promises";
|
|
2546
|
-
import { join
|
|
1428
|
+
import { join } from "path";
|
|
2547
1429
|
async function exists(p) {
|
|
2548
1430
|
try {
|
|
2549
1431
|
await stat(p);
|
|
@@ -2560,14 +1442,14 @@ async function readJson(p) {
|
|
|
2560
1442
|
}
|
|
2561
1443
|
}
|
|
2562
1444
|
async function classifyDir(cwd) {
|
|
2563
|
-
if (await exists(
|
|
2564
|
-
const cfg = await readJson(
|
|
1445
|
+
if (await exists(join(cwd, "project.config.json"))) {
|
|
1446
|
+
const cfg = await readJson(join(cwd, "project.config.json"));
|
|
2565
1447
|
if (cfg && "miniprogramRoot" in cfg) return "mini-program";
|
|
2566
1448
|
}
|
|
2567
|
-
if (await exists(
|
|
2568
|
-
if (await exists(
|
|
2569
|
-
if (await exists(
|
|
2570
|
-
const pkg2 = await readJson(
|
|
1449
|
+
if (await exists(join(cwd, "ProjectSettings/ProjectVersion.txt"))) return "unity";
|
|
1450
|
+
if (await exists(join(cwd, "Podfile"))) return "ios";
|
|
1451
|
+
if (await exists(join(cwd, "build.gradle")) || await exists(join(cwd, "settings.gradle"))) return "android";
|
|
1452
|
+
const pkg2 = await readJson(join(cwd, "package.json"));
|
|
2571
1453
|
if (pkg2) {
|
|
2572
1454
|
const deps = { ...pkg2.dependencies ?? {}, ...pkg2.devDependencies ?? {} };
|
|
2573
1455
|
if (deps.astro) return "web-astro";
|
|
@@ -2577,9 +1459,9 @@ async function classifyDir(cwd) {
|
|
|
2577
1459
|
if (deps.express || deps.fastify || deps.koa) return "node-server";
|
|
2578
1460
|
return "web-vanilla";
|
|
2579
1461
|
}
|
|
2580
|
-
if (await exists(
|
|
2581
|
-
if (await exists(
|
|
2582
|
-
if (await exists(
|
|
1462
|
+
if (await exists(join(cwd, "go.mod"))) return "go-server";
|
|
1463
|
+
if (await exists(join(cwd, "pom.xml"))) return "java-server";
|
|
1464
|
+
if (await exists(join(cwd, "pyproject.toml")) || await exists(join(cwd, "requirements.txt"))) return "python-server";
|
|
2583
1465
|
return "unknown";
|
|
2584
1466
|
}
|
|
2585
1467
|
async function classify(cwd) {
|
|
@@ -2594,7 +1476,7 @@ async function classify(cwd) {
|
|
|
2594
1476
|
const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules").slice(0, 20);
|
|
2595
1477
|
let vanillaMatch;
|
|
2596
1478
|
for (const d of dirs) {
|
|
2597
|
-
const sub = await classifyDir(
|
|
1479
|
+
const sub = await classifyDir(join(cwd, d.name));
|
|
2598
1480
|
if (sub !== "unknown" && sub !== "web-vanilla") {
|
|
2599
1481
|
return { appType: sub, subPath: d.name };
|
|
2600
1482
|
}
|
|
@@ -2642,8 +1524,8 @@ async function detectProject(cwd) {
|
|
|
2642
1524
|
import XLSXMod from "xlsx";
|
|
2643
1525
|
import path3 from "path";
|
|
2644
1526
|
var XLSX = XLSXMod.default ?? XLSXMod;
|
|
2645
|
-
var
|
|
2646
|
-
var
|
|
1527
|
+
var VALID_PROP_TYPES = /* @__PURE__ */ new Set(["string", "number", "bool", "datetime", "object", "array_row", "array_string"]);
|
|
1528
|
+
var VALID_UPDATE_TYPES = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
|
|
2647
1529
|
function normalizeHeader(h) {
|
|
2648
1530
|
return h.trim().replace(/[((]\s*(?:必填|必須|필수|required|Required)\s*[))]/g, "").trim().replace(/名称$/g, "\u540D");
|
|
2649
1531
|
}
|
|
@@ -2674,7 +1556,7 @@ function cellStr(row, idx) {
|
|
|
2674
1556
|
function parsePropType(raw, propName, sheetCtx) {
|
|
2675
1557
|
const canonical = displayToType(raw);
|
|
2676
1558
|
if (canonical) return canonical;
|
|
2677
|
-
if (
|
|
1559
|
+
if (VALID_PROP_TYPES.has(raw)) return raw;
|
|
2678
1560
|
process.stderr.write(
|
|
2679
1561
|
`[read] unknown type "${raw}" on ${sheetCtx}:${propName}, defaulting to string
|
|
2680
1562
|
`
|
|
@@ -2682,7 +1564,7 @@ function parsePropType(raw, propName, sheetCtx) {
|
|
|
2682
1564
|
return "string";
|
|
2683
1565
|
}
|
|
2684
1566
|
function parseUpdateType(raw, propName) {
|
|
2685
|
-
if (
|
|
1567
|
+
if (VALID_UPDATE_TYPES.has(raw)) return raw;
|
|
2686
1568
|
process.stderr.write(
|
|
2687
1569
|
`[xlsx/read] Warning: unknown update_type "${raw}" for user property "${propName}", falling back to "user_set"
|
|
2688
1570
|
`
|
|
@@ -2695,7 +1577,7 @@ function shouldSkipRow(row, firstColIdx) {
|
|
|
2695
1577
|
if (!/^[a-zA-Z#][a-zA-Z0-9_.]*$/.test(first)) return true;
|
|
2696
1578
|
return false;
|
|
2697
1579
|
}
|
|
2698
|
-
function parseEventSheet(rows, source,
|
|
1580
|
+
function parseEventSheet(rows, source, sheetName) {
|
|
2699
1581
|
const eventsMap = /* @__PURE__ */ new Map();
|
|
2700
1582
|
const propsMap = /* @__PURE__ */ new Map();
|
|
2701
1583
|
const eventsOrder = [];
|
|
@@ -2797,7 +1679,7 @@ function parseEventSheet(rows, source, sheetName2) {
|
|
|
2797
1679
|
evt.prop_names.push(propName);
|
|
2798
1680
|
}
|
|
2799
1681
|
if (!propsMap.has(propName)) {
|
|
2800
|
-
const propType = parsePropType(propTypeRaw, propName,
|
|
1682
|
+
const propType = parsePropType(propTypeRaw, propName, sheetName);
|
|
2801
1683
|
const prop = {
|
|
2802
1684
|
name: propName,
|
|
2803
1685
|
type: propType,
|
|
@@ -2808,7 +1690,7 @@ function parseEventSheet(rows, source, sheetName2) {
|
|
|
2808
1690
|
propsMap.set(propName, prop);
|
|
2809
1691
|
} else {
|
|
2810
1692
|
const existing = propsMap.get(propName);
|
|
2811
|
-
const newType = parsePropType(propTypeRaw, propName,
|
|
1693
|
+
const newType = parsePropType(propTypeRaw, propName, sheetName);
|
|
2812
1694
|
if (propTypeRaw && existing.type !== newType) {
|
|
2813
1695
|
process.stderr.write(
|
|
2814
1696
|
`[xlsx/read] Warning: property "${propName}" has conflicting types: "${existing.type}" vs "${newType}". Keeping first.
|
|
@@ -2822,7 +1704,7 @@ function parseEventSheet(rows, source, sheetName2) {
|
|
|
2822
1704
|
const event_properties = Array.from(propsMap.values());
|
|
2823
1705
|
return { events, event_properties };
|
|
2824
1706
|
}
|
|
2825
|
-
function parseCommonEventSheet(rows, source,
|
|
1707
|
+
function parseCommonEventSheet(rows, source, sheetName) {
|
|
2826
1708
|
const props = [];
|
|
2827
1709
|
const seen = /* @__PURE__ */ new Set();
|
|
2828
1710
|
if (rows.length < 2) return props;
|
|
@@ -2866,7 +1748,7 @@ function parseCommonEventSheet(rows, source, sheetName2) {
|
|
|
2866
1748
|
seen.add(name);
|
|
2867
1749
|
const prop = {
|
|
2868
1750
|
name,
|
|
2869
|
-
type: parsePropType(typeRaw, name,
|
|
1751
|
+
type: parsePropType(typeRaw, name, sheetName),
|
|
2870
1752
|
source
|
|
2871
1753
|
};
|
|
2872
1754
|
if (displayName) prop.display_name = displayName;
|
|
@@ -2875,7 +1757,7 @@ function parseCommonEventSheet(rows, source, sheetName2) {
|
|
|
2875
1757
|
}
|
|
2876
1758
|
return props;
|
|
2877
1759
|
}
|
|
2878
|
-
function parseUserDataSheet(rows, source,
|
|
1760
|
+
function parseUserDataSheet(rows, source, sheetName) {
|
|
2879
1761
|
const props = [];
|
|
2880
1762
|
const seen = /* @__PURE__ */ new Set();
|
|
2881
1763
|
if (rows.length < 2) return props;
|
|
@@ -2916,7 +1798,7 @@ function parseUserDataSheet(rows, source, sheetName2) {
|
|
|
2916
1798
|
seen.add(name);
|
|
2917
1799
|
const prop = {
|
|
2918
1800
|
name,
|
|
2919
|
-
type: parsePropType(typeRaw, name,
|
|
1801
|
+
type: parsePropType(typeRaw, name, sheetName),
|
|
2920
1802
|
update_type: parseUpdateType(updateTypeRaw, name),
|
|
2921
1803
|
source
|
|
2922
1804
|
};
|
|
@@ -3020,14 +1902,14 @@ function findCol(colIndex, candidates, fallback) {
|
|
|
3020
1902
|
}
|
|
3021
1903
|
return fallback;
|
|
3022
1904
|
}
|
|
3023
|
-
var
|
|
1905
|
+
var VALID_UPDATE_TYPES2 = /* @__PURE__ */ new Set(["user_set", "user_setOnce", "user_add"]);
|
|
3024
1906
|
function parseType(raw) {
|
|
3025
1907
|
const canonical = displayToType(raw);
|
|
3026
1908
|
if (canonical) return canonical;
|
|
3027
1909
|
return "string";
|
|
3028
1910
|
}
|
|
3029
1911
|
function parseUpdateType2(raw) {
|
|
3030
|
-
if (
|
|
1912
|
+
if (VALID_UPDATE_TYPES2.has(raw)) return raw;
|
|
3031
1913
|
return "user_set";
|
|
3032
1914
|
}
|
|
3033
1915
|
function trimCell(s) {
|
|
@@ -3277,7 +2159,7 @@ function registerCode(cmd) {
|
|
|
3277
2159
|
if (opts.server) {
|
|
3278
2160
|
draft.meta.server_language = opts.server;
|
|
3279
2161
|
}
|
|
3280
|
-
await mkdir(
|
|
2162
|
+
await mkdir(dirname(opts.out), { recursive: true });
|
|
3281
2163
|
await writeFile2(opts.out, JSON.stringify(draft, null, 2), "utf8");
|
|
3282
2164
|
process.stdout.write(t("code.wrote_events", { count: draft.events.length, path: opts.out }) + "\n");
|
|
3283
2165
|
});
|
|
@@ -3310,13 +2192,13 @@ function registerCode(cmd) {
|
|
|
3310
2192
|
}
|
|
3311
2193
|
|
|
3312
2194
|
// src/tracking/wiki-query/query.ts
|
|
3313
|
-
import { readFileSync
|
|
3314
|
-
import { join as
|
|
3315
|
-
var WIKI_ROOT =
|
|
2195
|
+
import { readFileSync, existsSync as existsSync4 } from "fs";
|
|
2196
|
+
import { join as join2 } from "path";
|
|
2197
|
+
var WIKI_ROOT = join2(getPackageRoot(), "wiki/te-docs");
|
|
3316
2198
|
function searchIndex(keyword) {
|
|
3317
|
-
const indexPath =
|
|
3318
|
-
if (!
|
|
3319
|
-
const lines =
|
|
2199
|
+
const indexPath = join2(WIKI_ROOT, "index.md");
|
|
2200
|
+
if (!existsSync4(indexPath)) return [];
|
|
2201
|
+
const lines = readFileSync(indexPath, "utf8").split("\n");
|
|
3320
2202
|
const kw = keyword.toLowerCase();
|
|
3321
2203
|
const hits = [];
|
|
3322
2204
|
for (const line of lines) {
|
|
@@ -3471,62 +2353,72 @@ program.name("ae-cli").version(version).description("CLI tool for ThinkingAI (AE
|
|
|
3471
2353
|
async function loadCommands() {
|
|
3472
2354
|
const commands = [];
|
|
3473
2355
|
try {
|
|
3474
|
-
const teAnalysis = await import("./te-analysis-
|
|
2356
|
+
const teAnalysis = await import("./te-analysis-MNCG65LU.js");
|
|
3475
2357
|
commands.push(...teAnalysis.default);
|
|
3476
2358
|
} catch {
|
|
3477
2359
|
}
|
|
3478
2360
|
try {
|
|
3479
|
-
const engage = await import("./te-engage-
|
|
2361
|
+
const engage = await import("./te-engage-TPKLRVTL.js");
|
|
3480
2362
|
commands.push(...engage.default);
|
|
3481
2363
|
} catch {
|
|
3482
2364
|
}
|
|
3483
2365
|
try {
|
|
3484
|
-
const experiment = await import("./te-experiment-
|
|
2366
|
+
const experiment = await import("./te-experiment-6BYKTCY7.js");
|
|
3485
2367
|
commands.push(...experiment.default);
|
|
3486
2368
|
} catch {
|
|
3487
2369
|
}
|
|
3488
2370
|
try {
|
|
3489
|
-
const community = await import("./te-community-
|
|
2371
|
+
const community = await import("./te-community-BNE6KREL.js");
|
|
3490
2372
|
commands.push(...community.default);
|
|
3491
2373
|
} catch {
|
|
3492
2374
|
}
|
|
3493
2375
|
try {
|
|
3494
|
-
const dataops = await import("./te-dataops-
|
|
2376
|
+
const dataops = await import("./te-dataops-TXLKM2W6.js");
|
|
3495
2377
|
commands.push(...dataops.default);
|
|
3496
2378
|
} catch {
|
|
3497
2379
|
}
|
|
3498
2380
|
try {
|
|
3499
|
-
const teKb = await import("./te-kb-
|
|
2381
|
+
const teKb = await import("./te-kb-BUD6N3NI.js");
|
|
3500
2382
|
commands.push(...teKb.default);
|
|
3501
2383
|
} catch {
|
|
3502
2384
|
}
|
|
3503
2385
|
try {
|
|
3504
|
-
const teTeam = await import("./te-team-
|
|
2386
|
+
const teTeam = await import("./te-team-XMP47YXE.js");
|
|
3505
2387
|
commands.push(...teTeam.default);
|
|
3506
2388
|
} catch {
|
|
3507
2389
|
}
|
|
3508
2390
|
try {
|
|
3509
|
-
const teAgent = await import("./te-agent-
|
|
2391
|
+
const teAgent = await import("./te-agent-WQZTMEK4.js");
|
|
3510
2392
|
commands.push(...teAgent.default);
|
|
3511
2393
|
} catch {
|
|
3512
2394
|
}
|
|
3513
2395
|
try {
|
|
3514
|
-
const memory = await import("./memory-
|
|
2396
|
+
const memory = await import("./memory-HBJQ2GC5.js");
|
|
3515
2397
|
commands.push(...memory.default);
|
|
3516
2398
|
} catch {
|
|
3517
2399
|
}
|
|
3518
2400
|
try {
|
|
3519
|
-
const teSystem = await import("./te-system-
|
|
2401
|
+
const teSystem = await import("./te-system-44LZJDTQ.js");
|
|
3520
2402
|
commands.push(...teSystem.default);
|
|
3521
2403
|
} catch {
|
|
3522
2404
|
}
|
|
3523
2405
|
try {
|
|
3524
|
-
const metadata = await import("./metadata-
|
|
2406
|
+
const metadata = await import("./metadata-62EWBEIG.js");
|
|
3525
2407
|
commands.push(...metadata.default);
|
|
3526
2408
|
} catch {
|
|
3527
2409
|
}
|
|
3528
2410
|
try {
|
|
3529
|
-
const
|
|
2411
|
+
const projectSemantic = await import("./project-semantic-BQ4MPUS5.js");
|
|
2412
|
+
commands.push(...projectSemantic.default);
|
|
2413
|
+
} catch {
|
|
2414
|
+
}
|
|
2415
|
+
try {
|
|
2416
|
+
const personalSemanticPreference = await import("./personal-semantic-preference-JBVMAI7L.js");
|
|
2417
|
+
commands.push(...personalSemanticPreference.default);
|
|
2418
|
+
} catch {
|
|
2419
|
+
}
|
|
2420
|
+
try {
|
|
2421
|
+
const dataIntegration = await import("./data-integration-4NZGZ45E.js");
|
|
3530
2422
|
commands.push(...dataIntegration.default);
|
|
3531
2423
|
} catch {
|
|
3532
2424
|
}
|
|
@@ -3534,42 +2426,42 @@ async function loadCommands() {
|
|
|
3534
2426
|
}
|
|
3535
2427
|
async function registerAuthCommands() {
|
|
3536
2428
|
try {
|
|
3537
|
-
const { registerAuth } = await import("./auth-
|
|
2429
|
+
const { registerAuth } = await import("./auth-QPEVVBKT.js");
|
|
3538
2430
|
registerAuth(program);
|
|
3539
2431
|
} catch {
|
|
3540
2432
|
}
|
|
3541
2433
|
}
|
|
3542
2434
|
async function registerConfigCommands() {
|
|
3543
2435
|
try {
|
|
3544
|
-
const { registerConfig } = await import("./config-
|
|
2436
|
+
const { registerConfig } = await import("./config-XNMACCKX.js");
|
|
3545
2437
|
registerConfig(program);
|
|
3546
2438
|
} catch {
|
|
3547
2439
|
}
|
|
3548
2440
|
}
|
|
3549
2441
|
async function registerCapabilityCommands() {
|
|
3550
2442
|
try {
|
|
3551
|
-
const { registerCapability } = await import("./capability-
|
|
2443
|
+
const { registerCapability } = await import("./capability-ASI62I4A.js");
|
|
3552
2444
|
registerCapability(program);
|
|
3553
2445
|
} catch {
|
|
3554
2446
|
}
|
|
3555
2447
|
}
|
|
3556
2448
|
async function registerSyncCommand() {
|
|
3557
2449
|
try {
|
|
3558
|
-
const { registerSync } = await import("./sync-
|
|
2450
|
+
const { registerSync } = await import("./sync-MUWPRM5I.js");
|
|
3559
2451
|
registerSync(program);
|
|
3560
2452
|
} catch {
|
|
3561
2453
|
}
|
|
3562
2454
|
}
|
|
3563
2455
|
async function registerModelCommand() {
|
|
3564
2456
|
try {
|
|
3565
|
-
const { registerModel } = await import("./model-
|
|
2457
|
+
const { registerModel } = await import("./model-BHLJ2QMT.js");
|
|
3566
2458
|
registerModel(program);
|
|
3567
2459
|
} catch {
|
|
3568
2460
|
}
|
|
3569
2461
|
}
|
|
3570
2462
|
async function registerUpdateCommand() {
|
|
3571
2463
|
try {
|
|
3572
|
-
const { registerUpdate } = await import("./update-
|
|
2464
|
+
const { registerUpdate } = await import("./update-UODFOZ4P.js");
|
|
3573
2465
|
registerUpdate(program);
|
|
3574
2466
|
} catch {
|
|
3575
2467
|
}
|