siluzan-tso-cli 1.1.58 → 1.1.59-beta.2
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 -1
- package/dist/index.js +549 -410
- package/dist/skill/AGENTS.md +1 -1
- package/dist/skill/SKILL.md +1 -1
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/accounts/accounts-balance-stats.md +2 -1
- package/dist/skill/references/accounts/accounts-list.md +1 -1
- package/dist/skill/references/accounts/accounts-permissions.md +2 -2
- package/dist/skill/references/accounts/finance.md +1 -1
- package/dist/skill/references/accounts/open-account-by-media.md +1 -1
- package/dist/skill/references/accounts/open-account-google-ui.md +1 -1
- package/dist/skill/references/analytics/keyword-planner-workflows.md +29 -17
- package/dist/skill/references/analytics/rag.md +1 -1
- package/dist/skill/references/analytics/reporting.md +5 -5
- package/dist/skill/references/core/intent-routing.md +4 -2
- package/dist/skill/references/core/setup.md +5 -5
- package/dist/skill/references/core/workflows.md +3 -3
- package/dist/skill/references/misc/tso-home.md +2 -2
- package/dist/skill/scripts/install.ps1 +3 -3
- package/dist/skill/scripts/install.sh +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4049,7 +4049,7 @@ var DEFAULT_API_BASE;
|
|
|
4049
4049
|
var init_defaults = __esm({
|
|
4050
4050
|
"src/config/defaults.ts"() {
|
|
4051
4051
|
"use strict";
|
|
4052
|
-
DEFAULT_API_BASE = "https://tso-api.siluzan.com";
|
|
4052
|
+
DEFAULT_API_BASE = "https://tso-api-ci.siluzan.com";
|
|
4053
4053
|
}
|
|
4054
4054
|
});
|
|
4055
4055
|
|
|
@@ -5983,6 +5983,7 @@ async function runAccountsDigest(opts) {
|
|
|
5983
5983
|
const fields = (row.spend ?? 0) > 0 ? summaries.get(row.mediaCustomerId) ?? errorCampaignTypes("\u672A\u8FD4\u56DE\u8BE5\u8D26\u6237\u7684\u7CFB\u5217\u7C7B\u578B") : skippedNoSpendCampaignTypes();
|
|
5984
5984
|
row.campaignTypesStatus = fields.campaignTypesStatus;
|
|
5985
5985
|
row.campaignTypes = fields.campaignTypes;
|
|
5986
|
+
row.channelTypeV2 = fields.campaignTypesStatus === "ok" ? fields.campaignTypes : null;
|
|
5986
5987
|
row.hasDisplay = fields.hasDisplay;
|
|
5987
5988
|
row.hasPmax = fields.hasPmax;
|
|
5988
5989
|
row.campaignTypesError = fields.campaignTypesError;
|
|
@@ -6726,8 +6727,8 @@ var init_bid_modifier_display = __esm({
|
|
|
6726
6727
|
});
|
|
6727
6728
|
|
|
6728
6729
|
// src/commands/facebook-analysis/xlsx-style-engine.ts
|
|
6729
|
-
import
|
|
6730
|
-
import
|
|
6730
|
+
import fs11 from "fs";
|
|
6731
|
+
import path16 from "path";
|
|
6731
6732
|
function resolveAccent(accent) {
|
|
6732
6733
|
if (!accent) return PLATFORM_ACCENTS.default;
|
|
6733
6734
|
const hex = accent.replace(/^#/, "");
|
|
@@ -7216,9 +7217,9 @@ var init_xlsx_style_engine = __esm({
|
|
|
7216
7217
|
return zipStore(files);
|
|
7217
7218
|
}
|
|
7218
7219
|
writeFile(filePath) {
|
|
7219
|
-
const abs =
|
|
7220
|
-
|
|
7221
|
-
|
|
7220
|
+
const abs = path16.resolve(filePath);
|
|
7221
|
+
fs11.mkdirSync(path16.dirname(abs), { recursive: true });
|
|
7222
|
+
fs11.writeFileSync(abs, this.toBuffer());
|
|
7222
7223
|
return abs;
|
|
7223
7224
|
}
|
|
7224
7225
|
};
|
|
@@ -103820,8 +103821,8 @@ var init_okki_display = __esm({
|
|
|
103820
103821
|
});
|
|
103821
103822
|
|
|
103822
103823
|
// src/commands/google-analysis/merge-snapshot.ts
|
|
103823
|
-
import * as
|
|
103824
|
-
import * as
|
|
103824
|
+
import * as fs28 from "fs/promises";
|
|
103825
|
+
import * as path33 from "path";
|
|
103825
103826
|
function asRecord20(value) {
|
|
103826
103827
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
103827
103828
|
return value;
|
|
@@ -103839,7 +103840,7 @@ async function readManifest(snapshotDir, accountId) {
|
|
|
103839
103840
|
const candidates = [];
|
|
103840
103841
|
if (accountId) candidates.push(googleAnalysisManifestFile(accountId));
|
|
103841
103842
|
try {
|
|
103842
|
-
const entries = await
|
|
103843
|
+
const entries = await fs28.readdir(snapshotDir);
|
|
103843
103844
|
const manifestNames = entries.filter((n) => n.startsWith("manifest") && n.endsWith(".json"));
|
|
103844
103845
|
for (const name2 of manifestNames) {
|
|
103845
103846
|
if (!candidates.includes(name2)) candidates.push(name2);
|
|
@@ -103848,7 +103849,7 @@ async function readManifest(snapshotDir, accountId) {
|
|
|
103848
103849
|
}
|
|
103849
103850
|
for (const name2 of candidates) {
|
|
103850
103851
|
try {
|
|
103851
|
-
const raw = await
|
|
103852
|
+
const raw = await fs28.readFile(path33.join(snapshotDir, name2), "utf8");
|
|
103852
103853
|
const parsed = JSON.parse(raw);
|
|
103853
103854
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
103854
103855
|
} catch {
|
|
@@ -103858,7 +103859,7 @@ async function readManifest(snapshotDir, accountId) {
|
|
|
103858
103859
|
}
|
|
103859
103860
|
async function loadSectionFile(snapshotDir, file) {
|
|
103860
103861
|
try {
|
|
103861
|
-
const raw = await
|
|
103862
|
+
const raw = await fs28.readFile(path33.join(snapshotDir, file), "utf8");
|
|
103862
103863
|
const parsed = JSON.parse(raw);
|
|
103863
103864
|
if (parsed && typeof parsed === "object") return parsed;
|
|
103864
103865
|
return null;
|
|
@@ -103892,7 +103893,7 @@ async function recoverMissingReportSections(sectionMap, absDir, accountId, prefe
|
|
|
103892
103893
|
if (!accountId) return;
|
|
103893
103894
|
let entries;
|
|
103894
103895
|
try {
|
|
103895
|
-
entries = await
|
|
103896
|
+
entries = await fs28.readdir(absDir);
|
|
103896
103897
|
} catch {
|
|
103897
103898
|
return;
|
|
103898
103899
|
}
|
|
@@ -103964,7 +103965,7 @@ function sumCampaignRowsToPeriodKpis(rows) {
|
|
|
103964
103965
|
};
|
|
103965
103966
|
}
|
|
103966
103967
|
async function mergeGoogleAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
103967
|
-
const absDir =
|
|
103968
|
+
const absDir = path33.resolve(snapshotDir);
|
|
103968
103969
|
const metaAccountId = typeof asRecord20(payload.meta)?.accountId === "string" ? asRecord20(payload.meta)?.accountId : void 0;
|
|
103969
103970
|
const manifest = await readManifest(snapshotDir, metaAccountId);
|
|
103970
103971
|
if (!manifest) {
|
|
@@ -104310,8 +104311,8 @@ var init_okki_report_content = __esm({
|
|
|
104310
104311
|
});
|
|
104311
104312
|
|
|
104312
104313
|
// src/commands/google-analysis/okki-merge-snapshot.ts
|
|
104313
|
-
import * as
|
|
104314
|
-
import * as
|
|
104314
|
+
import * as fs29 from "fs/promises";
|
|
104315
|
+
import * as path34 from "path";
|
|
104315
104316
|
function num5(value) {
|
|
104316
104317
|
const n = Number(value);
|
|
104317
104318
|
return Number.isFinite(n) ? n : void 0;
|
|
@@ -104337,7 +104338,7 @@ async function readManifest2(snapshotDir, accountId) {
|
|
|
104337
104338
|
const candidates = [];
|
|
104338
104339
|
if (accountId) candidates.push(googleAnalysisManifestFile(accountId));
|
|
104339
104340
|
try {
|
|
104340
|
-
const entries = await
|
|
104341
|
+
const entries = await fs29.readdir(snapshotDir);
|
|
104341
104342
|
for (const name2 of entries.filter((n) => n.startsWith("manifest") && n.endsWith(".json"))) {
|
|
104342
104343
|
if (!candidates.includes(name2)) candidates.push(name2);
|
|
104343
104344
|
}
|
|
@@ -104345,7 +104346,7 @@ async function readManifest2(snapshotDir, accountId) {
|
|
|
104345
104346
|
}
|
|
104346
104347
|
for (const name2 of candidates) {
|
|
104347
104348
|
try {
|
|
104348
|
-
const raw = await
|
|
104349
|
+
const raw = await fs29.readFile(path34.join(snapshotDir, name2), "utf8");
|
|
104349
104350
|
const parsed = JSON.parse(raw);
|
|
104350
104351
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
104351
104352
|
} catch {
|
|
@@ -104355,7 +104356,7 @@ async function readManifest2(snapshotDir, accountId) {
|
|
|
104355
104356
|
}
|
|
104356
104357
|
async function loadSectionFile2(snapshotDir, file) {
|
|
104357
104358
|
try {
|
|
104358
|
-
const raw = await
|
|
104359
|
+
const raw = await fs29.readFile(path34.join(snapshotDir, file), "utf8");
|
|
104359
104360
|
const parsed = JSON.parse(raw);
|
|
104360
104361
|
if (parsed && typeof parsed === "object") return parsed;
|
|
104361
104362
|
return null;
|
|
@@ -104364,7 +104365,7 @@ async function loadSectionFile2(snapshotDir, file) {
|
|
|
104364
104365
|
}
|
|
104365
104366
|
}
|
|
104366
104367
|
async function mergeOkkiSnapshotIntoReport(payload, snapshotDir) {
|
|
104367
|
-
const absDir =
|
|
104368
|
+
const absDir = path34.resolve(snapshotDir);
|
|
104368
104369
|
const metaAccountId = typeof asRecord21(payload.meta)?.accountId === "string" ? asRecord21(payload.meta)?.accountId : void 0;
|
|
104369
104370
|
const manifest = await readManifest2(absDir, metaAccountId);
|
|
104370
104371
|
if (!manifest) {
|
|
@@ -104381,7 +104382,7 @@ async function mergeOkkiSnapshotIntoReport(payload, snapshotDir) {
|
|
|
104381
104382
|
if (accountId) {
|
|
104382
104383
|
let entries = [];
|
|
104383
104384
|
try {
|
|
104384
|
-
entries = await
|
|
104385
|
+
entries = await fs29.readdir(absDir);
|
|
104385
104386
|
} catch {
|
|
104386
104387
|
entries = [];
|
|
104387
104388
|
}
|
|
@@ -104875,10 +104876,10 @@ var init_okki_render_excel = __esm({
|
|
|
104875
104876
|
});
|
|
104876
104877
|
|
|
104877
104878
|
// src/commands/google-analysis/okki-render-report.ts
|
|
104878
|
-
import
|
|
104879
|
-
import
|
|
104879
|
+
import fs30 from "fs/promises";
|
|
104880
|
+
import path35 from "path";
|
|
104880
104881
|
async function readJsonFile2(filePath) {
|
|
104881
|
-
const text3 = await
|
|
104882
|
+
const text3 = await fs30.readFile(filePath, "utf8");
|
|
104882
104883
|
try {
|
|
104883
104884
|
return JSON.parse(text3);
|
|
104884
104885
|
} catch {
|
|
@@ -104892,7 +104893,7 @@ function asPayload(value) {
|
|
|
104892
104893
|
throw new Error("\u62A5\u544A\u6570\u636E\u987B\u4E3A JSON \u5BF9\u8C61");
|
|
104893
104894
|
}
|
|
104894
104895
|
async function runGoogleAnalysisOkkiRender(opts) {
|
|
104895
|
-
const dataPath =
|
|
104896
|
+
const dataPath = path35.resolve(opts.dataFile);
|
|
104896
104897
|
const snapshotDir = opts.snapshotDir?.trim();
|
|
104897
104898
|
if (!snapshotDir) {
|
|
104898
104899
|
console.error("\n\u274C okki-render \u5FC5\u987B\u4F20 --snapshot-dir\uFF08google-analysis --json-out \u76EE\u5F55\uFF09\n");
|
|
@@ -104900,7 +104901,7 @@ async function runGoogleAnalysisOkkiRender(opts) {
|
|
|
104900
104901
|
}
|
|
104901
104902
|
let data = asPayload(await readJsonFile2(dataPath));
|
|
104902
104903
|
try {
|
|
104903
|
-
data = await mergeOkkiSnapshotIntoReport(data,
|
|
104904
|
+
data = await mergeOkkiSnapshotIntoReport(data, path35.resolve(snapshotDir));
|
|
104904
104905
|
} catch (err) {
|
|
104905
104906
|
console.error(`
|
|
104906
104907
|
\u274C ${err instanceof Error ? err.message : String(err)}
|
|
@@ -104919,10 +104920,10 @@ async function runGoogleAnalysisOkkiRender(opts) {
|
|
|
104919
104920
|
);
|
|
104920
104921
|
process.exit(1);
|
|
104921
104922
|
}
|
|
104922
|
-
const outPath =
|
|
104923
|
-
opts.out ??
|
|
104923
|
+
const outPath = path35.resolve(
|
|
104924
|
+
opts.out ?? path35.join(path35.dirname(dataPath), "okki-weekly-report.xlsx")
|
|
104924
104925
|
);
|
|
104925
|
-
await
|
|
104926
|
+
await fs30.mkdir(path35.dirname(outPath), { recursive: true });
|
|
104926
104927
|
writeOkkiWeeklyExcel(outPath, data);
|
|
104927
104928
|
console.log(`
|
|
104928
104929
|
\u2705 OKKI \u5468\u62A5\u5DF2\u751F\u6210\uFF1A${outPath}
|
|
@@ -105082,19 +105083,19 @@ var init_report_content = __esm({
|
|
|
105082
105083
|
});
|
|
105083
105084
|
|
|
105084
105085
|
// src/commands/google-analysis/render-report.ts
|
|
105085
|
-
import
|
|
105086
|
+
import fs31 from "fs";
|
|
105086
105087
|
import fsPromises2 from "fs/promises";
|
|
105087
|
-
import
|
|
105088
|
+
import path36 from "path";
|
|
105088
105089
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
105089
105090
|
function resolveSkillTemplatePath3(basename13) {
|
|
105090
|
-
const dir =
|
|
105091
|
+
const dir = path36.dirname(fileURLToPath9(import.meta.url));
|
|
105091
105092
|
const candidates = [
|
|
105092
|
-
|
|
105093
|
-
|
|
105094
|
-
|
|
105093
|
+
path36.join(dir, "skill", "report-templates", basename13),
|
|
105094
|
+
path36.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
105095
|
+
path36.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
105095
105096
|
];
|
|
105096
105097
|
for (const p of candidates) {
|
|
105097
|
-
if (
|
|
105098
|
+
if (fs31.existsSync(p)) return p;
|
|
105098
105099
|
}
|
|
105099
105100
|
return candidates[0];
|
|
105100
105101
|
}
|
|
@@ -105123,10 +105124,10 @@ function injectReportData2(html, payload) {
|
|
|
105123
105124
|
return html.replace(INJECT_MARKER, `window.__GOOGLE_PERIOD_REPORT__ = ${json};`);
|
|
105124
105125
|
}
|
|
105125
105126
|
async function runGoogleAnalysisRender(opts) {
|
|
105126
|
-
const dataPath =
|
|
105127
|
+
const dataPath = path36.resolve(opts.dataFile);
|
|
105127
105128
|
let data = asRecord23(await readJsonFile3(dataPath));
|
|
105128
105129
|
if (opts.snapshotDir?.trim()) {
|
|
105129
|
-
data = await mergeGoogleAnalysisSnapshotIntoReport(data,
|
|
105130
|
+
data = await mergeGoogleAnalysisSnapshotIntoReport(data, path36.resolve(opts.snapshotDir));
|
|
105130
105131
|
}
|
|
105131
105132
|
const contentCheck = validateGooglePeriodReportContent(data);
|
|
105132
105133
|
if (!contentCheck.ok) {
|
|
@@ -105152,10 +105153,10 @@ async function runGoogleAnalysisRender(opts) {
|
|
|
105152
105153
|
`);
|
|
105153
105154
|
process.exit(1);
|
|
105154
105155
|
}
|
|
105155
|
-
const outPath =
|
|
105156
|
-
opts.out ??
|
|
105156
|
+
const outPath = path36.resolve(
|
|
105157
|
+
opts.out ?? path36.join(path36.dirname(dataPath), "google-period-report.html")
|
|
105157
105158
|
);
|
|
105158
|
-
const outDir =
|
|
105159
|
+
const outDir = path36.dirname(outPath);
|
|
105159
105160
|
await fsPromises2.mkdir(outDir, { recursive: true });
|
|
105160
105161
|
await fsPromises2.writeFile(outPath, injectReportData2(html, data), "utf8");
|
|
105161
105162
|
const { stats } = contentCheck;
|
|
@@ -105184,8 +105185,8 @@ var init_render_report = __esm({
|
|
|
105184
105185
|
});
|
|
105185
105186
|
|
|
105186
105187
|
// src/utils/batch-manifest.ts
|
|
105187
|
-
import * as
|
|
105188
|
-
import * as
|
|
105188
|
+
import * as fs32 from "fs/promises";
|
|
105189
|
+
import * as path37 from "path";
|
|
105189
105190
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
105190
105191
|
function generateRunId(now = /* @__PURE__ */ new Date()) {
|
|
105191
105192
|
const pad3 = (n) => String(n).padStart(2, "0");
|
|
@@ -105199,26 +105200,26 @@ function isValidRunId(id) {
|
|
|
105199
105200
|
}
|
|
105200
105201
|
function resolveBatchPaths(baseDir, runId) {
|
|
105201
105202
|
if (!isValidRunId(runId)) throw new Error(`\u975E\u6CD5 runId\uFF1A${runId}`);
|
|
105202
|
-
const runDir =
|
|
105203
|
-
const stateDir =
|
|
105203
|
+
const runDir = path37.resolve(baseDir, runId);
|
|
105204
|
+
const stateDir = path37.join(runDir, "state");
|
|
105204
105205
|
return {
|
|
105205
105206
|
runDir,
|
|
105206
|
-
runManifestFile:
|
|
105207
|
-
progressFile:
|
|
105208
|
-
accountsFile:
|
|
105209
|
-
resultsDir:
|
|
105210
|
-
errorsDir:
|
|
105207
|
+
runManifestFile: path37.join(runDir, "run-manifest.json"),
|
|
105208
|
+
progressFile: path37.join(runDir, "progress.json"),
|
|
105209
|
+
accountsFile: path37.join(runDir, "accounts.json"),
|
|
105210
|
+
resultsDir: path37.join(runDir, "results"),
|
|
105211
|
+
errorsDir: path37.join(runDir, "errors"),
|
|
105211
105212
|
stateDir,
|
|
105212
|
-
tasksLogFile:
|
|
105213
|
-
lockFile:
|
|
105213
|
+
tasksLogFile: path37.join(stateDir, "tasks.jsonl"),
|
|
105214
|
+
lockFile: path37.join(stateDir, "tasks.lock")
|
|
105214
105215
|
};
|
|
105215
105216
|
}
|
|
105216
105217
|
async function ensureAccountDirs(paths, accountId) {
|
|
105217
105218
|
const safe = sanitizeAccountSegment(accountId);
|
|
105218
|
-
const results =
|
|
105219
|
-
const errors =
|
|
105220
|
-
await
|
|
105221
|
-
await
|
|
105219
|
+
const results = path37.join(paths.resultsDir, safe);
|
|
105220
|
+
const errors = path37.join(paths.errorsDir, safe);
|
|
105221
|
+
await fs32.mkdir(results, { recursive: true });
|
|
105222
|
+
await fs32.mkdir(errors, { recursive: true });
|
|
105222
105223
|
return { results, errors };
|
|
105223
105224
|
}
|
|
105224
105225
|
function sanitizeAccountSegment(accountId) {
|
|
@@ -105233,20 +105234,20 @@ function sanitizeAccountSegment(accountId) {
|
|
|
105233
105234
|
return slug;
|
|
105234
105235
|
}
|
|
105235
105236
|
async function atomicWriteFile(target, content) {
|
|
105236
|
-
const dir =
|
|
105237
|
-
await
|
|
105238
|
-
const tmp =
|
|
105237
|
+
const dir = path37.dirname(target);
|
|
105238
|
+
await fs32.mkdir(dir, { recursive: true });
|
|
105239
|
+
const tmp = path37.join(dir, `.tmp-${randomUUID2()}-${path37.basename(target)}`);
|
|
105239
105240
|
try {
|
|
105240
|
-
await
|
|
105241
|
-
await
|
|
105241
|
+
await fs32.writeFile(tmp, content, "utf8");
|
|
105242
|
+
await fs32.rename(tmp, target);
|
|
105242
105243
|
} catch (e) {
|
|
105243
|
-
await
|
|
105244
|
+
await fs32.rm(tmp, { force: true }).catch(() => void 0);
|
|
105244
105245
|
throw e;
|
|
105245
105246
|
}
|
|
105246
105247
|
}
|
|
105247
105248
|
async function readJsonIfExists(file) {
|
|
105248
105249
|
try {
|
|
105249
|
-
const raw = await
|
|
105250
|
+
const raw = await fs32.readFile(file, "utf8");
|
|
105250
105251
|
return JSON.parse(raw);
|
|
105251
105252
|
} catch (e) {
|
|
105252
105253
|
if (e.code === "ENOENT") return null;
|
|
@@ -105289,8 +105290,8 @@ function isTaskLogEntry(value) {
|
|
|
105289
105290
|
return typeof row.at === "string" && typeof row.id === "string" && typeof row.accountId === "string" && typeof row.section === "string" && typeof row.state === "string" && TASK_LOG_STATES.has(row.state) && typeof row.attempts === "number";
|
|
105290
105291
|
}
|
|
105291
105292
|
async function writeTaskLogLine(paths, entry) {
|
|
105292
|
-
await
|
|
105293
|
-
await
|
|
105293
|
+
await fs32.mkdir(paths.stateDir, { recursive: true });
|
|
105294
|
+
await fs32.appendFile(paths.tasksLogFile, JSON.stringify(clampTaskLogEntry(entry)) + "\n", "utf8");
|
|
105294
105295
|
}
|
|
105295
105296
|
async function appendTaskLog(paths, entry) {
|
|
105296
105297
|
const file = paths.tasksLogFile;
|
|
@@ -105308,7 +105309,7 @@ async function appendTaskLog(paths, entry) {
|
|
|
105308
105309
|
async function readTaskLog(paths) {
|
|
105309
105310
|
let raw;
|
|
105310
105311
|
try {
|
|
105311
|
-
raw = await
|
|
105312
|
+
raw = await fs32.readFile(paths.tasksLogFile, "utf8");
|
|
105312
105313
|
} catch (e) {
|
|
105313
105314
|
if (e.code === "ENOENT") return [];
|
|
105314
105315
|
throw e;
|
|
@@ -105386,9 +105387,9 @@ function emptyProgress(runId, totalTasks, accountConcurrency, sectionConcurrency
|
|
|
105386
105387
|
};
|
|
105387
105388
|
}
|
|
105388
105389
|
async function tryAcquireLock(paths) {
|
|
105389
|
-
await
|
|
105390
|
+
await fs32.mkdir(paths.stateDir, { recursive: true });
|
|
105390
105391
|
try {
|
|
105391
|
-
const handle = await
|
|
105392
|
+
const handle = await fs32.open(paths.lockFile, "wx");
|
|
105392
105393
|
await handle.writeFile(`${process.pid}@${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
105393
105394
|
await handle.close();
|
|
105394
105395
|
return true;
|
|
@@ -105398,7 +105399,7 @@ async function tryAcquireLock(paths) {
|
|
|
105398
105399
|
}
|
|
105399
105400
|
}
|
|
105400
105401
|
async function releaseLock(paths) {
|
|
105401
|
-
await
|
|
105402
|
+
await fs32.rm(paths.lockFile, { force: true }).catch(() => void 0);
|
|
105402
105403
|
}
|
|
105403
105404
|
var BATCH_SCHEMA_VERSION, MAX_TASK_LOG_ERROR_CHARS, TASK_LOG_STATES, taskLogAppendQueue;
|
|
105404
105405
|
var init_batch_manifest = __esm({
|
|
@@ -105420,8 +105421,8 @@ var init_batch_manifest = __esm({
|
|
|
105420
105421
|
|
|
105421
105422
|
// src/utils/batch-runner.ts
|
|
105422
105423
|
import { performance as performance2 } from "perf_hooks";
|
|
105423
|
-
import * as
|
|
105424
|
-
import * as
|
|
105424
|
+
import * as path38 from "path";
|
|
105425
|
+
import * as fs33 from "fs/promises";
|
|
105425
105426
|
async function runPool(items3, concurrencyRef, worker, signal) {
|
|
105426
105427
|
let cursor = 0;
|
|
105427
105428
|
const launch = () => {
|
|
@@ -105560,7 +105561,7 @@ async function runBatch(opts) {
|
|
|
105560
105561
|
}
|
|
105561
105562
|
const inner = {
|
|
105562
105563
|
...emptyProgress(
|
|
105563
|
-
opts.paths.runDir.split(
|
|
105564
|
+
opts.paths.runDir.split(path38.sep).pop() ?? "run",
|
|
105564
105565
|
allTasks.length,
|
|
105565
105566
|
opts.accountConcurrency,
|
|
105566
105567
|
opts.sectionConcurrency
|
|
@@ -105685,7 +105686,7 @@ async function runBatch(opts) {
|
|
|
105685
105686
|
signal: aborterToken.signal
|
|
105686
105687
|
});
|
|
105687
105688
|
await writer({
|
|
105688
|
-
snapshotDir:
|
|
105689
|
+
snapshotDir: path38.join(opts.paths.resultsDir, sanitizeAccountSegment(task.accountId)),
|
|
105689
105690
|
section: task.section,
|
|
105690
105691
|
accountId: task.accountId,
|
|
105691
105692
|
dateRange: result.dateRange,
|
|
@@ -105774,7 +105775,7 @@ async function runBatch(opts) {
|
|
|
105774
105775
|
};
|
|
105775
105776
|
}
|
|
105776
105777
|
async function writeTaskError(paths, errorsDir, task, err, cls) {
|
|
105777
|
-
const file =
|
|
105778
|
+
const file = path38.join(errorsDir, `${sanitizeSection(task.section)}.error.json`);
|
|
105778
105779
|
const payload = {
|
|
105779
105780
|
schemaVersion: 1,
|
|
105780
105781
|
taskId: task.id,
|
|
@@ -105820,10 +105821,10 @@ async function persistRunMetadata(input) {
|
|
|
105820
105821
|
accountsTotal: input.accounts.length,
|
|
105821
105822
|
invocation: input.invocation
|
|
105822
105823
|
};
|
|
105823
|
-
await
|
|
105824
|
-
await
|
|
105825
|
-
await
|
|
105826
|
-
await
|
|
105824
|
+
await fs33.mkdir(paths.runDir, { recursive: true });
|
|
105825
|
+
await fs33.mkdir(paths.stateDir, { recursive: true });
|
|
105826
|
+
await fs33.mkdir(paths.resultsDir, { recursive: true });
|
|
105827
|
+
await fs33.mkdir(paths.errorsDir, { recursive: true });
|
|
105827
105828
|
await writeRunManifest(paths, manifest);
|
|
105828
105829
|
await writeAccounts(paths, input.accounts);
|
|
105829
105830
|
return paths;
|
|
@@ -105886,7 +105887,7 @@ __export(google_analysis_batch_exports, {
|
|
|
105886
105887
|
parseAccountIds: () => parseAccountIds,
|
|
105887
105888
|
registerGoogleAnalysisBatchCommands: () => registerGoogleAnalysisBatchCommands
|
|
105888
105889
|
});
|
|
105889
|
-
import * as
|
|
105890
|
+
import * as path39 from "path";
|
|
105890
105891
|
import { performance as performance3 } from "perf_hooks";
|
|
105891
105892
|
function parseSections(input) {
|
|
105892
105893
|
if (!input || !input.trim()) return DEFAULT_SECTIONS;
|
|
@@ -106421,7 +106422,7 @@ var init_google_analysis_batch = __esm({
|
|
|
106421
106422
|
});
|
|
106422
106423
|
|
|
106423
106424
|
// src/commands/google-analysis/register-cli.ts
|
|
106424
|
-
import * as
|
|
106425
|
+
import * as path40 from "path";
|
|
106425
106426
|
import { performance as performance4 } from "perf_hooks";
|
|
106426
106427
|
import { Command } from "commander";
|
|
106427
106428
|
function normalizeAnalysisDateOpts(opts) {
|
|
@@ -106559,7 +106560,7 @@ async function runAllSections(opts) {
|
|
|
106559
106560
|
}
|
|
106560
106561
|
const succeeded = results.filter((r) => r.ok).length;
|
|
106561
106562
|
const failed = results.length - succeeded;
|
|
106562
|
-
const absoluteSnapshotDir =
|
|
106563
|
+
const absoluteSnapshotDir = path40.resolve(opts.jsonOut);
|
|
106563
106564
|
const summary = {
|
|
106564
106565
|
kind: "siluzan-tso-google-analysis-snapshot-batch",
|
|
106565
106566
|
absoluteSnapshotDir,
|
|
@@ -106826,8 +106827,8 @@ var init_google_analysis3 = __esm({
|
|
|
106826
106827
|
// src/index.ts
|
|
106827
106828
|
init_dist();
|
|
106828
106829
|
init_dist();
|
|
106829
|
-
import * as
|
|
106830
|
-
import * as
|
|
106830
|
+
import * as fs44 from "fs";
|
|
106831
|
+
import * as path55 from "path";
|
|
106831
106832
|
import { fileURLToPath as fileURLToPath15 } from "url";
|
|
106832
106833
|
import { Command as Command6 } from "commander";
|
|
106833
106834
|
|
|
@@ -107317,8 +107318,8 @@ function deriveWebUrl(apiBaseUrl) {
|
|
|
107317
107318
|
}
|
|
107318
107319
|
var TSO_UMI_ROUTE_PREFIX = "/v3umijs/tso";
|
|
107319
107320
|
function buildTsoPageWebUrl(webUrl, tsoSubRoute, extraQuery) {
|
|
107320
|
-
const
|
|
107321
|
-
const umiPath = `${TSO_UMI_ROUTE_PREFIX}/${
|
|
107321
|
+
const path56 = tsoSubRoute.replace(/^\/+/, "");
|
|
107322
|
+
const umiPath = `${TSO_UMI_ROUTE_PREFIX}/${path56}`;
|
|
107322
107323
|
const q = new URLSearchParams({ tso: umiPath });
|
|
107323
107324
|
if (extraQuery) {
|
|
107324
107325
|
for (const [key, value] of Object.entries(extraQuery)) {
|
|
@@ -107326,7 +107327,7 @@ function buildTsoPageWebUrl(webUrl, tsoSubRoute, extraQuery) {
|
|
|
107326
107327
|
if (v) q.set(key, v);
|
|
107327
107328
|
}
|
|
107328
107329
|
}
|
|
107329
|
-
return `${webUrl.replace(/\/+$/, "")}/v3/foreign_trade/tso/${
|
|
107330
|
+
return `${webUrl.replace(/\/+$/, "")}/v3/foreign_trade/tso/${path56}?${q.toString()}`;
|
|
107330
107331
|
}
|
|
107331
107332
|
function cmdConfigShow() {
|
|
107332
107333
|
const shared = readSharedConfig();
|
|
@@ -113865,6 +113866,78 @@ init_shared();
|
|
|
113865
113866
|
// src/commands/ad/campaign.ts
|
|
113866
113867
|
init_auth();
|
|
113867
113868
|
init_cli_json_snapshot();
|
|
113869
|
+
|
|
113870
|
+
// src/commands/ad/digest-campaign-reuse.ts
|
|
113871
|
+
import fs9 from "fs";
|
|
113872
|
+
import path14 from "path";
|
|
113873
|
+
var MAX_DEPTH = 4;
|
|
113874
|
+
var MAX_FILES = 20;
|
|
113875
|
+
function normalizeAccountId(id) {
|
|
113876
|
+
return id.replace(/[-\s]/g, "");
|
|
113877
|
+
}
|
|
113878
|
+
function listDigestFiles(dir, depth, out) {
|
|
113879
|
+
if (depth > MAX_DEPTH || out.length >= MAX_FILES) return;
|
|
113880
|
+
let entries;
|
|
113881
|
+
try {
|
|
113882
|
+
entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
113883
|
+
} catch {
|
|
113884
|
+
return;
|
|
113885
|
+
}
|
|
113886
|
+
for (const entry of entries) {
|
|
113887
|
+
if (out.length >= MAX_FILES) return;
|
|
113888
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
113889
|
+
const full = path14.join(dir, entry.name);
|
|
113890
|
+
if (entry.isDirectory()) {
|
|
113891
|
+
listDigestFiles(full, depth + 1, out);
|
|
113892
|
+
continue;
|
|
113893
|
+
}
|
|
113894
|
+
if (entry.isFile() && /^accounts-digest-.+\.json$/i.test(entry.name)) {
|
|
113895
|
+
out.push(full);
|
|
113896
|
+
}
|
|
113897
|
+
}
|
|
113898
|
+
}
|
|
113899
|
+
function readHit(file, wantedId) {
|
|
113900
|
+
let parsed;
|
|
113901
|
+
try {
|
|
113902
|
+
parsed = JSON.parse(fs9.readFileSync(file, "utf8"));
|
|
113903
|
+
} catch {
|
|
113904
|
+
return null;
|
|
113905
|
+
}
|
|
113906
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
113907
|
+
const items3 = parsed.data?.items;
|
|
113908
|
+
if (!Array.isArray(items3)) return null;
|
|
113909
|
+
for (const item of items3) {
|
|
113910
|
+
if (!item || typeof item !== "object") continue;
|
|
113911
|
+
const row = item;
|
|
113912
|
+
const id = normalizeAccountId(String(row.mediaCustomerId ?? ""));
|
|
113913
|
+
if (!id || id !== wantedId) continue;
|
|
113914
|
+
if (row.campaignTypesStatus !== "ok") continue;
|
|
113915
|
+
const campaignTypes = Array.isArray(row.campaignTypes) ? row.campaignTypes.map(String) : [];
|
|
113916
|
+
const channelTypeV2 = Array.isArray(row.channelTypeV2) ? row.channelTypeV2.map(String) : campaignTypes;
|
|
113917
|
+
return {
|
|
113918
|
+
mediaCustomerId: id,
|
|
113919
|
+
campaignTypes,
|
|
113920
|
+
channelTypeV2,
|
|
113921
|
+
hasDisplay: row.hasDisplay === true,
|
|
113922
|
+
hasPmax: row.hasPmax === true,
|
|
113923
|
+
sourceFile: file
|
|
113924
|
+
};
|
|
113925
|
+
}
|
|
113926
|
+
return null;
|
|
113927
|
+
}
|
|
113928
|
+
function findDigestCampaignTypes(cwd, accountId) {
|
|
113929
|
+
const wanted = normalizeAccountId(accountId);
|
|
113930
|
+
if (!wanted) return null;
|
|
113931
|
+
const files = [];
|
|
113932
|
+
listDigestFiles(cwd, 0, files);
|
|
113933
|
+
for (const file of files) {
|
|
113934
|
+
const hit = readHit(file, wanted);
|
|
113935
|
+
if (hit) return hit;
|
|
113936
|
+
}
|
|
113937
|
+
return null;
|
|
113938
|
+
}
|
|
113939
|
+
|
|
113940
|
+
// src/commands/ad/campaign.ts
|
|
113868
113941
|
init_strip_legacy_google_fields();
|
|
113869
113942
|
init_cli_table();
|
|
113870
113943
|
|
|
@@ -115280,7 +115353,7 @@ function cloneKeywordBlockShell(block) {
|
|
|
115280
115353
|
delete shell["matchTypeV2"];
|
|
115281
115354
|
return shell;
|
|
115282
115355
|
}
|
|
115283
|
-
function splitKeywordsForBatchJobBlockIfMixed(block,
|
|
115356
|
+
function splitKeywordsForBatchJobBlockIfMixed(block, path56, warnings) {
|
|
115284
115357
|
const declaredUi = matchTypeV2ToUi(readBlockMatchTypeRaw(block));
|
|
115285
115358
|
const entries = collectKeywordEntriesFromBlock(block);
|
|
115286
115359
|
if (entries.length === 0) return [block];
|
|
@@ -115299,7 +115372,7 @@ function splitKeywordsForBatchJobBlockIfMixed(block, path55, warnings) {
|
|
|
115299
115372
|
(ui) => matchTypeUiToV2(ui)
|
|
115300
115373
|
);
|
|
115301
115374
|
warnings.push(
|
|
115302
|
-
`${
|
|
115375
|
+
`${path56} \u542B\u591A\u79CD\u5339\u914D\u7C7B\u578B\uFF0C\u5DF2\u81EA\u52A8\u62C6\u5206\u4E3A ${groups.size} \u4E2A KeywordsForBatchJob \u5757\uFF08${labels.join("\u3001")}\uFF09`
|
|
115303
115376
|
);
|
|
115304
115377
|
const shell = cloneKeywordBlockShell(block);
|
|
115305
115378
|
const splitBlocks = [];
|
|
@@ -115319,16 +115392,16 @@ function splitKeywordsForBatchJobBlockIfMixed(block, path55, warnings) {
|
|
|
115319
115392
|
}
|
|
115320
115393
|
return splitBlocks;
|
|
115321
115394
|
}
|
|
115322
|
-
function validateKeywordCore(core,
|
|
115395
|
+
function validateKeywordCore(core, path56, errors, lengthViolations) {
|
|
115323
115396
|
const trimmed = core.trim();
|
|
115324
115397
|
if (!trimmed) {
|
|
115325
|
-
errors.push(`${
|
|
115398
|
+
errors.push(`${path56} \u5173\u952E\u8BCD\u8BCD\u5E72\u4E0D\u80FD\u4E3A\u7A7A`);
|
|
115326
115399
|
return false;
|
|
115327
115400
|
}
|
|
115328
115401
|
if (trimmed.length > GOOGLE_KEYWORD_MAX_CORE_LENGTH) {
|
|
115329
115402
|
if (lengthViolations) {
|
|
115330
115403
|
pushLengthViolation(lengthViolations, {
|
|
115331
|
-
path:
|
|
115404
|
+
path: path56,
|
|
115332
115405
|
field: "KeywordText",
|
|
115333
115406
|
kind: "keyword_core",
|
|
115334
115407
|
limit: GOOGLE_KEYWORD_MAX_CORE_LENGTH,
|
|
@@ -115338,13 +115411,13 @@ function validateKeywordCore(core, path55, errors, lengthViolations) {
|
|
|
115338
115411
|
});
|
|
115339
115412
|
}
|
|
115340
115413
|
errors.push(
|
|
115341
|
-
`${
|
|
115414
|
+
`${path56} \u5173\u952E\u8BCD\u8BCD\u5E72\u8D85\u8FC7 ${GOOGLE_KEYWORD_MAX_CORE_LENGTH} \u5B57\u7B26\uFF08\u5F53\u524D ${trimmed.length}\uFF09\uFF1A"${trimmed}"`
|
|
115342
115415
|
);
|
|
115343
115416
|
return false;
|
|
115344
115417
|
}
|
|
115345
115418
|
if (!VALID_CORE_REGEX.test(trimmed)) {
|
|
115346
115419
|
errors.push(
|
|
115347
|
-
`${
|
|
115420
|
+
`${path56} \u542B Google \u4E0D\u5141\u8BB8\u7684\u5B57\u7B26\uFF08\u8BCD\u5E72\u4EC5\u5141\u8BB8\u5B57\u6BCD/\u6570\u5B57/\u7A7A\u683C/\u8FDE\u5B57\u7B26/\u53E5\u70B9\uFF09\uFF1A"${trimmed.slice(0, 40)}${trimmed.length > 40 ? "\u2026" : ""}"`
|
|
115348
115421
|
);
|
|
115349
115422
|
return false;
|
|
115350
115423
|
}
|
|
@@ -115401,10 +115474,10 @@ function canonicalizeKeywordBatchBlock(block, resolvedMatchV2, normalizedTexts,
|
|
|
115401
115474
|
}
|
|
115402
115475
|
}
|
|
115403
115476
|
}
|
|
115404
|
-
function pushKeywordAutoFixWarning(warnings,
|
|
115477
|
+
function pushKeywordAutoFixWarning(warnings, path56, fieldLabel, trimmedRaw, formatted, declaredUi, beforeUi, matchType, inferredMatchType) {
|
|
115405
115478
|
if (inferredMatchType) {
|
|
115406
115479
|
warnings.push(
|
|
115407
|
-
`${
|
|
115480
|
+
`${path56}.${fieldLabel} \u672A\u6307\u5B9A MatchTypeV2\uFF0C\u5DF2\u6309\u8BCD\u9762\u63A8\u65AD\u4E3A ${matchTypeUiToV2(matchType)}`
|
|
115408
115481
|
);
|
|
115409
115482
|
return false;
|
|
115410
115483
|
}
|
|
@@ -115413,16 +115486,16 @@ function pushKeywordAutoFixWarning(warnings, path55, fieldLabel, trimmedRaw, for
|
|
|
115413
115486
|
}
|
|
115414
115487
|
if (declaredUi && beforeUi !== declaredUi) {
|
|
115415
115488
|
warnings.push(
|
|
115416
|
-
`${
|
|
115489
|
+
`${path56}.${fieldLabel} MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u4E0E\u8BCD\u9762\u4E0D\u4E00\u81F4\uFF0C\u5DF2\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`
|
|
115417
115490
|
);
|
|
115418
115491
|
return false;
|
|
115419
115492
|
}
|
|
115420
115493
|
if (formatted !== trimmedRaw) {
|
|
115421
|
-
warnings.push(`${
|
|
115494
|
+
warnings.push(`${path56}.${fieldLabel} \u5DF2\u81EA\u52A8\u4FEE\u590D\u8BCD\u9762\uFF1A${trimmedRaw} \u2192 ${formatted}`);
|
|
115422
115495
|
}
|
|
115423
115496
|
return false;
|
|
115424
115497
|
}
|
|
115425
|
-
function normalizeKeywordTextList(texts, matchTypeRaw,
|
|
115498
|
+
function normalizeKeywordTextList(texts, matchTypeRaw, path56, fieldLabel, errors, warnings, lengthViolations) {
|
|
115426
115499
|
const declaredUi = matchTypeV2ToUi(matchTypeRaw);
|
|
115427
115500
|
const normalized = [];
|
|
115428
115501
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -115431,7 +115504,7 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path55, fieldLabel, error
|
|
|
115431
115504
|
for (let k = 0; k < texts.length; k++) {
|
|
115432
115505
|
const raw = texts[k];
|
|
115433
115506
|
if (typeof raw !== "string" || !raw.trim()) {
|
|
115434
|
-
errors.push(`${
|
|
115507
|
+
errors.push(`${path56}.${fieldLabel}[${k}] \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
115435
115508
|
continue;
|
|
115436
115509
|
}
|
|
115437
115510
|
const trimmedRaw = collapseDuplicateSpacesInKeywordText(raw.trim());
|
|
@@ -115442,7 +115515,7 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path55, fieldLabel, error
|
|
|
115442
115515
|
);
|
|
115443
115516
|
if (pushKeywordAutoFixWarning(
|
|
115444
115517
|
warnings,
|
|
115445
|
-
|
|
115518
|
+
path56,
|
|
115446
115519
|
fieldLabel,
|
|
115447
115520
|
trimmedRaw,
|
|
115448
115521
|
formatted,
|
|
@@ -115454,11 +115527,11 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path55, fieldLabel, error
|
|
|
115454
115527
|
bareWrapped++;
|
|
115455
115528
|
}
|
|
115456
115529
|
const core = unwrapKeywordDisplayTextForEdit(formatted);
|
|
115457
|
-
if (!validateKeywordCore(core, `${
|
|
115530
|
+
if (!validateKeywordCore(core, `${path56}.${fieldLabel}[${k}]`, errors, lengthViolations))
|
|
115458
115531
|
continue;
|
|
115459
115532
|
const dedupeKey = `${matchTypeUiToV2(matchType)}:${core.toLowerCase()}`;
|
|
115460
115533
|
if (seen.has(dedupeKey)) {
|
|
115461
|
-
warnings.push(`${
|
|
115534
|
+
warnings.push(`${path56}.${fieldLabel}[${k}] \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
|
|
115462
115535
|
continue;
|
|
115463
115536
|
}
|
|
115464
115537
|
seen.add(dedupeKey);
|
|
@@ -115467,17 +115540,17 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path55, fieldLabel, error
|
|
|
115467
115540
|
}
|
|
115468
115541
|
if (bareWrapped > 0 && declaredUi) {
|
|
115469
115542
|
warnings.push(
|
|
115470
|
-
`${
|
|
115543
|
+
`${path56}.${fieldLabel}\uFF1A${bareWrapped} \u4E2A\u88F8\u8BCD\u5DF2\u6309 MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u81EA\u52A8\u4FEE\u590D\uFF08\u8865\u5168${declaredUi === "Exact" ? " [ ]" : "\u5F15\u53F7"}\uFF0C\u9884\u671F\u884C\u4E3A\uFF09`
|
|
115471
115544
|
);
|
|
115472
115545
|
}
|
|
115473
115546
|
return { normalized, resolvedUi };
|
|
115474
115547
|
}
|
|
115475
|
-
function normalizeKeywordsForBatchJobBlock(block,
|
|
115548
|
+
function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, lengthViolations) {
|
|
115476
115549
|
const matchTypeRaw = readBlockMatchTypeRaw(block);
|
|
115477
115550
|
const declaredUi = matchTypeV2ToUi(matchTypeRaw);
|
|
115478
115551
|
if (matchTypeRaw !== void 0 && declaredUi === null) {
|
|
115479
115552
|
errors.push(
|
|
115480
|
-
`${
|
|
115553
|
+
`${path56}.MatchTypeV2 \u65E0\u6548\uFF08${String(matchTypeRaw)}\uFF09\uFF0C\u5408\u6CD5\u503C\uFF1ABROAD | PHRASE | EXACT`
|
|
115481
115554
|
);
|
|
115482
115555
|
return;
|
|
115483
115556
|
}
|
|
@@ -115492,7 +115565,7 @@ function normalizeKeywordsForBatchJobBlock(block, path55, errors, warnings, leng
|
|
|
115492
115565
|
const result = normalizeKeywordTextList(
|
|
115493
115566
|
texts,
|
|
115494
115567
|
matchTypeRaw,
|
|
115495
|
-
|
|
115568
|
+
path56,
|
|
115496
115569
|
"KeywordText",
|
|
115497
115570
|
errors,
|
|
115498
115571
|
warnings,
|
|
@@ -115501,7 +115574,7 @@ function normalizeKeywordsForBatchJobBlock(block, path55, errors, warnings, leng
|
|
|
115501
115574
|
normalizedTexts = result.normalized;
|
|
115502
115575
|
if (result.resolvedUi) resolvedUi = result.resolvedUi;
|
|
115503
115576
|
if (normalizedTexts.length === 0 && texts.length > 0) {
|
|
115504
|
-
errors.push(`${
|
|
115577
|
+
errors.push(`${path56}.KeywordText \u7ECF\u6821\u9A8C\u540E\u65E0\u6709\u6548\u5173\u952E\u8BCD\uFF0C\u8BF7\u4FEE\u6B63\u8BCD\u9762\u6216 MatchTypeV2`);
|
|
115505
115578
|
}
|
|
115506
115579
|
}
|
|
115507
115580
|
if (hasItems && items3) {
|
|
@@ -115509,12 +115582,12 @@ function normalizeKeywordsForBatchJobBlock(block, path55, errors, warnings, leng
|
|
|
115509
115582
|
for (let k = 0; k < items3.length; k++) {
|
|
115510
115583
|
const item = items3[k];
|
|
115511
115584
|
if (!item || typeof item !== "object") {
|
|
115512
|
-
errors.push(`${
|
|
115585
|
+
errors.push(`${path56}.Items[${k}] \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
115513
115586
|
continue;
|
|
115514
115587
|
}
|
|
115515
115588
|
const raw = readItemText(item);
|
|
115516
115589
|
if (raw === null || !raw.trim()) {
|
|
115517
|
-
errors.push(`${
|
|
115590
|
+
errors.push(`${path56}.Items[${k}].Text \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
115518
115591
|
continue;
|
|
115519
115592
|
}
|
|
115520
115593
|
const trimmedRaw = collapseDuplicateSpacesInKeywordText(raw.trim());
|
|
@@ -115525,7 +115598,7 @@ function normalizeKeywordsForBatchJobBlock(block, path55, errors, warnings, leng
|
|
|
115525
115598
|
);
|
|
115526
115599
|
if (pushKeywordAutoFixWarning(
|
|
115527
115600
|
warnings,
|
|
115528
|
-
|
|
115601
|
+
path56,
|
|
115529
115602
|
`Items[${k}].Text`,
|
|
115530
115603
|
trimmedRaw,
|
|
115531
115604
|
formatted,
|
|
@@ -115534,14 +115607,14 @@ function normalizeKeywordsForBatchJobBlock(block, path55, errors, warnings, leng
|
|
|
115534
115607
|
matchType,
|
|
115535
115608
|
inferredMatchType
|
|
115536
115609
|
)) {
|
|
115537
|
-
warnings.push(`${
|
|
115610
|
+
warnings.push(`${path56}.Items[${k}].Text \u5DF2\u6309\u5757\u7EA7\u5339\u914D\u7C7B\u578B\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`);
|
|
115538
115611
|
}
|
|
115539
115612
|
const core = unwrapKeywordDisplayTextForEdit(formatted);
|
|
115540
|
-
if (!validateKeywordCore(core, `${
|
|
115613
|
+
if (!validateKeywordCore(core, `${path56}.Items[${k}].Text`, errors, lengthViolations))
|
|
115541
115614
|
continue;
|
|
115542
115615
|
const dedupeKey = `${matchTypeUiToV2(matchType)}:${core.toLowerCase()}`;
|
|
115543
115616
|
if (seen.has(dedupeKey)) {
|
|
115544
|
-
warnings.push(`${
|
|
115617
|
+
warnings.push(`${path56}.Items[${k}].Text \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
|
|
115545
115618
|
continue;
|
|
115546
115619
|
}
|
|
115547
115620
|
seen.add(dedupeKey);
|
|
@@ -115687,16 +115760,16 @@ function warnIfNegativeKeywordsInPositiveKeywords(campaign, warnings) {
|
|
|
115687
115760
|
const raw = texts[ki];
|
|
115688
115761
|
if (typeof raw !== "string" || !raw.trim()) continue;
|
|
115689
115762
|
const core = normalizeKeywordCoreForNegativeCheck(raw);
|
|
115690
|
-
const
|
|
115763
|
+
const path56 = `campaign.AdGroupsForBatchJob[${gi}].KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
|
|
115691
115764
|
if (plannedNegCores.has(core)) {
|
|
115692
115765
|
warnings.push(
|
|
115693
|
-
`${
|
|
115766
|
+
`${path56} \u8BCD\u9762\u300C${raw}\u300D\u5DF2\u51FA\u73B0\u5728 campaign.NegativeKeywordsForBatchJob\uFF0C\u4E0D\u5E94\u91CD\u590D\u5199\u5165\u6B63\u5411 KeywordsForBatchJob\uFF1B\u5426\u8BCD\u53EA\u653E NegativeKeywordsForBatchJob`
|
|
115694
115767
|
);
|
|
115695
115768
|
continue;
|
|
115696
115769
|
}
|
|
115697
115770
|
if (looksLikeStandaloneNegativeKeyword(core)) {
|
|
115698
115771
|
warnings.push(
|
|
115699
|
-
`${
|
|
115772
|
+
`${path56} \u8BCD\u9762\u300C${raw}\u300D\u7591\u4F3C\u5426\u5B9A\u5173\u952E\u8BCD\uFF08\u5E38\u89C1\u5426\u8BCD\u8BCD\u6839\uFF09\uFF0C\u5E94\u5199\u5165 campaign.NegativeKeywordsForBatchJob\uFF08MatchTypeV2: BROAD\uFF09\uFF0C\u52FF\u653E\u5165 KeywordsForBatchJob`
|
|
115700
115773
|
);
|
|
115701
115774
|
}
|
|
115702
115775
|
}
|
|
@@ -116632,8 +116705,41 @@ function parseCampaignTimeMs(v) {
|
|
|
116632
116705
|
const t = new Date(v).getTime();
|
|
116633
116706
|
return Number.isFinite(t) ? t : null;
|
|
116634
116707
|
}
|
|
116708
|
+
async function emitReusedDigestCampaignTypes(opts, hit) {
|
|
116709
|
+
process.stderr.write(
|
|
116710
|
+
`\u5DF2\u6709 accounts-digest \u7CFB\u5217\u7C7B\u578B\uFF08${hit.sourceFile}\uFF09\uFF0C\u672A\u8BF7\u6C42\u5E7F\u544A\u7CFB\u5217\u5217\u8868\u3002channelTypeV2 \u4E0E campaignTypes \u76F8\u540C\u3002\u8981\u7CFB\u5217\u540D\u79F0\u3001\u72B6\u6001\u3001\u6D88\u8017\u8BF7\u52A0 --live\u3002
|
|
116711
|
+
`
|
|
116712
|
+
);
|
|
116713
|
+
const payload = {
|
|
116714
|
+
ok: true,
|
|
116715
|
+
source: "accounts-digest",
|
|
116716
|
+
mediaCustomerId: hit.mediaCustomerId,
|
|
116717
|
+
campaignTypes: hit.campaignTypes,
|
|
116718
|
+
channelTypeV2: hit.channelTypeV2,
|
|
116719
|
+
hasDisplay: hit.hasDisplay,
|
|
116720
|
+
hasPmax: hit.hasPmax,
|
|
116721
|
+
note: "\u7CFB\u5217\u7C7B\u578B\u6765\u81EA\u5DE5\u4F5C\u76EE\u5F55\u91CC\u5DF2\u6709\u7684 accounts-digest\uFF0C\u4E0D\u662F\u5E7F\u544A\u7CFB\u5217\u5217\u8868\u3002"
|
|
116722
|
+
};
|
|
116723
|
+
if (await emitCliJsonOrSnapshot(opts, {
|
|
116724
|
+
section: `ad-campaigns-${opts.account}`,
|
|
116725
|
+
commandLabel: "ad campaigns",
|
|
116726
|
+
commandHint: opts.account,
|
|
116727
|
+
payload,
|
|
116728
|
+
idSuffix: opts.account
|
|
116729
|
+
})) {
|
|
116730
|
+
return;
|
|
116731
|
+
}
|
|
116732
|
+
console.log(JSON.stringify(payload));
|
|
116733
|
+
}
|
|
116635
116734
|
async function runAdCampaigns(opts) {
|
|
116636
116735
|
opts = withResolvedAdAccount(opts);
|
|
116736
|
+
if (!opts.live) {
|
|
116737
|
+
const hit = findDigestCampaignTypes(process.cwd(), opts.account);
|
|
116738
|
+
if (hit) {
|
|
116739
|
+
await emitReusedDigestCampaignTypes(opts, hit);
|
|
116740
|
+
return;
|
|
116741
|
+
}
|
|
116742
|
+
}
|
|
116637
116743
|
const config = loadConfig(opts.token);
|
|
116638
116744
|
const googleApiUrl = requireGoogleApi(config);
|
|
116639
116745
|
const url = campaignListUrl(googleApiUrl, opts.account, opts.startDate, opts.endDate, opts.fresh);
|
|
@@ -119414,8 +119520,8 @@ init_cli_table();
|
|
|
119414
119520
|
init_auth();
|
|
119415
119521
|
init_cli_json_snapshot();
|
|
119416
119522
|
init_shared();
|
|
119417
|
-
import
|
|
119418
|
-
import
|
|
119523
|
+
import fs10 from "fs";
|
|
119524
|
+
import path15 from "path";
|
|
119419
119525
|
|
|
119420
119526
|
// src/commands/ad/campaign-extension-remediate.ts
|
|
119421
119527
|
function shellArg(value) {
|
|
@@ -119559,7 +119665,7 @@ function buildBatchOperationSlots(cfg) {
|
|
|
119559
119665
|
const campaign = asRecord3(cfg.campaign) ?? {};
|
|
119560
119666
|
const names = Array.isArray(cfg.locations) ? cfg.locations : [];
|
|
119561
119667
|
const slots = [];
|
|
119562
|
-
const push = (kind,
|
|
119668
|
+
const push = (kind, path56, label2) => slots.push({ index: slots.length, kind, path: path56, label: label2 });
|
|
119563
119669
|
push("campaign_budget", "campaign.Budget", "\u7CFB\u5217\u9884\u7B97");
|
|
119564
119670
|
push("campaign", "campaign.Name", `\u7CFB\u5217\u300C${pickText(campaign, "Name", "name") || "\u2014"}\u300D`);
|
|
119565
119671
|
pickArray(campaign, "targetedLocations", "TargetedLocations").forEach((loc, i) => {
|
|
@@ -120042,13 +120148,13 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120042
120148
|
for (let ki = 0; ki < texts.length; ki++) {
|
|
120043
120149
|
const t = texts[ki];
|
|
120044
120150
|
if (typeof t !== "string" || !t.trim()) continue;
|
|
120045
|
-
const
|
|
120151
|
+
const path56 = `${groupPath}.KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
|
|
120046
120152
|
const key = keywordKey(t, matchTypeV2);
|
|
120047
120153
|
const plannedContent = `\u8BCD\u9762: ${t} | \u5339\u914D: ${matchTypeV2}`;
|
|
120048
120154
|
if (groupAbsent) {
|
|
120049
120155
|
pushItem(items3, {
|
|
120050
120156
|
layer: "keyword",
|
|
120051
|
-
path:
|
|
120157
|
+
path: path56,
|
|
120052
120158
|
adGroupName: groupName,
|
|
120053
120159
|
plannedContent,
|
|
120054
120160
|
status: "skipped",
|
|
@@ -120060,7 +120166,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120060
120166
|
if (!liveKwKeys.has(key)) {
|
|
120061
120167
|
pushItem(items3, {
|
|
120062
120168
|
layer: "keyword",
|
|
120063
|
-
path:
|
|
120169
|
+
path: path56,
|
|
120064
120170
|
adGroupName: groupName,
|
|
120065
120171
|
plannedContent,
|
|
120066
120172
|
status: "missing",
|
|
@@ -120070,7 +120176,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120070
120176
|
} else {
|
|
120071
120177
|
pushItem(items3, {
|
|
120072
120178
|
layer: "keyword",
|
|
120073
|
-
path:
|
|
120179
|
+
path: path56,
|
|
120074
120180
|
adGroupName: groupName,
|
|
120075
120181
|
plannedContent,
|
|
120076
120182
|
status: "ok",
|
|
@@ -120090,7 +120196,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120090
120196
|
for (let ai = 0; ai < ads.length; ai++) {
|
|
120091
120197
|
const ad = asRecord4(ads[ai]);
|
|
120092
120198
|
if (!ad) continue;
|
|
120093
|
-
const
|
|
120199
|
+
const path56 = `${groupPath}.AdsForBatchJob[${ai}]`;
|
|
120094
120200
|
const primary = pickString2(ad["headlinePart1"], ad["AdTitle"]);
|
|
120095
120201
|
const finalUrl = pickString2(ad["Finalurl"], ad["DestinationUrl"], ad["finalUrl"]);
|
|
120096
120202
|
const rsaAssets = listPlannedRsaAssets(ad, groupPath, ai, groupName);
|
|
@@ -120099,7 +120205,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120099
120205
|
if (groupAbsent) {
|
|
120100
120206
|
pushItem(items3, {
|
|
120101
120207
|
layer: "ad",
|
|
120102
|
-
path:
|
|
120208
|
+
path: path56,
|
|
120103
120209
|
adGroupName: groupName,
|
|
120104
120210
|
adLabel,
|
|
120105
120211
|
plannedContent: primary ? `RSA \u9996\u6807\u9898: ${primary}${finalUrl ? ` | \u843D\u5730\u9875: ${finalUrl}` : ""}` : `AdsForBatchJob[${ai}]\uFF08\u7F3A\u5C11 headlinePart1\uFF09`,
|
|
@@ -120128,7 +120234,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120128
120234
|
if (!primary) {
|
|
120129
120235
|
pushItem(items3, {
|
|
120130
120236
|
layer: "ad",
|
|
120131
|
-
path:
|
|
120237
|
+
path: path56,
|
|
120132
120238
|
adGroupName: groupName,
|
|
120133
120239
|
adLabel,
|
|
120134
120240
|
plannedContent: `AdsForBatchJob[${ai}]\uFF08\u7F3A\u5C11 headlinePart1\uFF0C\u65E0\u6CD5\u6BD4\u5BF9\u6574\u6761 RSA\uFF09`,
|
|
@@ -120156,7 +120262,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120156
120262
|
const rsaFound = matchedLive != null && liveAdHasHeadline(matchedLive, primary);
|
|
120157
120263
|
pushItem(items3, {
|
|
120158
120264
|
layer: "ad",
|
|
120159
|
-
path:
|
|
120265
|
+
path: path56,
|
|
120160
120266
|
adGroupName: groupName,
|
|
120161
120267
|
adLabel,
|
|
120162
120268
|
plannedContent: `RSA \u9996\u6807\u9898: ${primary}${finalUrl ? ` | \u843D\u5730\u9875: ${finalUrl}` : ""}`,
|
|
@@ -120224,11 +120330,11 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120224
120330
|
for (let ei = 0; ei < extBlocks.length; ei++) {
|
|
120225
120331
|
const ext = asRecord4(extBlocks[ei]);
|
|
120226
120332
|
const plannedContent = formatExtensionPlanned(ext);
|
|
120227
|
-
const
|
|
120333
|
+
const path56 = `campaign.ExtensionsForBatchJob[${ei}]`;
|
|
120228
120334
|
if (campaignMissing) {
|
|
120229
120335
|
pushItem(items3, {
|
|
120230
120336
|
layer: "extension",
|
|
120231
|
-
path:
|
|
120337
|
+
path: path56,
|
|
120232
120338
|
plannedContent,
|
|
120233
120339
|
status: "skipped",
|
|
120234
120340
|
liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u9644\u52A0\u4FE1\u606F\u6BD4\u5BF9",
|
|
@@ -120240,7 +120346,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120240
120346
|
const remediateCommand = !found && ext && accountId && campaignId ? buildExtensionRemediateCommandLine({ accountId, campaignId, ext }) ?? void 0 : void 0;
|
|
120241
120347
|
pushItem(items3, {
|
|
120242
120348
|
layer: "extension",
|
|
120243
|
-
path:
|
|
120349
|
+
path: path56,
|
|
120244
120350
|
plannedContent,
|
|
120245
120351
|
status: found ? "ok" : "missing",
|
|
120246
120352
|
liveNote: `\u7CFB\u5217\u7EA7\u9644\u52A0\u4FE1\u606F\u8D26\u6237\u5185 ${liveExt}/${plannedExt} \u6761`,
|
|
@@ -120267,11 +120373,11 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120267
120373
|
if (!id) continue;
|
|
120268
120374
|
const displayName = locationNames[li] || pickString2(loc["locationName"], loc["name"], loc["countryOrRegion"]) || "";
|
|
120269
120375
|
const plannedContent = `locationId: ${id}${displayName ? ` | \u540D\u79F0: ${displayName}` : ""}`;
|
|
120270
|
-
const
|
|
120376
|
+
const path56 = `campaign.targetedLocations[${li}]`;
|
|
120271
120377
|
if (campaignMissing) {
|
|
120272
120378
|
pushItem(items3, {
|
|
120273
120379
|
layer: "location",
|
|
120274
|
-
path:
|
|
120380
|
+
path: path56,
|
|
120275
120381
|
plannedContent,
|
|
120276
120382
|
status: "skipped",
|
|
120277
120383
|
liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u5730\u57DF\u6BD4\u5BF9",
|
|
@@ -120283,7 +120389,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120283
120389
|
const remediateCommand = !found && accountId && campaignId ? buildGeoRemediateCommandLine({ accountId, campaignId, locationId: id }) : void 0;
|
|
120284
120390
|
pushItem(items3, {
|
|
120285
120391
|
layer: "location",
|
|
120286
|
-
path:
|
|
120392
|
+
path: path56,
|
|
120287
120393
|
plannedContent,
|
|
120288
120394
|
status: found ? "ok" : "missing",
|
|
120289
120395
|
liveNote: `\u7CFB\u5217\u5DF2\u5B9A\u5411 ${liveLocIds.size}/${plannedLocCount} \u4E2A\u5730\u57DF`,
|
|
@@ -120303,12 +120409,12 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120303
120409
|
const loc = asRecord4(plannedExcl[li]);
|
|
120304
120410
|
const id = loc ? pickString2(loc["id"], loc["Id"]) : "";
|
|
120305
120411
|
if (!id) continue;
|
|
120306
|
-
const
|
|
120412
|
+
const path56 = `campaign.excludedLocations[${li}]`;
|
|
120307
120413
|
const plannedContent = `\u6392\u9664 locationId: ${id}`;
|
|
120308
120414
|
if (campaignMissing) {
|
|
120309
120415
|
pushItem(items3, {
|
|
120310
120416
|
layer: "excluded_location",
|
|
120311
|
-
path:
|
|
120417
|
+
path: path56,
|
|
120312
120418
|
plannedContent,
|
|
120313
120419
|
status: "skipped",
|
|
120314
120420
|
liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u6392\u9664\u5730\u57DF\u6BD4\u5BF9",
|
|
@@ -120319,7 +120425,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
|
|
|
120319
120425
|
const found = liveExclIds.has(id);
|
|
120320
120426
|
pushItem(items3, {
|
|
120321
120427
|
layer: "excluded_location",
|
|
120322
|
-
path:
|
|
120428
|
+
path: path56,
|
|
120323
120429
|
plannedContent,
|
|
120324
120430
|
status: found ? "ok" : "missing",
|
|
120325
120431
|
liveNote: `\u7CFB\u5217\u5DF2\u6392\u9664 ${liveExclIds.size}/${plannedExclCount} \u4E2A\u5730\u57DF`,
|
|
@@ -120835,23 +120941,23 @@ function buildCampaignCreateStatusMarkdown(result) {
|
|
|
120835
120941
|
return lines.join("\n");
|
|
120836
120942
|
}
|
|
120837
120943
|
function resolveBatchDiffMdOutPath(opts) {
|
|
120838
|
-
if (opts.mdOut?.trim()) return
|
|
120944
|
+
if (opts.mdOut?.trim()) return path15.resolve(opts.mdOut.trim());
|
|
120839
120945
|
const fileName = `campaign-create-status-${opts.campaignId || "unknown"}.md`;
|
|
120840
120946
|
if (opts.jsonOut?.trim()) {
|
|
120841
120947
|
const jsonOut = opts.jsonOut.trim();
|
|
120842
|
-
const abs =
|
|
120948
|
+
const abs = path15.resolve(jsonOut);
|
|
120843
120949
|
const looksLikeFile = /\.json$/i.test(jsonOut);
|
|
120844
120950
|
if (looksLikeFile) {
|
|
120845
|
-
return
|
|
120951
|
+
return path15.join(path15.dirname(abs), fileName);
|
|
120846
120952
|
}
|
|
120847
|
-
return
|
|
120953
|
+
return path15.join(abs, fileName);
|
|
120848
120954
|
}
|
|
120849
|
-
return
|
|
120955
|
+
return path15.resolve(fileName);
|
|
120850
120956
|
}
|
|
120851
120957
|
function writeCampaignCreateStatusMarkdown(result, mdPath) {
|
|
120852
120958
|
const reportMarkdown = buildCampaignCreateStatusMarkdown(result);
|
|
120853
|
-
|
|
120854
|
-
|
|
120959
|
+
fs10.mkdirSync(path15.dirname(mdPath), { recursive: true });
|
|
120960
|
+
fs10.writeFileSync(mdPath, reportMarkdown, "utf8");
|
|
120855
120961
|
return { reportMarkdown, reportMarkdownFile: mdPath };
|
|
120856
120962
|
}
|
|
120857
120963
|
var USER_DELIVERY_MARKDOWN_BEGIN = "\u2500\u2500 BEGIN_USER_DELIVERY_MARKDOWN \uFF08\u5FC5\u987B\u539F\u6837\u7C98\u8D34\u5230\u5BF9\u7528\u6237\u7684\u4E0B\u4E00\u6761\u6D88\u606F\uFF1B\u7981\u6B62\u6458\u8981\u4EE3\u66FF\uFF1B\u4EA4\u4ED8\u4F18\u5148\u4E8E\u8865\u5EFA\uFF09\u2500\u2500";
|
|
@@ -121969,8 +122075,8 @@ function pmaxChannelTypesUrl(googleApiUrl) {
|
|
|
121969
122075
|
}
|
|
121970
122076
|
function pmaxCampaignUrl(googleApiUrl, accountId, campaignId) {
|
|
121971
122077
|
const base = googleApiUrl.replace(/\/$/, "");
|
|
121972
|
-
const
|
|
121973
|
-
return campaignId ? `${
|
|
122078
|
+
const path56 = `${base}/accounts/${accountId}/campaign/pmax`;
|
|
122079
|
+
return campaignId ? `${path56}/${campaignId}` : path56;
|
|
121974
122080
|
}
|
|
121975
122081
|
function pmaxBrandAssetsUrl(googleApiUrl, accountId, campaignId) {
|
|
121976
122082
|
return `${pmaxCampaignUrl(googleApiUrl, accountId, campaignId)}/brand-assets`;
|
|
@@ -121980,8 +122086,8 @@ function pmaxBrandGuidelinesEnableUrl(googleApiUrl, accountId, campaignId) {
|
|
|
121980
122086
|
}
|
|
121981
122087
|
function pmaxAssetGroupUrl(googleApiUrl, accountId, assetGroupId, suffix) {
|
|
121982
122088
|
const base = googleApiUrl.replace(/\/$/, "");
|
|
121983
|
-
const
|
|
121984
|
-
return suffix ? `${
|
|
122089
|
+
const path56 = `${base}/accounts/${accountId}/campaign/pmax/asset-group/${assetGroupId}`;
|
|
122090
|
+
return suffix ? `${path56}/${suffix.replace(/^\//, "")}` : path56;
|
|
121985
122091
|
}
|
|
121986
122092
|
function pmaxCampaignAssetGroupUrl(googleApiUrl, accountId, campaignId) {
|
|
121987
122093
|
const base = googleApiUrl.replace(/\/$/, "");
|
|
@@ -124732,8 +124838,8 @@ async function runAdPmaxImageConvert(opts) {
|
|
|
124732
124838
|
}
|
|
124733
124839
|
|
|
124734
124840
|
// src/commands/ad/pmax-brand-mgmt.ts
|
|
124735
|
-
function loadBrandConfig(
|
|
124736
|
-
const cfg = loadPmaxJsonFile(
|
|
124841
|
+
function loadBrandConfig(path56, accountId, campaignId) {
|
|
124842
|
+
const cfg = loadPmaxJsonFile(path56);
|
|
124737
124843
|
return {
|
|
124738
124844
|
...cfg,
|
|
124739
124845
|
account: String(cfg["account"] ?? accountId).trim(),
|
|
@@ -124976,6 +125082,10 @@ function register21(program2) {
|
|
|
124976
125082
|
"--fresh",
|
|
124977
125083
|
"\u8DF3\u8FC7\u7F51\u5173 60 \u79D2\u7F13\u5B58\uFF0C\u5F3A\u5236\u62C9\u53D6\u6700\u65B0\u6570\u636E\uFF08\u7F51\u5173 newest=true\uFF09\uFF1B\u521A\u521B\u5EFA/\u7F16\u8F91\u5B8C\u60F3\u7ACB\u523B\u770B\u5230\u7ED3\u679C\u65F6\u7528",
|
|
124978
125084
|
false
|
|
125085
|
+
).option(
|
|
125086
|
+
"--live",
|
|
125087
|
+
"\u5FFD\u7565\u5DE5\u4F5C\u76EE\u5F55\u91CC\u5DF2\u6709\u7684 accounts-digest \u7CFB\u5217\u7C7B\u578B\uFF0C\u5F3A\u5236\u8BF7\u6C42\u7CFB\u5217\u5217\u8868\uFF08\u8981\u7CFB\u5217\u540D\u79F0\u3001\u72B6\u6001\u3001\u6D88\u8017\u65F6\u7528\uFF1B\u5DE1\u68C0\u4E0D\u8981\u52A0\uFF09",
|
|
125088
|
+
false
|
|
124979
125089
|
).option("-t, --token <token>", "Auth Token").option(
|
|
124980
125090
|
"--json-out <path>",
|
|
124981
125091
|
"\u843D\u76D8\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\u8DEF\u5F84\uFF09\u5E76\u66F4\u65B0 cli-manifest[-<\u67E5\u8BE2id>].json\uFF1B\u76EE\u5F55\u6A21\u5F0F\u6587\u4EF6\u540D\u4E3A `<section>[-<\u67E5\u8BE2id>].json`\uFF1Bstdout \u4E00\u884C\u6458\u8981 JSON\uFF0C\u542B outlineFile\uFF08TS \u5F0F\u7C7B\u578B\u5728 `*.outline.txt`\uFF09",
|
|
@@ -124988,6 +125098,7 @@ function register21(program2) {
|
|
|
124988
125098
|
startDate: opts.start,
|
|
124989
125099
|
endDate: opts.end,
|
|
124990
125100
|
fresh: opts.fresh,
|
|
125101
|
+
live: opts.live,
|
|
124991
125102
|
jsonOut: opts.jsonOut,
|
|
124992
125103
|
verbose: opts.verbose
|
|
124993
125104
|
});
|
|
@@ -126393,9 +126504,9 @@ function metaAdContext(token) {
|
|
|
126393
126504
|
const config = loadConfig(token);
|
|
126394
126505
|
return { config, facebookApiUrl: requireFacebookApi(config) };
|
|
126395
126506
|
}
|
|
126396
|
-
function adsUrl(facebookApiUrl, account,
|
|
126507
|
+
function adsUrl(facebookApiUrl, account, path56) {
|
|
126397
126508
|
const base = metaAdsBaseUrl(facebookApiUrl, account);
|
|
126398
|
-
const p =
|
|
126509
|
+
const p = path56.startsWith("/") ? path56 : `/${path56}`;
|
|
126399
126510
|
return `${base}${p}`;
|
|
126400
126511
|
}
|
|
126401
126512
|
async function metaAdGet(url, config, verbose, action) {
|
|
@@ -127602,9 +127713,9 @@ async function runMetaAdForms(opts) {
|
|
|
127602
127713
|
if (opts.after) params.set("after", opts.after);
|
|
127603
127714
|
if (opts.before) params.set("before", opts.before);
|
|
127604
127715
|
const qs = params.toString();
|
|
127605
|
-
const
|
|
127716
|
+
const path56 = `/pages/${encodeURIComponent(opts.pageId)}/forms${qs ? `?${qs}` : ""}`;
|
|
127606
127717
|
const raw = await metaAdGet(
|
|
127607
|
-
adsUrl(facebookApiUrl, digits,
|
|
127718
|
+
adsUrl(facebookApiUrl, digits, path56),
|
|
127608
127719
|
config,
|
|
127609
127720
|
opts.verbose,
|
|
127610
127721
|
"\u5217\u8868\u5355\u5931\u8D25"
|
|
@@ -127699,8 +127810,8 @@ async function runMetaAdFormCreate(opts) {
|
|
|
127699
127810
|
|
|
127700
127811
|
// src/commands/meta-ad/plan-render.ts
|
|
127701
127812
|
init_xlsx_style_engine();
|
|
127702
|
-
import
|
|
127703
|
-
import
|
|
127813
|
+
import fs12 from "fs";
|
|
127814
|
+
import path17 from "path";
|
|
127704
127815
|
var PENDING = "[\u5F85\u8865]";
|
|
127705
127816
|
var SHEET_NAMES = ["\u65B9\u6848\u603B\u89C8", "1-\u5BA2\u6237\u753B\u50CF", "2-\u8D26\u6237\u7ED3\u6784", "3-\u8868\u5355\u8BE2\u76D8C1"];
|
|
127706
127817
|
var OPS = {
|
|
@@ -128081,17 +128192,17 @@ function writeMetaLeadPlanExcel(outPath, cfg) {
|
|
|
128081
128192
|
return writeOpsExcel(outPath, cfg);
|
|
128082
128193
|
}
|
|
128083
128194
|
function writeMetaLeadPlanMarkdown(outPath, cfg) {
|
|
128084
|
-
const abs =
|
|
128085
|
-
|
|
128086
|
-
|
|
128195
|
+
const abs = path17.resolve(outPath);
|
|
128196
|
+
fs12.mkdirSync(path17.dirname(abs), { recursive: true });
|
|
128197
|
+
fs12.writeFileSync(abs, renderMarkdown(cfg), "utf8");
|
|
128087
128198
|
return abs;
|
|
128088
128199
|
}
|
|
128089
128200
|
async function runMetaAdPlanRender(opts) {
|
|
128090
128201
|
const cfg = loadMetaLeadCreateConfig(opts.configFile);
|
|
128091
|
-
const configDir =
|
|
128092
|
-
const xlsxOut =
|
|
128093
|
-
const mdOut =
|
|
128094
|
-
opts.mdOut ||
|
|
128202
|
+
const configDir = path17.dirname(path17.resolve(opts.configFile));
|
|
128203
|
+
const xlsxOut = path17.resolve(opts.out || path17.join(configDir, "meta-lead-plan.xlsx"));
|
|
128204
|
+
const mdOut = path17.resolve(
|
|
128205
|
+
opts.mdOut || path17.join(path17.dirname(xlsxOut), `${path17.parse(xlsxOut).name}.md`)
|
|
128095
128206
|
);
|
|
128096
128207
|
const xlsxPath = writeMetaLeadPlanExcel(xlsxOut, cfg);
|
|
128097
128208
|
const mdPath = writeMetaLeadPlanMarkdown(mdOut, cfg);
|
|
@@ -129429,6 +129540,13 @@ async function runKeywordSuggest(opts) {
|
|
|
129429
129540
|
return !excludes.some((exc) => kw.includes(exc));
|
|
129430
129541
|
});
|
|
129431
129542
|
}
|
|
129543
|
+
const beforeVolumeFilter = items3.length;
|
|
129544
|
+
items3 = filterByMinMonthlySearch(items3, opts.minMonthlySearch);
|
|
129545
|
+
if (opts.minMonthlySearch != null && opts.minMonthlySearch > 0 && items3.length !== beforeVolumeFilter) {
|
|
129546
|
+
console.error(
|
|
129547
|
+
` [keyword] \u6708\u641C\u7D22\u91CF >= ${opts.minMonthlySearch}\uFF1A\u4FDD\u7559 ${items3.length} \u6761\uFF0C\u53BB\u6389 ${beforeVolumeFilter - items3.length} \u6761\uFF08\u7F3A\u641C\u7D22\u91CF\u89C6\u4E3A 0\uFF09`
|
|
129548
|
+
);
|
|
129549
|
+
}
|
|
129432
129550
|
if (accountId) {
|
|
129433
129551
|
try {
|
|
129434
129552
|
const accountNormSet = await fetchAccountPositiveKeywordNormSet(
|
|
@@ -129566,6 +129684,23 @@ function microsItemToBidAmounts(item) {
|
|
|
129566
129684
|
)
|
|
129567
129685
|
};
|
|
129568
129686
|
}
|
|
129687
|
+
function filterByMinMonthlySearch(items3, minMonthlySearch) {
|
|
129688
|
+
if (minMonthlySearch == null || !Number.isFinite(minMonthlySearch) || minMonthlySearch <= 0) {
|
|
129689
|
+
return items3;
|
|
129690
|
+
}
|
|
129691
|
+
return items3.filter((item) => {
|
|
129692
|
+
const volume = Number(item.montlySearch);
|
|
129693
|
+
return Number.isFinite(volume) && volume >= minMonthlySearch;
|
|
129694
|
+
});
|
|
129695
|
+
}
|
|
129696
|
+
function parseMinMonthlySearch(raw) {
|
|
129697
|
+
const value = Number(raw);
|
|
129698
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
129699
|
+
console.error("\n\u274C --min-monthly-search \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6570\u5B57\u3002\n");
|
|
129700
|
+
process.exit(1);
|
|
129701
|
+
}
|
|
129702
|
+
return value;
|
|
129703
|
+
}
|
|
129569
129704
|
function attachBaseCliOptions(cmd) {
|
|
129570
129705
|
attachJsonOutOption(cmd);
|
|
129571
129706
|
cmd.option("--verbose", "\u8F93\u51FA\u8BE6\u7EC6\u9519\u8BEF\u5806\u6808").option("--token <jwt>", "\u4E34\u65F6\u4F7F\u7528\u7684 JWT Token\uFF08\u8986\u76D6 ~/.siluzan/config.json\uFF09");
|
|
@@ -129584,7 +129719,10 @@ function register23(program2) {
|
|
|
129584
129719
|
).option(
|
|
129585
129720
|
"--geo <ids>",
|
|
129586
129721
|
"geoTargetConstant ID\uFF08\u5148 keyword geo-list\uFF1B\u4F8B 2840=\u7F8E\u56FD\uFF09\u3002\u591A\u4E2A ID \u4E3A\u6C47\u603B\u6307\u6807\uFF1B\u5206\u5E02\u573A\u987B\u591A\u6B21\u8C03\u7528\u3001\u6BCF\u6B21\u53EA\u4F20\u4E00\u4E2A"
|
|
129587
|
-
).option("--url <url>", "\u516C\u53F8/\u4EA7\u54C1\u7F51\u5740\uFF08\u586B\u5199\u540E\u89E6\u53D1\u7F51\u5740\u62D3\u8BCD\uFF1B\u4E0E --google-only \u4E92\u65A5\uFF09").option("--google-only", "\u4EC5 Google Keyword Planner\uFF0C\u4E0D\u53E0\u52A0\u7F51\u5740\u62D3\u8BCD").option("--include <words>", "\u7ED3\u679C\u5FC5\u987B\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").option("--exclude <words>", "\u7ED3\u679C\u4E0D\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").
|
|
129722
|
+
).option("--url <url>", "\u516C\u53F8/\u4EA7\u54C1\u7F51\u5740\uFF08\u586B\u5199\u540E\u89E6\u53D1\u7F51\u5740\u62D3\u8BCD\uFF1B\u4E0E --google-only \u4E92\u65A5\uFF09").option("--google-only", "\u4EC5 Google Keyword Planner\uFF0C\u4E0D\u53E0\u52A0\u7F51\u5740\u62D3\u8BCD").option("--include <words>", "\u7ED3\u679C\u5FC5\u987B\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").option("--exclude <words>", "\u7ED3\u679C\u4E0D\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").option(
|
|
129723
|
+
"--min-monthly-search <n>",
|
|
129724
|
+
"\u4E22\u6389\u6708\u641C\u7D22\u91CF\u4F4E\u4E8E\u8BE5\u503C\u7684\u8BCD\uFF1B\u7F3A\u641C\u7D22\u91CF\u89C6\u4E3A 0\u3002\u7528\u6237\u8981\u6709\u641C\u7D22\u70ED\u5EA6\u65F6\u7528 1"
|
|
129725
|
+
).action(async (opts) => {
|
|
129588
129726
|
await runKeywordSuggest({
|
|
129589
129727
|
token: opts.token,
|
|
129590
129728
|
account: opts.account,
|
|
@@ -129594,6 +129732,7 @@ function register23(program2) {
|
|
|
129594
129732
|
include: opts.include,
|
|
129595
129733
|
exclude: opts.exclude,
|
|
129596
129734
|
googleOnly: opts.googleOnly,
|
|
129735
|
+
minMonthlySearch: opts.minMonthlySearch == null ? void 0 : parseMinMonthlySearch(opts.minMonthlySearch),
|
|
129597
129736
|
jsonOut: opts.jsonOut,
|
|
129598
129737
|
verbose: opts.verbose
|
|
129599
129738
|
});
|
|
@@ -132151,8 +132290,8 @@ async function runOpenAccountYandex(opts) {
|
|
|
132151
132290
|
|
|
132152
132291
|
// src/commands/open-account/bing.ts
|
|
132153
132292
|
init_auth();
|
|
132154
|
-
import * as
|
|
132155
|
-
import * as
|
|
132293
|
+
import * as fs13 from "fs";
|
|
132294
|
+
import * as path18 from "path";
|
|
132156
132295
|
init_cli_json_snapshot();
|
|
132157
132296
|
|
|
132158
132297
|
// src/commands/open-account/bing-industry-dict.ts
|
|
@@ -132280,8 +132419,8 @@ async function fetchBingIndustryOptions(config, verbose) {
|
|
|
132280
132419
|
|
|
132281
132420
|
// src/commands/open-account/bing.ts
|
|
132282
132421
|
async function uploadAttachment(filePath, apiBaseUrl, config, verbose) {
|
|
132283
|
-
const fileName =
|
|
132284
|
-
const fileBuffer =
|
|
132422
|
+
const fileName = path18.basename(filePath);
|
|
132423
|
+
const fileBuffer = fs13.readFileSync(filePath);
|
|
132285
132424
|
const mimeType = guessContentType2(fileName);
|
|
132286
132425
|
const form = new FormData();
|
|
132287
132426
|
form.append("file", new Blob([fileBuffer], { type: mimeType }), fileName);
|
|
@@ -132309,7 +132448,7 @@ async function uploadAttachment(filePath, apiBaseUrl, config, verbose) {
|
|
|
132309
132448
|
return { id: data.id, fileName, storageProvider: data.storageProvider ?? "StorageAccount" };
|
|
132310
132449
|
}
|
|
132311
132450
|
function guessContentType2(fileName) {
|
|
132312
|
-
const ext =
|
|
132451
|
+
const ext = path18.extname(fileName).toLowerCase();
|
|
132313
132452
|
const map = {
|
|
132314
132453
|
".jpg": "image/jpeg",
|
|
132315
132454
|
".jpeg": "image/jpeg",
|
|
@@ -132322,7 +132461,7 @@ function guessContentType2(fileName) {
|
|
|
132322
132461
|
}
|
|
132323
132462
|
async function runOpenAccountBing(opts) {
|
|
132324
132463
|
const config = loadConfig(opts.token);
|
|
132325
|
-
if (!
|
|
132464
|
+
if (!fs13.existsSync(opts.licenseFile)) {
|
|
132326
132465
|
console.error(`
|
|
132327
132466
|
\u274C \u8425\u4E1A\u6267\u7167\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${opts.licenseFile}
|
|
132328
132467
|
`);
|
|
@@ -132824,13 +132963,13 @@ Google \u5F00\u6237\u884C\u4E1A\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${rows.le
|
|
|
132824
132963
|
|
|
132825
132964
|
// src/commands/open-account/tiktok.ts
|
|
132826
132965
|
init_auth();
|
|
132827
|
-
import * as
|
|
132828
|
-
import * as
|
|
132966
|
+
import * as fs14 from "fs";
|
|
132967
|
+
import * as path19 from "path";
|
|
132829
132968
|
init_cli_json_snapshot();
|
|
132830
132969
|
init_cli_table();
|
|
132831
132970
|
async function uploadLicenseToTikTok(filePath, businessCentreType, config, verbose) {
|
|
132832
|
-
const fileName =
|
|
132833
|
-
const fileBuffer =
|
|
132971
|
+
const fileName = path19.basename(filePath);
|
|
132972
|
+
const fileBuffer = fs14.readFileSync(filePath);
|
|
132834
132973
|
const base64Image = fileBuffer.toString("base64");
|
|
132835
132974
|
const res = await apiFetch2(
|
|
132836
132975
|
`${config.apiBaseUrl}/command/media-account/tiktok/Upload`,
|
|
@@ -132855,7 +132994,7 @@ async function uploadLicenseToTikTok(filePath, businessCentreType, config, verbo
|
|
|
132855
132994
|
async function runOpenAccountTikTok(opts) {
|
|
132856
132995
|
const config = loadConfig(opts.token);
|
|
132857
132996
|
const bcType = opts.businessCentreType ?? "Shop";
|
|
132858
|
-
if (!
|
|
132997
|
+
if (!fs14.existsSync(opts.licenseFile)) {
|
|
132859
132998
|
console.error(`
|
|
132860
132999
|
\u274C \u8425\u4E1A\u6267\u7167\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${opts.licenseFile}
|
|
132861
133000
|
`);
|
|
@@ -134044,10 +134183,10 @@ async function runWebsiteDiagnosisCollect(opts) {
|
|
|
134044
134183
|
|
|
134045
134184
|
// src/commands/website-diagnosis/prepare.ts
|
|
134046
134185
|
init_cli_json_snapshot();
|
|
134047
|
-
import
|
|
134048
|
-
import
|
|
134186
|
+
import fs15 from "fs";
|
|
134187
|
+
import path20 from "path";
|
|
134049
134188
|
function readJson(filePath) {
|
|
134050
|
-
const text3 =
|
|
134189
|
+
const text3 = fs15.readFileSync(filePath, "utf8");
|
|
134051
134190
|
try {
|
|
134052
134191
|
const v = JSON.parse(text3);
|
|
134053
134192
|
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
@@ -134077,8 +134216,8 @@ function signalsFromCollectPayload(collect) {
|
|
|
134077
134216
|
});
|
|
134078
134217
|
}
|
|
134079
134218
|
async function runWebsiteDiagnosisPrepare(opts) {
|
|
134080
|
-
const collectPath =
|
|
134081
|
-
if (!
|
|
134219
|
+
const collectPath = path20.resolve(opts.collectFile);
|
|
134220
|
+
if (!fs15.existsSync(collectPath)) {
|
|
134082
134221
|
console.error(`
|
|
134083
134222
|
\u274C \u627E\u4E0D\u5230 collect \u6587\u4EF6\uFF1A${collectPath}
|
|
134084
134223
|
`);
|
|
@@ -134087,11 +134226,11 @@ async function runWebsiteDiagnosisPrepare(opts) {
|
|
|
134087
134226
|
const collect = readJson(collectPath);
|
|
134088
134227
|
const signals = signalsFromCollectPayload(collect);
|
|
134089
134228
|
const scaffold = buildDiagnosisScaffold(signals);
|
|
134090
|
-
const outPath =
|
|
134091
|
-
opts.out ??
|
|
134229
|
+
const outPath = path20.resolve(
|
|
134230
|
+
opts.out ?? path20.join(path20.dirname(collectPath), "diagnosis.scaffold.json")
|
|
134092
134231
|
);
|
|
134093
|
-
|
|
134094
|
-
|
|
134232
|
+
fs15.mkdirSync(path20.dirname(outPath), { recursive: true });
|
|
134233
|
+
fs15.writeFileSync(outPath, JSON.stringify(scaffold, null, 2), "utf8");
|
|
134095
134234
|
const summary = {
|
|
134096
134235
|
url: signals.url,
|
|
134097
134236
|
out: outPath,
|
|
@@ -134128,23 +134267,23 @@ async function runWebsiteDiagnosisPrepare(opts) {
|
|
|
134128
134267
|
}
|
|
134129
134268
|
|
|
134130
134269
|
// src/commands/website-diagnosis/render-report.ts
|
|
134131
|
-
import
|
|
134270
|
+
import fs16 from "fs";
|
|
134132
134271
|
import fsPromises from "fs/promises";
|
|
134133
|
-
import
|
|
134272
|
+
import path21 from "path";
|
|
134134
134273
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
134135
134274
|
var TEMPLATE_BASENAMES = {
|
|
134136
134275
|
html: "website-diagnosis-report.html",
|
|
134137
134276
|
runtime: "website-diagnosis-report.runtime.js"
|
|
134138
134277
|
};
|
|
134139
134278
|
function resolveSkillTemplatePath(basename13) {
|
|
134140
|
-
const dir =
|
|
134279
|
+
const dir = path21.dirname(fileURLToPath4(import.meta.url));
|
|
134141
134280
|
const candidates = [
|
|
134142
|
-
|
|
134143
|
-
|
|
134144
|
-
|
|
134281
|
+
path21.join(dir, "skill", "report-templates", basename13),
|
|
134282
|
+
path21.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
134283
|
+
path21.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
134145
134284
|
];
|
|
134146
134285
|
for (const p of candidates) {
|
|
134147
|
-
if (
|
|
134286
|
+
if (fs16.existsSync(p)) return p;
|
|
134148
134287
|
}
|
|
134149
134288
|
return candidates[0];
|
|
134150
134289
|
}
|
|
@@ -134188,11 +134327,11 @@ function injectReportData(html, payload) {
|
|
|
134188
134327
|
return html.replace(marker, `window.__WEBSITE_DIAGNOSIS__ = ${json};`);
|
|
134189
134328
|
}
|
|
134190
134329
|
async function runWebsiteDiagnosisRender(opts) {
|
|
134191
|
-
const dataPath =
|
|
134330
|
+
const dataPath = path21.resolve(opts.dataFile);
|
|
134192
134331
|
const dataRaw = await readJsonFile(dataPath);
|
|
134193
134332
|
let data = asRecord5(dataRaw);
|
|
134194
134333
|
if (opts.collectFile) {
|
|
134195
|
-
const collectRaw = await readJsonFile(
|
|
134334
|
+
const collectRaw = await readJsonFile(path21.resolve(opts.collectFile));
|
|
134196
134335
|
data = mergeCollectLighthouse(data, asRecord5(collectRaw));
|
|
134197
134336
|
}
|
|
134198
134337
|
const templatePath = websiteDiagnosisReportTemplatePath();
|
|
@@ -134206,14 +134345,14 @@ async function runWebsiteDiagnosisRender(opts) {
|
|
|
134206
134345
|
`);
|
|
134207
134346
|
process.exit(1);
|
|
134208
134347
|
}
|
|
134209
|
-
const outPath =
|
|
134210
|
-
opts.out ??
|
|
134348
|
+
const outPath = path21.resolve(
|
|
134349
|
+
opts.out ?? path21.join(path21.dirname(dataPath), "website-diagnosis-report.html")
|
|
134211
134350
|
);
|
|
134212
|
-
const outDir =
|
|
134351
|
+
const outDir = path21.dirname(outPath);
|
|
134213
134352
|
await fsPromises.mkdir(outDir, { recursive: true });
|
|
134214
134353
|
await fsPromises.writeFile(outPath, injectReportData(html, data), "utf8");
|
|
134215
134354
|
const runtimeSrc = websiteDiagnosisRuntimePath();
|
|
134216
|
-
const runtimeOut =
|
|
134355
|
+
const runtimeOut = path21.join(outDir, TEMPLATE_BASENAMES.runtime);
|
|
134217
134356
|
let runtimeCopied = false;
|
|
134218
134357
|
try {
|
|
134219
134358
|
await fsPromises.copyFile(runtimeSrc, runtimeOut);
|
|
@@ -134417,8 +134556,8 @@ async function runMarketAnalysisCollect(opts) {
|
|
|
134417
134556
|
}
|
|
134418
134557
|
|
|
134419
134558
|
// src/commands/market-analysis/render-report.ts
|
|
134420
|
-
import
|
|
134421
|
-
import
|
|
134559
|
+
import fs17 from "fs/promises";
|
|
134560
|
+
import path22 from "path";
|
|
134422
134561
|
|
|
134423
134562
|
// src/commands/market-analysis/report-content.ts
|
|
134424
134563
|
var SILUZAN_ECHARTS_CDN_URL = "https://staticpn.siluzan.com/assets/slz/homeCDN/echarts.min.js";
|
|
@@ -134869,10 +135008,10 @@ function resolveMarketAnalysisHtml(data) {
|
|
|
134869
135008
|
throw new Error("JSON \u4E2D\u7F3A\u5C11 htmlContent \u6216 rawResponse \u5B57\u6BB5");
|
|
134870
135009
|
}
|
|
134871
135010
|
async function runMarketAnalysisRender(opts) {
|
|
134872
|
-
const dataPath =
|
|
135011
|
+
const dataPath = path22.resolve(opts.dataFile);
|
|
134873
135012
|
let dataRaw;
|
|
134874
135013
|
try {
|
|
134875
|
-
dataRaw = JSON.parse(await
|
|
135014
|
+
dataRaw = JSON.parse(await fs17.readFile(dataPath, "utf8"));
|
|
134876
135015
|
} catch {
|
|
134877
135016
|
console.error(`
|
|
134878
135017
|
\u274C \u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${dataPath}
|
|
@@ -134905,11 +135044,11 @@ async function runMarketAnalysisRender(opts) {
|
|
|
134905
135044
|
);
|
|
134906
135045
|
process.exit(1);
|
|
134907
135046
|
}
|
|
134908
|
-
const outPath =
|
|
134909
|
-
opts.out ??
|
|
135047
|
+
const outPath = path22.resolve(
|
|
135048
|
+
opts.out ?? path22.join(path22.dirname(dataPath), "market-analysis-report.html")
|
|
134910
135049
|
);
|
|
134911
|
-
await
|
|
134912
|
-
await
|
|
135050
|
+
await fs17.mkdir(path22.dirname(outPath), { recursive: true });
|
|
135051
|
+
await fs17.writeFile(outPath, html, "utf8");
|
|
134913
135052
|
const { stats } = contentCheck;
|
|
134914
135053
|
console.log(`
|
|
134915
135054
|
\u2705 \u5E02\u573A\u5206\u6790 HTML \u62A5\u544A\u5DF2\u751F\u6210\uFF1A${outPath}
|
|
@@ -134955,12 +135094,12 @@ function registerMarketAnalysisCommands(program2) {
|
|
|
134955
135094
|
|
|
134956
135095
|
// src/commands/google-ads-diagnosis/run-collect.ts
|
|
134957
135096
|
init_auth();
|
|
134958
|
-
import
|
|
134959
|
-
import
|
|
135097
|
+
import fs22 from "fs/promises";
|
|
135098
|
+
import path26 from "path";
|
|
134960
135099
|
|
|
134961
135100
|
// src/commands/google-ads-diagnosis/shared.ts
|
|
134962
|
-
import
|
|
134963
|
-
import
|
|
135101
|
+
import fs18 from "fs";
|
|
135102
|
+
import path23 from "path";
|
|
134964
135103
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
134965
135104
|
var GOOGLE_ADS_DIAGNOSIS_TEMPLATE_BASENAME = "GoogleAdsDiagnosisReport.html";
|
|
134966
135105
|
var GOOGLE_ADS_DIAGNOSIS_DATA_MARKER = "__REPORT_DATA__";
|
|
@@ -135017,15 +135156,15 @@ function buildGoogleAdsDiagnosisNarrativeChecks() {
|
|
|
135017
135156
|
}
|
|
135018
135157
|
var GOOGLE_ADS_DIAGNOSIS_NARRATIVE_CHECKS = buildGoogleAdsDiagnosisNarrativeChecks();
|
|
135019
135158
|
function resolveSkillTemplatePath2(basename13) {
|
|
135020
|
-
const dir =
|
|
135159
|
+
const dir = path23.dirname(fileURLToPath5(import.meta.url));
|
|
135021
135160
|
const candidates = [
|
|
135022
|
-
|
|
135023
|
-
|
|
135024
|
-
|
|
135025
|
-
|
|
135161
|
+
path23.join(dir, "skill", "report-templates", basename13),
|
|
135162
|
+
path23.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
135163
|
+
path23.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13),
|
|
135164
|
+
path23.join(dir, "..", "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
135026
135165
|
];
|
|
135027
135166
|
for (const p of candidates) {
|
|
135028
|
-
if (
|
|
135167
|
+
if (fs18.existsSync(p)) return p;
|
|
135029
135168
|
}
|
|
135030
135169
|
return candidates[0];
|
|
135031
135170
|
}
|
|
@@ -135055,8 +135194,8 @@ function buildGoogleAdsDiagnosisCollectAgentHint(snapDir) {
|
|
|
135055
135194
|
}
|
|
135056
135195
|
|
|
135057
135196
|
// src/commands/google-ads-diagnosis/build-report-data.ts
|
|
135058
|
-
import
|
|
135059
|
-
import
|
|
135197
|
+
import fs20 from "fs";
|
|
135198
|
+
import path25 from "path";
|
|
135060
135199
|
|
|
135061
135200
|
// src/commands/google-ads-diagnosis/agent-brief.ts
|
|
135062
135201
|
function buildGoogleAdsDiagnosisAgentBrief(input) {
|
|
@@ -135125,8 +135264,8 @@ function buildGoogleAdsDiagnosisAgentBrief(input) {
|
|
|
135125
135264
|
|
|
135126
135265
|
// src/commands/google-ads-diagnosis/snapshot-io.ts
|
|
135127
135266
|
init_google_analysis_snapshot();
|
|
135128
|
-
import
|
|
135129
|
-
import
|
|
135267
|
+
import fs19 from "fs";
|
|
135268
|
+
import path24 from "path";
|
|
135130
135269
|
function dateRangeManifest(start, end) {
|
|
135131
135270
|
if (start && end) return { mode: "range", start, end };
|
|
135132
135271
|
return null;
|
|
@@ -135137,17 +135276,17 @@ function findSectionSnapshotFile(snapDir, section, accountId, start, end) {
|
|
|
135137
135276
|
accountId,
|
|
135138
135277
|
dateRangeManifest(start, end)
|
|
135139
135278
|
);
|
|
135140
|
-
const exactPath =
|
|
135141
|
-
if (
|
|
135279
|
+
const exactPath = path24.join(snapDir, exactName);
|
|
135280
|
+
if (fs19.existsSync(exactPath)) return exactPath;
|
|
135142
135281
|
if (start && end) return void 0;
|
|
135143
|
-
const files =
|
|
135144
|
-
return files.filter((f) => f.startsWith(`${section}-${accountId}`) && f.endsWith(".json")).sort().map((f) =>
|
|
135282
|
+
const files = fs19.readdirSync(snapDir);
|
|
135283
|
+
return files.filter((f) => f.startsWith(`${section}-${accountId}`) && f.endsWith(".json")).sort().map((f) => path24.join(snapDir, f)).at(-1);
|
|
135145
135284
|
}
|
|
135146
135285
|
function loadSectionSnapshot(snapDir, section, accountId, start, end) {
|
|
135147
135286
|
const file = findSectionSnapshotFile(snapDir, section, accountId, start, end);
|
|
135148
|
-
if (!file || !
|
|
135287
|
+
if (!file || !fs19.existsSync(file)) return null;
|
|
135149
135288
|
try {
|
|
135150
|
-
return JSON.parse(
|
|
135289
|
+
return JSON.parse(fs19.readFileSync(file, "utf8"));
|
|
135151
135290
|
} catch {
|
|
135152
135291
|
return null;
|
|
135153
135292
|
}
|
|
@@ -135604,10 +135743,10 @@ function toDailyConversionItem(row) {
|
|
|
135604
135743
|
};
|
|
135605
135744
|
}
|
|
135606
135745
|
function loadCompanyNameFromSnap(snapDir) {
|
|
135607
|
-
const file =
|
|
135608
|
-
if (!
|
|
135746
|
+
const file = path25.join(snapDir, "list-accounts-google.json");
|
|
135747
|
+
if (!fs20.existsSync(file)) return void 0;
|
|
135609
135748
|
try {
|
|
135610
|
-
const parsed = JSON.parse(
|
|
135749
|
+
const parsed = JSON.parse(fs20.readFileSync(file, "utf8"));
|
|
135611
135750
|
const item = parsed.items?.[0];
|
|
135612
135751
|
return item?.ma?.mediaCustomerName?.trim() || item?.mag?.advertiserName?.trim() || void 0;
|
|
135613
135752
|
} catch {
|
|
@@ -136264,7 +136403,7 @@ function invokeGoogleAnalysisCli(opts) {
|
|
|
136264
136403
|
}
|
|
136265
136404
|
|
|
136266
136405
|
// src/commands/google-ads-diagnosis/write-draft.ts
|
|
136267
|
-
import
|
|
136406
|
+
import fs21 from "fs/promises";
|
|
136268
136407
|
function asRecord10(value) {
|
|
136269
136408
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
136270
136409
|
return value;
|
|
@@ -136292,12 +136431,12 @@ function hasAgentNarrative(data) {
|
|
|
136292
136431
|
}
|
|
136293
136432
|
async function writeDiagnosisDraft(opts) {
|
|
136294
136433
|
try {
|
|
136295
|
-
const existing = JSON.parse(await
|
|
136434
|
+
const existing = JSON.parse(await fs21.readFile(opts.draftPath, "utf8"));
|
|
136296
136435
|
const record2 = asRecord10(existing);
|
|
136297
136436
|
if (record2 && hasAgentNarrative(record2)) return "skipped-existing-narrative";
|
|
136298
136437
|
} catch {
|
|
136299
136438
|
}
|
|
136300
|
-
await
|
|
136439
|
+
await fs21.writeFile(opts.draftPath, `${JSON.stringify(opts.reportData, null, 2)}
|
|
136301
136440
|
`, "utf8");
|
|
136302
136441
|
return "written";
|
|
136303
136442
|
}
|
|
@@ -136334,8 +136473,8 @@ async function runGoogleAdsDiagnosisCollect(opts) {
|
|
|
136334
136473
|
console.error("\n\u274C collect \u987B\u540C\u65F6\u6307\u5B9A --start \u4E0E --end\u3002\n");
|
|
136335
136474
|
process.exit(1);
|
|
136336
136475
|
}
|
|
136337
|
-
const snapDir =
|
|
136338
|
-
await
|
|
136476
|
+
const snapDir = path26.resolve(opts.jsonOut);
|
|
136477
|
+
await fs22.mkdir(snapDir, { recursive: true });
|
|
136339
136478
|
let degraded = false;
|
|
136340
136479
|
console.error(`
|
|
136341
136480
|
\u{1F4E5} google-analysis \u62C9\u6570\uFF1A\u8D26\u6237 ${accountId}\uFF0C${opts.start} ~ ${opts.end}
|
|
@@ -136431,13 +136570,13 @@ async function runGoogleAdsDiagnosisCollect(opts) {
|
|
|
136431
136570
|
agentBrief,
|
|
136432
136571
|
agentHint: buildGoogleAdsDiagnosisCollectAgentHint(snapDir)
|
|
136433
136572
|
};
|
|
136434
|
-
const collectPath =
|
|
136435
|
-
await
|
|
136573
|
+
const collectPath = path26.join(snapDir, GOOGLE_ADS_DIAGNOSIS_COLLECT_BASENAME);
|
|
136574
|
+
await fs22.writeFile(collectPath, `${JSON.stringify(collectPayload, null, 2)}
|
|
136436
136575
|
`, "utf8");
|
|
136437
|
-
const draftPath =
|
|
136576
|
+
const draftPath = path26.join(snapDir, GOOGLE_ADS_DIAGNOSIS_REPORT_BASENAME);
|
|
136438
136577
|
const draftOutcome = await writeDiagnosisDraft({ draftPath, reportData });
|
|
136439
|
-
const digestPath =
|
|
136440
|
-
await
|
|
136578
|
+
const digestPath = path26.join(snapDir, GOOGLE_ADS_DIAGNOSIS_DIGEST_BASENAME);
|
|
136579
|
+
await fs22.writeFile(
|
|
136441
136580
|
digestPath,
|
|
136442
136581
|
buildCollectDigest(reportData, {
|
|
136443
136582
|
accountId,
|
|
@@ -136479,8 +136618,8 @@ async function runGoogleAdsDiagnosisCollect(opts) {
|
|
|
136479
136618
|
}
|
|
136480
136619
|
|
|
136481
136620
|
// src/commands/google-ads-diagnosis/render-report.ts
|
|
136482
|
-
import
|
|
136483
|
-
import
|
|
136621
|
+
import fs23 from "fs/promises";
|
|
136622
|
+
import path27 from "path";
|
|
136484
136623
|
|
|
136485
136624
|
// src/commands/google-ads-diagnosis/report-content.ts
|
|
136486
136625
|
function asRecord11(value) {
|
|
@@ -136489,9 +136628,9 @@ function asRecord11(value) {
|
|
|
136489
136628
|
}
|
|
136490
136629
|
return null;
|
|
136491
136630
|
}
|
|
136492
|
-
function getNestedValue(root,
|
|
136631
|
+
function getNestedValue(root, path56) {
|
|
136493
136632
|
let cur = root;
|
|
136494
|
-
for (const key of
|
|
136633
|
+
for (const key of path56) {
|
|
136495
136634
|
const rec = asRecord11(cur);
|
|
136496
136635
|
if (!rec) return void 0;
|
|
136497
136636
|
cur = rec[key];
|
|
@@ -137144,7 +137283,7 @@ function asRecord16(value) {
|
|
|
137144
137283
|
}
|
|
137145
137284
|
async function tryLoadCollectReportData(collectPath) {
|
|
137146
137285
|
try {
|
|
137147
|
-
const raw = JSON.parse(await
|
|
137286
|
+
const raw = JSON.parse(await fs23.readFile(collectPath, "utf8"));
|
|
137148
137287
|
const root = asRecord16(raw);
|
|
137149
137288
|
const reportData = asRecord16(root?.reportData);
|
|
137150
137289
|
return reportData ?? root;
|
|
@@ -137153,10 +137292,10 @@ async function tryLoadCollectReportData(collectPath) {
|
|
|
137153
137292
|
}
|
|
137154
137293
|
}
|
|
137155
137294
|
async function runGoogleAdsDiagnosisRender(opts) {
|
|
137156
|
-
const dataPath =
|
|
137295
|
+
const dataPath = path27.resolve(opts.dataFile);
|
|
137157
137296
|
let dataRaw;
|
|
137158
137297
|
try {
|
|
137159
|
-
dataRaw = JSON.parse(await
|
|
137298
|
+
dataRaw = JSON.parse(await fs23.readFile(dataPath, "utf8"));
|
|
137160
137299
|
} catch {
|
|
137161
137300
|
console.error(`
|
|
137162
137301
|
\u274C \u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${dataPath}
|
|
@@ -137165,8 +137304,8 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
137165
137304
|
}
|
|
137166
137305
|
let data = asRecord16(dataRaw);
|
|
137167
137306
|
if (!opts.noMergeCollect) {
|
|
137168
|
-
const collectPath =
|
|
137169
|
-
opts.collectFile ??
|
|
137307
|
+
const collectPath = path27.resolve(
|
|
137308
|
+
opts.collectFile ?? path27.join(path27.dirname(dataPath), GOOGLE_ADS_DIAGNOSIS_COLLECT_BASENAME)
|
|
137170
137309
|
);
|
|
137171
137310
|
const collectReportData = await tryLoadCollectReportData(collectPath);
|
|
137172
137311
|
if (collectReportData) {
|
|
@@ -137195,7 +137334,7 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
137195
137334
|
}
|
|
137196
137335
|
}
|
|
137197
137336
|
}
|
|
137198
|
-
data = reconcileGoldAccountInReport(data,
|
|
137337
|
+
data = reconcileGoldAccountInReport(data, path27.dirname(dataPath));
|
|
137199
137338
|
data = applyDataRenderedCopy(data);
|
|
137200
137339
|
const overview = normalizeDiagnosisOverview(data);
|
|
137201
137340
|
data = overview.data;
|
|
@@ -137251,7 +137390,7 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
137251
137390
|
const templatePath = googleAdsDiagnosisReportTemplatePath();
|
|
137252
137391
|
let html;
|
|
137253
137392
|
try {
|
|
137254
|
-
html = await
|
|
137393
|
+
html = await fs23.readFile(templatePath, "utf8");
|
|
137255
137394
|
} catch {
|
|
137256
137395
|
console.error(`
|
|
137257
137396
|
\u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
|
|
@@ -137269,11 +137408,11 @@ async function runGoogleAdsDiagnosisRender(opts) {
|
|
|
137269
137408
|
`);
|
|
137270
137409
|
process.exit(1);
|
|
137271
137410
|
}
|
|
137272
|
-
const outPath =
|
|
137273
|
-
opts.out ??
|
|
137411
|
+
const outPath = path27.resolve(
|
|
137412
|
+
opts.out ?? path27.join(path27.dirname(dataPath), "google-ads-diagnosis-report.html")
|
|
137274
137413
|
);
|
|
137275
|
-
await
|
|
137276
|
-
await
|
|
137414
|
+
await fs23.mkdir(path27.dirname(outPath), { recursive: true });
|
|
137415
|
+
await fs23.writeFile(outPath, rendered, "utf8");
|
|
137277
137416
|
console.log(`
|
|
137278
137417
|
\u2705 Google \u5E7F\u544A\u8BCA\u65AD HTML \u62A5\u544A\u5DF2\u751F\u6210\uFF1A${outPath}
|
|
137279
137418
|
`);
|
|
@@ -137340,8 +137479,8 @@ function registerGoogleAdsDiagnosisCommands(program2) {
|
|
|
137340
137479
|
|
|
137341
137480
|
// src/commands/google-quarterly/run-collect.ts
|
|
137342
137481
|
init_auth();
|
|
137343
|
-
import
|
|
137344
|
-
import
|
|
137482
|
+
import fs26 from "fs/promises";
|
|
137483
|
+
import path30 from "path";
|
|
137345
137484
|
|
|
137346
137485
|
// src/commands/google-quarterly/drill-country.ts
|
|
137347
137486
|
init_geo_en2zh();
|
|
@@ -137848,31 +137987,31 @@ function buildSpendPlanDefaults(currentSpend) {
|
|
|
137848
137987
|
}
|
|
137849
137988
|
|
|
137850
137989
|
// src/commands/google-quarterly/region.ts
|
|
137851
|
-
import
|
|
137852
|
-
import
|
|
137990
|
+
import fs24 from "fs";
|
|
137991
|
+
import path28 from "path";
|
|
137853
137992
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
137854
137993
|
var EAST_ASIA = /* @__PURE__ */ new Set(["\u4E2D\u56FD", "\u65E5\u672C", "\u97E9\u56FD", "\u671D\u9C9C", "\u8499\u53E4", "\u9999\u6E2F", "\u6FB3\u95E8", "\u53F0\u6E7E"]);
|
|
137855
137994
|
var continentMap = null;
|
|
137856
137995
|
function continentsPath() {
|
|
137857
|
-
const dir =
|
|
137996
|
+
const dir = path28.dirname(fileURLToPath6(import.meta.url));
|
|
137858
137997
|
const candidates = [
|
|
137859
137998
|
// dist/index.js → dist/skill/references/...
|
|
137860
|
-
|
|
137861
|
-
|
|
137999
|
+
path28.join(dir, "skill", "references", "analytics", "geo-continents.json"),
|
|
138000
|
+
path28.join(dir, "skill", "siluzan-ads", "references", "analytics", "geo-continents.json"),
|
|
137862
138001
|
// dist/index.js → tso-cli/assets/...
|
|
137863
|
-
|
|
138002
|
+
path28.join(dir, "..", "assets", "siluzan-ads", "references", "analytics", "geo-continents.json"),
|
|
137864
138003
|
// src/commands/google-quarterly/region.ts → tso-cli/assets/...
|
|
137865
|
-
|
|
137866
|
-
|
|
138004
|
+
path28.join(dir, "..", "..", "assets", "siluzan-ads", "references", "analytics", "geo-continents.json"),
|
|
138005
|
+
path28.join(dir, "..", "..", "..", "assets", "siluzan-ads", "references", "analytics", "geo-continents.json")
|
|
137867
138006
|
];
|
|
137868
138007
|
for (const p of candidates) {
|
|
137869
|
-
if (
|
|
138008
|
+
if (fs24.existsSync(p)) return p;
|
|
137870
138009
|
}
|
|
137871
138010
|
return candidates[0];
|
|
137872
138011
|
}
|
|
137873
138012
|
function loadContinentMap() {
|
|
137874
138013
|
if (continentMap) return continentMap;
|
|
137875
|
-
const raw = JSON.parse(
|
|
138014
|
+
const raw = JSON.parse(fs24.readFileSync(continentsPath(), "utf8"));
|
|
137876
138015
|
const map = {};
|
|
137877
138016
|
for (const [k, v] of Object.entries(raw)) {
|
|
137878
138017
|
if (k.startsWith("_")) continue;
|
|
@@ -138308,23 +138447,23 @@ function roundFacts(facts) {
|
|
|
138308
138447
|
}
|
|
138309
138448
|
|
|
138310
138449
|
// src/commands/google-quarterly/shared.ts
|
|
138311
|
-
import
|
|
138312
|
-
import
|
|
138450
|
+
import fs25 from "fs";
|
|
138451
|
+
import path29 from "path";
|
|
138313
138452
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
138314
138453
|
var GOOGLE_QUARTERLY_COLLECT_BASENAME = "google-quarterly-collect.json";
|
|
138315
138454
|
var GOOGLE_QUARTERLY_HTML_BASENAME = "google-quarterly-report.html";
|
|
138316
138455
|
var GOOGLE_QUARTERLY_TEMPLATE_BASENAME = "google-quarterly-report.html";
|
|
138317
138456
|
var GOOGLE_QUARTERLY_INJECT_MARKER = "window.__GOOGLE_QUARTERLY_REPORT__ = window.__GOOGLE_QUARTERLY_REPORT__ || null;";
|
|
138318
138457
|
function googleQuarterlyTemplatePath() {
|
|
138319
|
-
const dir =
|
|
138458
|
+
const dir = path29.dirname(fileURLToPath7(import.meta.url));
|
|
138320
138459
|
const candidates = [
|
|
138321
|
-
|
|
138322
|
-
|
|
138323
|
-
|
|
138324
|
-
|
|
138460
|
+
path29.join(dir, "skill", "report-templates", GOOGLE_QUARTERLY_TEMPLATE_BASENAME),
|
|
138461
|
+
path29.join(dir, "skill", "siluzan-ads", "report-templates", GOOGLE_QUARTERLY_TEMPLATE_BASENAME),
|
|
138462
|
+
path29.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", GOOGLE_QUARTERLY_TEMPLATE_BASENAME),
|
|
138463
|
+
path29.join(dir, "..", "..", "..", "assets", "siluzan-ads", "report-templates", GOOGLE_QUARTERLY_TEMPLATE_BASENAME)
|
|
138325
138464
|
];
|
|
138326
138465
|
for (const p of candidates) {
|
|
138327
|
-
if (
|
|
138466
|
+
if (fs25.existsSync(p)) return p;
|
|
138328
138467
|
}
|
|
138329
138468
|
return candidates[2];
|
|
138330
138469
|
}
|
|
@@ -138350,7 +138489,7 @@ function periodSnap(dir, account, start, end, extra = []) {
|
|
|
138350
138489
|
}
|
|
138351
138490
|
async function readInquiries(file) {
|
|
138352
138491
|
if (!file?.trim()) return void 0;
|
|
138353
|
-
const raw = await
|
|
138492
|
+
const raw = await fs26.readFile(path30.resolve(file), "utf8");
|
|
138354
138493
|
return JSON.parse(raw);
|
|
138355
138494
|
}
|
|
138356
138495
|
async function runGoogleQuarterlyCollect(opts) {
|
|
@@ -138363,8 +138502,8 @@ async function runGoogleQuarterlyCollect(opts) {
|
|
|
138363
138502
|
const previous = previousRange(current.start, current.end);
|
|
138364
138503
|
const yoy = yearOverYearRange(current.start, current.end);
|
|
138365
138504
|
const months = listMonths(current.start, current.end);
|
|
138366
|
-
const snapDir =
|
|
138367
|
-
await
|
|
138505
|
+
const snapDir = path30.resolve(opts.jsonOut);
|
|
138506
|
+
await fs26.mkdir(snapDir, { recursive: true });
|
|
138368
138507
|
let degraded = false;
|
|
138369
138508
|
const run = (label2, start, end, sections) => {
|
|
138370
138509
|
console.error(`
|
|
@@ -138492,8 +138631,8 @@ async function runGoogleQuarterlyCollect(opts) {
|
|
|
138492
138631
|
planDefaults: facts.planDefaults
|
|
138493
138632
|
}
|
|
138494
138633
|
};
|
|
138495
|
-
const outFile =
|
|
138496
|
-
await
|
|
138634
|
+
const outFile = path30.join(snapDir, GOOGLE_QUARTERLY_COLLECT_BASENAME);
|
|
138635
|
+
await fs26.writeFile(outFile, JSON.stringify(payload, null, 2), "utf8");
|
|
138497
138636
|
console.log(
|
|
138498
138637
|
JSON.stringify({
|
|
138499
138638
|
kind: "siluzan-tso-google-quarterly-collect-summary",
|
|
@@ -138512,8 +138651,8 @@ async function runGoogleQuarterlyCollect(opts) {
|
|
|
138512
138651
|
}
|
|
138513
138652
|
|
|
138514
138653
|
// src/commands/google-quarterly/render-report.ts
|
|
138515
|
-
import
|
|
138516
|
-
import
|
|
138654
|
+
import fs27 from "fs/promises";
|
|
138655
|
+
import path32 from "path";
|
|
138517
138656
|
|
|
138518
138657
|
// src/commands/google-quarterly/report-content.ts
|
|
138519
138658
|
function asRecord17(value) {
|
|
@@ -138556,9 +138695,9 @@ function mergeCollectFacts(agentData, collect) {
|
|
|
138556
138695
|
|
|
138557
138696
|
// src/test-utils/report-echarts.ts
|
|
138558
138697
|
import { readFileSync as readFileSync19 } from "fs";
|
|
138559
|
-
import
|
|
138698
|
+
import path31 from "path";
|
|
138560
138699
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
138561
|
-
var TSO_CLI_ROOT =
|
|
138700
|
+
var TSO_CLI_ROOT = path31.join(path31.dirname(fileURLToPath8(import.meta.url)), "../..");
|
|
138562
138701
|
|
|
138563
138702
|
// src/commands/google-quarterly/render-report.ts
|
|
138564
138703
|
function asRecord18(value) {
|
|
@@ -138568,22 +138707,22 @@ function asRecord18(value) {
|
|
|
138568
138707
|
throw new Error("\u62A5\u544A JSON \u987B\u4E3A\u5BF9\u8C61");
|
|
138569
138708
|
}
|
|
138570
138709
|
async function runGoogleQuarterlyRender(opts) {
|
|
138571
|
-
const dataPath =
|
|
138710
|
+
const dataPath = path32.resolve(opts.dataFile);
|
|
138572
138711
|
let agentRaw;
|
|
138573
138712
|
try {
|
|
138574
|
-
agentRaw = JSON.parse(await
|
|
138713
|
+
agentRaw = JSON.parse(await fs27.readFile(dataPath, "utf8"));
|
|
138575
138714
|
} catch {
|
|
138576
138715
|
console.error(`
|
|
138577
138716
|
\u274C \u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${dataPath}
|
|
138578
138717
|
`);
|
|
138579
138718
|
process.exit(1);
|
|
138580
138719
|
}
|
|
138581
|
-
const collectPath =
|
|
138582
|
-
opts.collectFile ??
|
|
138720
|
+
const collectPath = path32.resolve(
|
|
138721
|
+
opts.collectFile ?? path32.join(path32.dirname(dataPath), GOOGLE_QUARTERLY_COLLECT_BASENAME)
|
|
138583
138722
|
);
|
|
138584
138723
|
let collectRaw;
|
|
138585
138724
|
try {
|
|
138586
|
-
collectRaw = JSON.parse(await
|
|
138725
|
+
collectRaw = JSON.parse(await fs27.readFile(collectPath, "utf8"));
|
|
138587
138726
|
} catch {
|
|
138588
138727
|
console.error(`
|
|
138589
138728
|
\u274C \u65E0\u6CD5\u8BFB\u53D6 collect\uFF1A${collectPath}
|
|
@@ -138601,22 +138740,22 @@ async function runGoogleQuarterlyRender(opts) {
|
|
|
138601
138740
|
const templatePath = googleQuarterlyTemplatePath();
|
|
138602
138741
|
let html;
|
|
138603
138742
|
try {
|
|
138604
|
-
html = await
|
|
138743
|
+
html = await fs27.readFile(templatePath, "utf8");
|
|
138605
138744
|
} catch {
|
|
138606
138745
|
console.error(`
|
|
138607
138746
|
\u274C \u627E\u4E0D\u5230\u6A21\u677F\uFF1A${templatePath}
|
|
138608
138747
|
`);
|
|
138609
138748
|
process.exit(1);
|
|
138610
138749
|
}
|
|
138611
|
-
const outPath =
|
|
138612
|
-
await
|
|
138750
|
+
const outPath = path32.resolve(opts.out ?? path32.join(path32.dirname(dataPath), GOOGLE_QUARTERLY_HTML_BASENAME));
|
|
138751
|
+
await fs27.mkdir(path32.dirname(outPath), { recursive: true });
|
|
138613
138752
|
const periodChrome = reportPeriodChrome(readMetaRange(merged, "current"), readMetaRange(merged, "previous"));
|
|
138614
138753
|
const outHtml = injectQuarterlyReport(html, { ...merged, periodChrome });
|
|
138615
138754
|
if (!outHtml.includes("homeCDN/echarts.min.js") || /new Chart\s*\(/.test(outHtml)) {
|
|
138616
138755
|
console.error("\n\u274C \u6A21\u677F\u5FC5\u987B\u4F7F\u7528 ECharts\uFF0C\u7981\u6B62 Chart.js\u3002\n");
|
|
138617
138756
|
process.exit(1);
|
|
138618
138757
|
}
|
|
138619
|
-
await
|
|
138758
|
+
await fs27.writeFile(outPath, outHtml, "utf8");
|
|
138620
138759
|
console.log(`
|
|
138621
138760
|
\u2705 ${periodChrome.reportTitle}\u5DF2\u751F\u6210\uFF1A${outPath}
|
|
138622
138761
|
`);
|
|
@@ -138755,14 +138894,14 @@ var FACEBOOK_SECTION_ALIASES = {
|
|
|
138755
138894
|
import { Command as Command2 } from "commander";
|
|
138756
138895
|
|
|
138757
138896
|
// src/commands/facebook-analysis/render-report.ts
|
|
138758
|
-
import
|
|
138897
|
+
import fs35 from "fs";
|
|
138759
138898
|
import fsPromises3 from "fs/promises";
|
|
138760
|
-
import
|
|
138899
|
+
import path42 from "path";
|
|
138761
138900
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
138762
138901
|
|
|
138763
138902
|
// src/commands/facebook-analysis/merge-snapshot.ts
|
|
138764
|
-
import * as
|
|
138765
|
-
import * as
|
|
138903
|
+
import * as fs34 from "fs/promises";
|
|
138904
|
+
import * as path41 from "path";
|
|
138766
138905
|
|
|
138767
138906
|
// src/commands/facebook-analysis/report-metrics.ts
|
|
138768
138907
|
function asRecord24(value) {
|
|
@@ -138914,7 +139053,7 @@ function hasResults(row) {
|
|
|
138914
139053
|
|
|
138915
139054
|
// src/commands/facebook-analysis/merge-snapshot.ts
|
|
138916
139055
|
async function readManifest3(snapshotDir) {
|
|
138917
|
-
const entries = await
|
|
139056
|
+
const entries = await fs34.readdir(snapshotDir);
|
|
138918
139057
|
const manifestNames = entries.filter(
|
|
138919
139058
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
138920
139059
|
);
|
|
@@ -138924,7 +139063,7 @@ async function readManifest3(snapshotDir) {
|
|
|
138924
139063
|
];
|
|
138925
139064
|
for (const name2 of ordered) {
|
|
138926
139065
|
try {
|
|
138927
|
-
const raw = await
|
|
139066
|
+
const raw = await fs34.readFile(path41.join(snapshotDir, name2), "utf8");
|
|
138928
139067
|
const parsed = JSON.parse(raw);
|
|
138929
139068
|
if (parsed?.artifacts?.length) return parsed;
|
|
138930
139069
|
} catch {
|
|
@@ -138934,7 +139073,7 @@ async function readManifest3(snapshotDir) {
|
|
|
138934
139073
|
}
|
|
138935
139074
|
async function loadSectionFile3(snapshotDir, file) {
|
|
138936
139075
|
try {
|
|
138937
|
-
const raw = await
|
|
139076
|
+
const raw = await fs34.readFile(path41.join(snapshotDir, file), "utf8");
|
|
138938
139077
|
return asRecord24(JSON.parse(raw));
|
|
138939
139078
|
} catch {
|
|
138940
139079
|
return null;
|
|
@@ -138978,7 +139117,7 @@ function mapAdSetRows(groups) {
|
|
|
138978
139117
|
})).sort((a, b) => (b.spend ?? 0) - (a.spend ?? 0));
|
|
138979
139118
|
}
|
|
138980
139119
|
async function mergeFacebookSnapshotIntoReport(payload, snapshotDir) {
|
|
138981
|
-
const absDir =
|
|
139120
|
+
const absDir = path41.resolve(snapshotDir);
|
|
138982
139121
|
const manifest = await readManifest3(snapshotDir);
|
|
138983
139122
|
if (!manifest) {
|
|
138984
139123
|
throw new Error(
|
|
@@ -139585,14 +139724,14 @@ var TEMPLATE_BASENAMES2 = {
|
|
|
139585
139724
|
};
|
|
139586
139725
|
var INJECT_MARKER2 = "window.__META_PERIOD_REPORT__ = window.__META_PERIOD_REPORT__ || null;";
|
|
139587
139726
|
function resolveSkillTemplatePath4(basename13) {
|
|
139588
|
-
const dir =
|
|
139727
|
+
const dir = path42.dirname(fileURLToPath10(import.meta.url));
|
|
139589
139728
|
const candidates = [
|
|
139590
|
-
|
|
139591
|
-
|
|
139592
|
-
|
|
139729
|
+
path42.join(dir, "skill", "report-templates", basename13),
|
|
139730
|
+
path42.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
139731
|
+
path42.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
139593
139732
|
];
|
|
139594
139733
|
for (const p of candidates) {
|
|
139595
|
-
if (
|
|
139734
|
+
if (fs35.existsSync(p)) return p;
|
|
139596
139735
|
}
|
|
139597
139736
|
return candidates[0];
|
|
139598
139737
|
}
|
|
@@ -139637,7 +139776,7 @@ function injectReportData3(html, payload) {
|
|
|
139637
139776
|
}
|
|
139638
139777
|
function defaultOutPath(dataPath, format, out) {
|
|
139639
139778
|
if (out?.trim()) {
|
|
139640
|
-
const resolved =
|
|
139779
|
+
const resolved = path42.resolve(out);
|
|
139641
139780
|
if (format === "xlsx" && !/\.xlsx$/i.test(resolved)) {
|
|
139642
139781
|
return resolved.replace(/\.(html?)$/i, ".xlsx");
|
|
139643
139782
|
}
|
|
@@ -139646,14 +139785,14 @@ function defaultOutPath(dataPath, format, out) {
|
|
|
139646
139785
|
}
|
|
139647
139786
|
return resolved;
|
|
139648
139787
|
}
|
|
139649
|
-
const dir =
|
|
139650
|
-
return
|
|
139788
|
+
const dir = path42.dirname(dataPath);
|
|
139789
|
+
return path42.join(dir, format === "xlsx" ? "meta-period-report.xlsx" : "meta-period-report.html");
|
|
139651
139790
|
}
|
|
139652
139791
|
async function runFacebookAnalysisRender(opts) {
|
|
139653
|
-
const dataPath =
|
|
139792
|
+
const dataPath = path42.resolve(opts.dataFile);
|
|
139654
139793
|
let data = asRecord27(await readJsonFile4(dataPath));
|
|
139655
139794
|
if (opts.snapshotDir?.trim()) {
|
|
139656
|
-
data = await mergeFacebookSnapshotIntoReport(data,
|
|
139795
|
+
data = await mergeFacebookSnapshotIntoReport(data, path42.resolve(opts.snapshotDir));
|
|
139657
139796
|
}
|
|
139658
139797
|
localizeFacebookReportLabels(data);
|
|
139659
139798
|
const contentCheck = validateMetaPeriodReportContent(data);
|
|
@@ -139672,7 +139811,7 @@ async function runFacebookAnalysisRender(opts) {
|
|
|
139672
139811
|
const written = [];
|
|
139673
139812
|
for (const format of formats) {
|
|
139674
139813
|
const outPath = defaultOutPath(dataPath, format, opts.out);
|
|
139675
|
-
await fsPromises3.mkdir(
|
|
139814
|
+
await fsPromises3.mkdir(path42.dirname(outPath), { recursive: true });
|
|
139676
139815
|
if (format === "xlsx") {
|
|
139677
139816
|
writeMetaPeriodExcel(outPath, data);
|
|
139678
139817
|
} else {
|
|
@@ -139708,14 +139847,14 @@ async function runFacebookAnalysisRender(opts) {
|
|
|
139708
139847
|
}
|
|
139709
139848
|
|
|
139710
139849
|
// src/commands/facebook-analysis/diagnosis-render-report.ts
|
|
139711
|
-
import
|
|
139850
|
+
import fs37 from "fs";
|
|
139712
139851
|
import fsPromises4 from "fs/promises";
|
|
139713
|
-
import
|
|
139852
|
+
import path44 from "path";
|
|
139714
139853
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
139715
139854
|
|
|
139716
139855
|
// src/commands/facebook-analysis/diagnosis-merge-snapshot.ts
|
|
139717
|
-
import * as
|
|
139718
|
-
import * as
|
|
139856
|
+
import * as fs36 from "fs/promises";
|
|
139857
|
+
import * as path43 from "path";
|
|
139719
139858
|
function asRecord28(value) {
|
|
139720
139859
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
139721
139860
|
return value;
|
|
@@ -139751,7 +139890,7 @@ async function readManifest4(snapshotDir, accountId) {
|
|
|
139751
139890
|
const candidates = [];
|
|
139752
139891
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
139753
139892
|
try {
|
|
139754
|
-
const entries = await
|
|
139893
|
+
const entries = await fs36.readdir(snapshotDir);
|
|
139755
139894
|
const manifestNames = entries.filter(
|
|
139756
139895
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
139757
139896
|
);
|
|
@@ -139765,7 +139904,7 @@ async function readManifest4(snapshotDir, accountId) {
|
|
|
139765
139904
|
}
|
|
139766
139905
|
for (const name2 of candidates) {
|
|
139767
139906
|
try {
|
|
139768
|
-
const raw = await
|
|
139907
|
+
const raw = await fs36.readFile(path43.join(snapshotDir, name2), "utf8");
|
|
139769
139908
|
const parsed = JSON.parse(raw);
|
|
139770
139909
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
139771
139910
|
} catch {
|
|
@@ -139775,14 +139914,14 @@ async function readManifest4(snapshotDir, accountId) {
|
|
|
139775
139914
|
}
|
|
139776
139915
|
async function loadSectionFile4(snapshotDir, file) {
|
|
139777
139916
|
try {
|
|
139778
|
-
const raw = await
|
|
139917
|
+
const raw = await fs36.readFile(path43.join(snapshotDir, file), "utf8");
|
|
139779
139918
|
return asRecord28(JSON.parse(raw));
|
|
139780
139919
|
} catch {
|
|
139781
139920
|
return null;
|
|
139782
139921
|
}
|
|
139783
139922
|
}
|
|
139784
139923
|
async function mergeMetaDiagnosisSnapshotIntoReport(payload, snapshotDir) {
|
|
139785
|
-
const absDir =
|
|
139924
|
+
const absDir = path43.resolve(snapshotDir);
|
|
139786
139925
|
const metaAccountId = typeof asRecord28(payload.meta)?.accountId === "string" ? asRecord28(payload.meta)?.accountId : void 0;
|
|
139787
139926
|
const manifest = await readManifest4(snapshotDir, metaAccountId);
|
|
139788
139927
|
if (!manifest) {
|
|
@@ -140061,14 +140200,14 @@ function formatMetaDiagnosisReportErrors(result) {
|
|
|
140061
140200
|
var TEMPLATE_BASENAME2 = "meta-account-diagnosis-report.html";
|
|
140062
140201
|
var INJECT_MARKER3 = "window.__META_DIAGNOSIS_REPORT__ = window.__META_DIAGNOSIS_REPORT__ || null;";
|
|
140063
140202
|
function resolveSkillTemplatePath5(basename13) {
|
|
140064
|
-
const dir =
|
|
140203
|
+
const dir = path44.dirname(fileURLToPath11(import.meta.url));
|
|
140065
140204
|
const candidates = [
|
|
140066
|
-
|
|
140067
|
-
|
|
140068
|
-
|
|
140205
|
+
path44.join(dir, "skill", "report-templates", basename13),
|
|
140206
|
+
path44.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
140207
|
+
path44.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
140069
140208
|
];
|
|
140070
140209
|
for (const p of candidates) {
|
|
140071
|
-
if (
|
|
140210
|
+
if (fs37.existsSync(p)) return p;
|
|
140072
140211
|
}
|
|
140073
140212
|
return candidates[0];
|
|
140074
140213
|
}
|
|
@@ -140097,10 +140236,10 @@ function injectReportData4(html, payload) {
|
|
|
140097
140236
|
return html.replace(INJECT_MARKER3, `window.__META_DIAGNOSIS_REPORT__ = ${json};`);
|
|
140098
140237
|
}
|
|
140099
140238
|
async function runFacebookAnalysisDiagnosisRender(opts) {
|
|
140100
|
-
const dataPath =
|
|
140239
|
+
const dataPath = path44.resolve(opts.dataFile);
|
|
140101
140240
|
let data = asRecord30(await readJsonFile5(dataPath));
|
|
140102
140241
|
if (opts.snapshotDir?.trim()) {
|
|
140103
|
-
data = await mergeMetaDiagnosisSnapshotIntoReport(data,
|
|
140242
|
+
data = await mergeMetaDiagnosisSnapshotIntoReport(data, path44.resolve(opts.snapshotDir));
|
|
140104
140243
|
}
|
|
140105
140244
|
const contentCheck = validateMetaDiagnosisReportContent(data);
|
|
140106
140245
|
if (!contentCheck.ok) {
|
|
@@ -140126,10 +140265,10 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
|
|
|
140126
140265
|
`);
|
|
140127
140266
|
process.exit(1);
|
|
140128
140267
|
}
|
|
140129
|
-
const outPath =
|
|
140130
|
-
opts.out ??
|
|
140268
|
+
const outPath = path44.resolve(
|
|
140269
|
+
opts.out ?? path44.join(path44.dirname(dataPath), "meta-account-diagnosis-report.html")
|
|
140131
140270
|
);
|
|
140132
|
-
const outDir =
|
|
140271
|
+
const outDir = path44.dirname(outPath);
|
|
140133
140272
|
await fsPromises4.mkdir(outDir, { recursive: true });
|
|
140134
140273
|
await fsPromises4.writeFile(outPath, injectReportData4(html, data), "utf8");
|
|
140135
140274
|
const { stats } = contentCheck;
|
|
@@ -140147,7 +140286,7 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
|
|
|
140147
140286
|
|
|
140148
140287
|
// src/commands/facebook-analysis/run-batch.ts
|
|
140149
140288
|
init_auth();
|
|
140150
|
-
import * as
|
|
140289
|
+
import * as path45 from "path";
|
|
140151
140290
|
import { performance as performance5 } from "perf_hooks";
|
|
140152
140291
|
init_version();
|
|
140153
140292
|
|
|
@@ -140249,7 +140388,7 @@ async function runAllFacebookSections(opts) {
|
|
|
140249
140388
|
const results = await runWithConcurrency3(tasks, concurrency);
|
|
140250
140389
|
const succeeded = results.filter((r) => r.ok).length;
|
|
140251
140390
|
const failed = results.length - succeeded;
|
|
140252
|
-
const absoluteSnapshotDir =
|
|
140391
|
+
const absoluteSnapshotDir = path45.resolve(opts.jsonOut);
|
|
140253
140392
|
const summary = {
|
|
140254
140393
|
kind: "siluzan-tso-facebook-analysis-snapshot-batch",
|
|
140255
140394
|
absoluteSnapshotDir,
|
|
@@ -140373,9 +140512,9 @@ function parseEffectiveStatusFilter(raw) {
|
|
|
140373
140512
|
}
|
|
140374
140513
|
return canonical.length ? canonical.join(",") : void 0;
|
|
140375
140514
|
}
|
|
140376
|
-
function facebookAdsUrl(facebookApiUrl, digits,
|
|
140515
|
+
function facebookAdsUrl(facebookApiUrl, digits, path56) {
|
|
140377
140516
|
const base = facebookApiUrl.replace(/\/$/, "");
|
|
140378
|
-
const p =
|
|
140517
|
+
const p = path56.startsWith("/") ? path56 : `/${path56}`;
|
|
140379
140518
|
return `${base}/api/fb/ads/${digits}${p}`;
|
|
140380
140519
|
}
|
|
140381
140520
|
function facebookInsightsUrl(facebookApiUrl, digits, level) {
|
|
@@ -140412,7 +140551,7 @@ async function fetchFacebookAccount(config, digits, verbose) {
|
|
|
140412
140551
|
verbose
|
|
140413
140552
|
);
|
|
140414
140553
|
}
|
|
140415
|
-
async function fetchFacebookPagedList(config, digits,
|
|
140554
|
+
async function fetchFacebookPagedList(config, digits, path56, opts) {
|
|
140416
140555
|
const base = requireFacebookApi(config);
|
|
140417
140556
|
const items3 = [];
|
|
140418
140557
|
let after;
|
|
@@ -140427,7 +140566,7 @@ async function fetchFacebookPagedList(config, digits, path55, opts) {
|
|
|
140427
140566
|
adsetId: opts.adsetId
|
|
140428
140567
|
});
|
|
140429
140568
|
const raw = await apiFetch2(
|
|
140430
|
-
`${facebookAdsUrl(base, digits,
|
|
140569
|
+
`${facebookAdsUrl(base, digits, path56)}?${query}`,
|
|
140431
140570
|
config,
|
|
140432
140571
|
{},
|
|
140433
140572
|
opts.verbose
|
|
@@ -140562,7 +140701,7 @@ async function runFacebookEntityList(opts, kind) {
|
|
|
140562
140701
|
}
|
|
140563
140702
|
const pageSize = resolveFacebookPageSize(opts.pageSize);
|
|
140564
140703
|
const config = loadConfig(opts.token);
|
|
140565
|
-
const
|
|
140704
|
+
const path56 = `/${kind}`;
|
|
140566
140705
|
const labels = {
|
|
140567
140706
|
campaigns: {
|
|
140568
140707
|
section: "facebook-campaign-entities",
|
|
@@ -140575,7 +140714,7 @@ async function runFacebookEntityList(opts, kind) {
|
|
|
140575
140714
|
const meta = labels[kind];
|
|
140576
140715
|
let result;
|
|
140577
140716
|
try {
|
|
140578
|
-
result = await fetchFacebookPagedList(config, manifestId,
|
|
140717
|
+
result = await fetchFacebookPagedList(config, manifestId, path56, {
|
|
140579
140718
|
pageSize,
|
|
140580
140719
|
verbose: !!opts.verbose,
|
|
140581
140720
|
effectiveStatus,
|
|
@@ -141321,7 +141460,7 @@ function endpointHintForBingSection(def) {
|
|
|
141321
141460
|
|
|
141322
141461
|
// src/commands/bing-analysis/run-batch.ts
|
|
141323
141462
|
init_auth();
|
|
141324
|
-
import * as
|
|
141463
|
+
import * as path46 from "path";
|
|
141325
141464
|
import { performance as performance6 } from "perf_hooks";
|
|
141326
141465
|
init_version();
|
|
141327
141466
|
async function runWithConcurrency4(tasks, concurrency) {
|
|
@@ -141396,7 +141535,7 @@ async function runAllBingSections(opts) {
|
|
|
141396
141535
|
const results = await runWithConcurrency4(tasks, concurrency);
|
|
141397
141536
|
const succeeded = results.filter((r) => r.ok).length;
|
|
141398
141537
|
const failed = results.length - succeeded;
|
|
141399
|
-
const absoluteSnapshotDir =
|
|
141538
|
+
const absoluteSnapshotDir = path46.resolve(opts.jsonOut);
|
|
141400
141539
|
const summary = {
|
|
141401
141540
|
kind: "siluzan-tso-bing-analysis-snapshot-batch",
|
|
141402
141541
|
absoluteSnapshotDir,
|
|
@@ -141740,14 +141879,14 @@ Bing \u5B98\u65B9\u6708\u6D88\u8017\uFF08${id}\uFF09
|
|
|
141740
141879
|
import { Command as Command3 } from "commander";
|
|
141741
141880
|
|
|
141742
141881
|
// src/commands/bing-analysis/render-report.ts
|
|
141743
|
-
import
|
|
141882
|
+
import fs39 from "fs";
|
|
141744
141883
|
import fsPromises5 from "fs/promises";
|
|
141745
|
-
import
|
|
141884
|
+
import path48 from "path";
|
|
141746
141885
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
141747
141886
|
|
|
141748
141887
|
// src/commands/bing-analysis/merge-snapshot.ts
|
|
141749
|
-
import * as
|
|
141750
|
-
import * as
|
|
141888
|
+
import * as fs38 from "fs/promises";
|
|
141889
|
+
import * as path47 from "path";
|
|
141751
141890
|
function asRecord32(value) {
|
|
141752
141891
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
141753
141892
|
return value;
|
|
@@ -141769,7 +141908,7 @@ function asRows2(value) {
|
|
|
141769
141908
|
}
|
|
141770
141909
|
async function loadSectionPayload(snapshotDir, file) {
|
|
141771
141910
|
try {
|
|
141772
|
-
const raw = await
|
|
141911
|
+
const raw = await fs38.readFile(path47.join(snapshotDir, file), "utf8");
|
|
141773
141912
|
return JSON.parse(raw);
|
|
141774
141913
|
} catch {
|
|
141775
141914
|
return null;
|
|
@@ -141779,7 +141918,7 @@ async function readManifest5(snapshotDir, accountId) {
|
|
|
141779
141918
|
const candidates = [];
|
|
141780
141919
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
141781
141920
|
try {
|
|
141782
|
-
const entries = await
|
|
141921
|
+
const entries = await fs38.readdir(snapshotDir);
|
|
141783
141922
|
const manifestNames = entries.filter(
|
|
141784
141923
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
141785
141924
|
);
|
|
@@ -141790,7 +141929,7 @@ async function readManifest5(snapshotDir, accountId) {
|
|
|
141790
141929
|
}
|
|
141791
141930
|
for (const name2 of candidates) {
|
|
141792
141931
|
try {
|
|
141793
|
-
const raw = await
|
|
141932
|
+
const raw = await fs38.readFile(path47.join(snapshotDir, name2), "utf8");
|
|
141794
141933
|
const parsed = JSON.parse(raw);
|
|
141795
141934
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
141796
141935
|
} catch {
|
|
@@ -141957,7 +142096,7 @@ function mapSearchTermRows(payload) {
|
|
|
141957
142096
|
);
|
|
141958
142097
|
}
|
|
141959
142098
|
async function mergeBingAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
141960
|
-
const absDir =
|
|
142099
|
+
const absDir = path47.resolve(snapshotDir);
|
|
141961
142100
|
const metaAccountId = typeof asRecord32(payload.meta)?.accountId === "string" ? asRecord32(payload.meta)?.accountId : void 0;
|
|
141962
142101
|
const manifest = await readManifest5(snapshotDir, metaAccountId);
|
|
141963
142102
|
if (!manifest) {
|
|
@@ -142193,14 +142332,14 @@ init_report_period();
|
|
|
142193
142332
|
var TEMPLATE_BASENAME3 = "bing-period-report.html";
|
|
142194
142333
|
var INJECT_MARKER4 = "window.__BING_PERIOD_REPORT__ = window.__BING_PERIOD_REPORT__ || null;";
|
|
142195
142334
|
function resolveSkillTemplatePath6(basename13) {
|
|
142196
|
-
const dir =
|
|
142335
|
+
const dir = path48.dirname(fileURLToPath12(import.meta.url));
|
|
142197
142336
|
const candidates = [
|
|
142198
|
-
|
|
142199
|
-
|
|
142200
|
-
|
|
142337
|
+
path48.join(dir, "skill", "report-templates", basename13),
|
|
142338
|
+
path48.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
142339
|
+
path48.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
142201
142340
|
];
|
|
142202
142341
|
for (const p of candidates) {
|
|
142203
|
-
if (
|
|
142342
|
+
if (fs39.existsSync(p)) return p;
|
|
142204
142343
|
}
|
|
142205
142344
|
return candidates[0];
|
|
142206
142345
|
}
|
|
@@ -142229,10 +142368,10 @@ function injectReportData5(html, payload) {
|
|
|
142229
142368
|
return html.replace(INJECT_MARKER4, `window.__BING_PERIOD_REPORT__ = ${json};`);
|
|
142230
142369
|
}
|
|
142231
142370
|
async function runBingAnalysisRender(opts) {
|
|
142232
|
-
const dataPath =
|
|
142371
|
+
const dataPath = path48.resolve(opts.dataFile);
|
|
142233
142372
|
let data = asRecord34(await readJsonFile6(dataPath));
|
|
142234
142373
|
if (opts.snapshotDir?.trim()) {
|
|
142235
|
-
data = await mergeBingAnalysisSnapshotIntoReport(data,
|
|
142374
|
+
data = await mergeBingAnalysisSnapshotIntoReport(data, path48.resolve(opts.snapshotDir));
|
|
142236
142375
|
}
|
|
142237
142376
|
const contentCheck = validateBingPeriodReportContent(data);
|
|
142238
142377
|
if (!contentCheck.ok) {
|
|
@@ -142258,10 +142397,10 @@ async function runBingAnalysisRender(opts) {
|
|
|
142258
142397
|
`);
|
|
142259
142398
|
process.exit(1);
|
|
142260
142399
|
}
|
|
142261
|
-
const outPath =
|
|
142262
|
-
opts.out ??
|
|
142400
|
+
const outPath = path48.resolve(
|
|
142401
|
+
opts.out ?? path48.join(path48.dirname(dataPath), "bing-period-report.html")
|
|
142263
142402
|
);
|
|
142264
|
-
const outDir =
|
|
142403
|
+
const outDir = path48.dirname(outPath);
|
|
142265
142404
|
await fsPromises5.mkdir(outDir, { recursive: true });
|
|
142266
142405
|
await fsPromises5.writeFile(outPath, injectReportData5(html, data), "utf8");
|
|
142267
142406
|
const { stats } = contentCheck;
|
|
@@ -142598,7 +142737,7 @@ async function fetchTikTokInterestList(config, account, verbose) {
|
|
|
142598
142737
|
|
|
142599
142738
|
// src/commands/tiktok-analysis/run-batch.ts
|
|
142600
142739
|
init_auth();
|
|
142601
|
-
import * as
|
|
142740
|
+
import * as path49 from "path";
|
|
142602
142741
|
import { performance as performance7 } from "perf_hooks";
|
|
142603
142742
|
init_version();
|
|
142604
142743
|
async function runWithConcurrency5(tasks, concurrency) {
|
|
@@ -142673,7 +142812,7 @@ async function runAllTikTokSections(opts) {
|
|
|
142673
142812
|
const results = await runWithConcurrency5(tasks, concurrency);
|
|
142674
142813
|
const succeeded = results.filter((r) => r.ok).length;
|
|
142675
142814
|
const failed = results.length - succeeded;
|
|
142676
|
-
const absoluteSnapshotDir =
|
|
142815
|
+
const absoluteSnapshotDir = path49.resolve(opts.jsonOut);
|
|
142677
142816
|
const summary = {
|
|
142678
142817
|
kind: "siluzan-tso-tiktok-analysis-snapshot-batch",
|
|
142679
142818
|
absoluteSnapshotDir,
|
|
@@ -142696,14 +142835,14 @@ init_auth();
|
|
|
142696
142835
|
import { Command as Command4 } from "commander";
|
|
142697
142836
|
|
|
142698
142837
|
// src/commands/tiktok-analysis/render-report.ts
|
|
142699
|
-
import
|
|
142838
|
+
import fs41 from "fs";
|
|
142700
142839
|
import fsPromises6 from "fs/promises";
|
|
142701
|
-
import
|
|
142840
|
+
import path51 from "path";
|
|
142702
142841
|
import { fileURLToPath as fileURLToPath13 } from "url";
|
|
142703
142842
|
|
|
142704
142843
|
// src/commands/tiktok-analysis/merge-snapshot.ts
|
|
142705
|
-
import * as
|
|
142706
|
-
import * as
|
|
142844
|
+
import * as fs40 from "fs/promises";
|
|
142845
|
+
import * as path50 from "path";
|
|
142707
142846
|
function asRecord35(value) {
|
|
142708
142847
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
142709
142848
|
return value;
|
|
@@ -142719,7 +142858,7 @@ function round28(value) {
|
|
|
142719
142858
|
}
|
|
142720
142859
|
async function loadSectionPayload2(snapshotDir, file) {
|
|
142721
142860
|
try {
|
|
142722
|
-
const raw = await
|
|
142861
|
+
const raw = await fs40.readFile(path50.join(snapshotDir, file), "utf8");
|
|
142723
142862
|
return JSON.parse(raw);
|
|
142724
142863
|
} catch {
|
|
142725
142864
|
return null;
|
|
@@ -142729,7 +142868,7 @@ async function readManifest6(snapshotDir, accountId) {
|
|
|
142729
142868
|
const candidates = [];
|
|
142730
142869
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
142731
142870
|
try {
|
|
142732
|
-
const entries = await
|
|
142871
|
+
const entries = await fs40.readdir(snapshotDir);
|
|
142733
142872
|
const manifestNames = entries.filter(
|
|
142734
142873
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
142735
142874
|
);
|
|
@@ -142740,7 +142879,7 @@ async function readManifest6(snapshotDir, accountId) {
|
|
|
142740
142879
|
}
|
|
142741
142880
|
for (const name2 of candidates) {
|
|
142742
142881
|
try {
|
|
142743
|
-
const raw = await
|
|
142882
|
+
const raw = await fs40.readFile(path50.join(snapshotDir, name2), "utf8");
|
|
142744
142883
|
const parsed = JSON.parse(raw);
|
|
142745
142884
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
142746
142885
|
} catch {
|
|
@@ -142881,7 +143020,7 @@ function mapAudienceMerged(payload) {
|
|
|
142881
143020
|
};
|
|
142882
143021
|
}
|
|
142883
143022
|
async function mergeTikTokAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
142884
|
-
const absDir =
|
|
143023
|
+
const absDir = path50.resolve(snapshotDir);
|
|
142885
143024
|
const metaAccountId = typeof asRecord35(payload.meta)?.accountId === "string" ? asRecord35(payload.meta)?.accountId : void 0;
|
|
142886
143025
|
const manifest = await readManifest6(snapshotDir, metaAccountId);
|
|
142887
143026
|
if (!manifest) {
|
|
@@ -143092,14 +143231,14 @@ init_report_period();
|
|
|
143092
143231
|
var TEMPLATE_BASENAME4 = "tiktok-period-report.html";
|
|
143093
143232
|
var INJECT_MARKER5 = "window.__TIKTOK_PERIOD_REPORT__ = window.__TIKTOK_PERIOD_REPORT__ || null;";
|
|
143094
143233
|
function resolveSkillTemplatePath7(basename13) {
|
|
143095
|
-
const dir =
|
|
143234
|
+
const dir = path51.dirname(fileURLToPath13(import.meta.url));
|
|
143096
143235
|
const candidates = [
|
|
143097
|
-
|
|
143098
|
-
|
|
143099
|
-
|
|
143236
|
+
path51.join(dir, "skill", "report-templates", basename13),
|
|
143237
|
+
path51.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
143238
|
+
path51.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
143100
143239
|
];
|
|
143101
143240
|
for (const p of candidates) {
|
|
143102
|
-
if (
|
|
143241
|
+
if (fs41.existsSync(p)) return p;
|
|
143103
143242
|
}
|
|
143104
143243
|
return candidates[0];
|
|
143105
143244
|
}
|
|
@@ -143128,10 +143267,10 @@ function injectReportData6(html, payload) {
|
|
|
143128
143267
|
return html.replace(INJECT_MARKER5, `window.__TIKTOK_PERIOD_REPORT__ = ${json};`);
|
|
143129
143268
|
}
|
|
143130
143269
|
async function runTikTokAnalysisRender(opts) {
|
|
143131
|
-
const dataPath =
|
|
143270
|
+
const dataPath = path51.resolve(opts.dataFile);
|
|
143132
143271
|
let data = asRecord37(await readJsonFile7(dataPath));
|
|
143133
143272
|
if (opts.snapshotDir?.trim()) {
|
|
143134
|
-
data = await mergeTikTokAnalysisSnapshotIntoReport(data,
|
|
143273
|
+
data = await mergeTikTokAnalysisSnapshotIntoReport(data, path51.resolve(opts.snapshotDir));
|
|
143135
143274
|
}
|
|
143136
143275
|
const contentCheck = validateTikTokPeriodReportContent(data);
|
|
143137
143276
|
if (!contentCheck.ok) {
|
|
@@ -143157,10 +143296,10 @@ async function runTikTokAnalysisRender(opts) {
|
|
|
143157
143296
|
`);
|
|
143158
143297
|
process.exit(1);
|
|
143159
143298
|
}
|
|
143160
|
-
const outPath =
|
|
143161
|
-
opts.out ??
|
|
143299
|
+
const outPath = path51.resolve(
|
|
143300
|
+
opts.out ?? path51.join(path51.dirname(dataPath), "tiktok-period-report.html")
|
|
143162
143301
|
);
|
|
143163
|
-
const outDir =
|
|
143302
|
+
const outDir = path51.dirname(outPath);
|
|
143164
143303
|
await fsPromises6.mkdir(outDir, { recursive: true });
|
|
143165
143304
|
await fsPromises6.writeFile(outPath, injectReportData6(html, data), "utf8");
|
|
143166
143305
|
const { stats } = contentCheck;
|
|
@@ -144087,7 +144226,7 @@ var YANDEX_SECTION_ALIASES = {
|
|
|
144087
144226
|
|
|
144088
144227
|
// src/commands/yandex-analysis/run-batch.ts
|
|
144089
144228
|
init_auth();
|
|
144090
|
-
import * as
|
|
144229
|
+
import * as path53 from "path";
|
|
144091
144230
|
import { performance as performance8 } from "perf_hooks";
|
|
144092
144231
|
init_version();
|
|
144093
144232
|
|
|
@@ -144227,8 +144366,8 @@ function endpointHintForYandexSection(def) {
|
|
|
144227
144366
|
}
|
|
144228
144367
|
|
|
144229
144368
|
// src/commands/yandex-analysis/merge-snapshot.ts
|
|
144230
|
-
import * as
|
|
144231
|
-
import * as
|
|
144369
|
+
import * as fs42 from "fs/promises";
|
|
144370
|
+
import * as path52 from "path";
|
|
144232
144371
|
function asRecord38(value) {
|
|
144233
144372
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
144234
144373
|
return value;
|
|
@@ -144278,7 +144417,7 @@ function pickMetrics2(row, extras = []) {
|
|
|
144278
144417
|
}
|
|
144279
144418
|
async function loadSectionPayload3(snapshotDir, file) {
|
|
144280
144419
|
try {
|
|
144281
|
-
const raw = await
|
|
144420
|
+
const raw = await fs42.readFile(path52.join(snapshotDir, file), "utf8");
|
|
144282
144421
|
return JSON.parse(raw);
|
|
144283
144422
|
} catch {
|
|
144284
144423
|
return null;
|
|
@@ -144288,7 +144427,7 @@ async function readManifest7(snapshotDir, accountId) {
|
|
|
144288
144427
|
const candidates = [];
|
|
144289
144428
|
if (accountId) candidates.push(reportManifestFile(accountId));
|
|
144290
144429
|
try {
|
|
144291
|
-
const entries = await
|
|
144430
|
+
const entries = await fs42.readdir(snapshotDir);
|
|
144292
144431
|
for (const name2 of entries.filter(
|
|
144293
144432
|
(n) => n.startsWith("report-manifest") && n.endsWith(".json")
|
|
144294
144433
|
)) {
|
|
@@ -144298,7 +144437,7 @@ async function readManifest7(snapshotDir, accountId) {
|
|
|
144298
144437
|
}
|
|
144299
144438
|
for (const name2 of candidates) {
|
|
144300
144439
|
try {
|
|
144301
|
-
const raw = await
|
|
144440
|
+
const raw = await fs42.readFile(path52.join(snapshotDir, name2), "utf8");
|
|
144302
144441
|
const parsed = JSON.parse(raw);
|
|
144303
144442
|
if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
|
|
144304
144443
|
} catch {
|
|
@@ -144457,7 +144596,7 @@ function mapDeviceRows2(payload) {
|
|
|
144457
144596
|
return asItems(payload).map((r) => pickMetrics2(r, ["device", "network"]));
|
|
144458
144597
|
}
|
|
144459
144598
|
async function mergeYandexAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
144460
|
-
const absDir =
|
|
144599
|
+
const absDir = path52.resolve(snapshotDir);
|
|
144461
144600
|
const metaAccountId = typeof asRecord38(payload.meta)?.accountId === "string" ? asRecord38(payload.meta)?.accountId : void 0;
|
|
144462
144601
|
const manifest = await readManifest7(snapshotDir, metaAccountId);
|
|
144463
144602
|
if (!manifest) {
|
|
@@ -144643,7 +144782,7 @@ async function runAllYandexSections(opts) {
|
|
|
144643
144782
|
const results = await runWithConcurrency6(tasks, concurrency);
|
|
144644
144783
|
const succeeded = results.filter((r) => r.ok).length;
|
|
144645
144784
|
const failed = results.length - succeeded;
|
|
144646
|
-
const absoluteSnapshotDir =
|
|
144785
|
+
const absoluteSnapshotDir = path53.resolve(opts.jsonOut);
|
|
144647
144786
|
const summary = {
|
|
144648
144787
|
kind: "siluzan-tso-yandex-analysis-snapshot-batch",
|
|
144649
144788
|
absoluteSnapshotDir,
|
|
@@ -144661,9 +144800,9 @@ async function runAllYandexSections(opts) {
|
|
|
144661
144800
|
}
|
|
144662
144801
|
|
|
144663
144802
|
// src/commands/yandex-analysis/render-report.ts
|
|
144664
|
-
import
|
|
144803
|
+
import fs43 from "fs";
|
|
144665
144804
|
import fsPromises7 from "fs/promises";
|
|
144666
|
-
import
|
|
144805
|
+
import path54 from "path";
|
|
144667
144806
|
import { fileURLToPath as fileURLToPath14 } from "url";
|
|
144668
144807
|
|
|
144669
144808
|
// src/commands/yandex-analysis/report-content.ts
|
|
@@ -144868,14 +145007,14 @@ init_report_period();
|
|
|
144868
145007
|
var TEMPLATE_BASENAME5 = "yandex-period-report.html";
|
|
144869
145008
|
var INJECT_MARKER6 = "window.__YANDEX_PERIOD_REPORT__ = window.__YANDEX_PERIOD_REPORT__ || null;";
|
|
144870
145009
|
function resolveSkillTemplatePath8(basename13) {
|
|
144871
|
-
const dir =
|
|
145010
|
+
const dir = path54.dirname(fileURLToPath14(import.meta.url));
|
|
144872
145011
|
const candidates = [
|
|
144873
|
-
|
|
144874
|
-
|
|
144875
|
-
|
|
145012
|
+
path54.join(dir, "skill", "report-templates", basename13),
|
|
145013
|
+
path54.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
|
|
145014
|
+
path54.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
|
|
144876
145015
|
];
|
|
144877
145016
|
for (const p of candidates) {
|
|
144878
|
-
if (
|
|
145017
|
+
if (fs43.existsSync(p)) return p;
|
|
144879
145018
|
}
|
|
144880
145019
|
return candidates[0];
|
|
144881
145020
|
}
|
|
@@ -144917,10 +145056,10 @@ function injectReportData7(html, payload) {
|
|
|
144917
145056
|
return html.replace(INJECT_MARKER6, `window.__YANDEX_PERIOD_REPORT__ = ${json};`);
|
|
144918
145057
|
}
|
|
144919
145058
|
async function runYandexAnalysisRender(opts) {
|
|
144920
|
-
const dataPath =
|
|
145059
|
+
const dataPath = path54.resolve(opts.dataFile);
|
|
144921
145060
|
let data = asRecord40(await readJsonFile8(dataPath));
|
|
144922
145061
|
if (opts.snapshotDir?.trim()) {
|
|
144923
|
-
data = await mergeYandexAnalysisSnapshotIntoReport(data,
|
|
145062
|
+
data = await mergeYandexAnalysisSnapshotIntoReport(data, path54.resolve(opts.snapshotDir));
|
|
144924
145063
|
}
|
|
144925
145064
|
data = refreshWeeklyFromDaily(data);
|
|
144926
145065
|
const contentCheck = validateYandexPeriodReportContent(data);
|
|
@@ -144945,10 +145084,10 @@ async function runYandexAnalysisRender(opts) {
|
|
|
144945
145084
|
`);
|
|
144946
145085
|
process.exit(1);
|
|
144947
145086
|
}
|
|
144948
|
-
const outPath =
|
|
144949
|
-
opts.out ??
|
|
145087
|
+
const outPath = path54.resolve(
|
|
145088
|
+
opts.out ?? path54.join(path54.dirname(dataPath), "yandex-period-report.html")
|
|
144950
145089
|
);
|
|
144951
|
-
const outDir =
|
|
145090
|
+
const outDir = path54.dirname(outPath);
|
|
144952
145091
|
await fsPromises7.mkdir(outDir, { recursive: true });
|
|
144953
145092
|
await fsPromises7.writeFile(outPath, injectReportData7(html, data), "utf8");
|
|
144954
145093
|
const { stats } = contentCheck;
|
|
@@ -145049,13 +145188,13 @@ function optionalId(raw) {
|
|
|
145049
145188
|
function insightsLevelToPath(level) {
|
|
145050
145189
|
return level;
|
|
145051
145190
|
}
|
|
145052
|
-
function assertYandexAnalysisQuery(
|
|
145053
|
-
const caps = YANDEX_PATH_CAPS[
|
|
145191
|
+
function assertYandexAnalysisQuery(path56, query) {
|
|
145192
|
+
const caps = YANDEX_PATH_CAPS[path56];
|
|
145054
145193
|
if (query.timeIncrement != null && !caps.timeIncrement) {
|
|
145055
|
-
throw new Error(`--time-increment \u4E0D\u80FD\u7528\u4E8E /${
|
|
145194
|
+
throw new Error(`--time-increment \u4E0D\u80FD\u7528\u4E8E /${path56}\uFF08\u4EC5 campaigns / adgroups / ads\uFF09\u3002`);
|
|
145056
145195
|
}
|
|
145057
145196
|
if (query.network != null && !caps.network) {
|
|
145058
|
-
throw new Error(`--network \u4E0D\u80FD\u7528\u4E8E /${
|
|
145197
|
+
throw new Error(`--network \u4E0D\u80FD\u7528\u4E8E /${path56}\uFF08\u4EC5 campaigns / geo / devices\uFF09\u3002`);
|
|
145059
145198
|
}
|
|
145060
145199
|
if (query.status != null && !caps.status) {
|
|
145061
145200
|
throw new Error(`--status \u4EC5\u7528\u4E8E /ads\uFF08\u62D2\u5BA1/\u5BA1\u6838\u6001\u8D70\u7ED3\u6784\u67E5\u8BE2\uFF0C\u884C\u5185 spend \u4E3A 0\uFF09\u3002`);
|
|
@@ -145072,12 +145211,12 @@ function assertYandexAnalysisQuery(path55, query) {
|
|
|
145072
145211
|
);
|
|
145073
145212
|
}
|
|
145074
145213
|
if (query.limit != null && !caps.limit) {
|
|
145075
|
-
throw new Error(`--limit \u4E0D\u80FD\u7528\u4E8E /${
|
|
145214
|
+
throw new Error(`--limit \u4E0D\u80FD\u7528\u4E8E /${path56}\uFF08overview / daily / devices \u65E0\u6B64\u53C2\u6570\uFF09\u3002`);
|
|
145076
145215
|
}
|
|
145077
145216
|
}
|
|
145078
|
-
function buildYandexAnalysisSearchParams(
|
|
145079
|
-
assertYandexAnalysisQuery(
|
|
145080
|
-
const caps = YANDEX_PATH_CAPS[
|
|
145217
|
+
function buildYandexAnalysisSearchParams(path56, query) {
|
|
145218
|
+
assertYandexAnalysisQuery(path56, query);
|
|
145219
|
+
const caps = YANDEX_PATH_CAPS[path56];
|
|
145081
145220
|
const params = new URLSearchParams({
|
|
145082
145221
|
account: query.account,
|
|
145083
145222
|
start: query.start,
|
|
@@ -145103,10 +145242,10 @@ function buildYandexAnalysisSearchParams(path55, query) {
|
|
|
145103
145242
|
}
|
|
145104
145243
|
return params;
|
|
145105
145244
|
}
|
|
145106
|
-
async function fetchYandexAnalysisPath(config,
|
|
145245
|
+
async function fetchYandexAnalysisPath(config, path56, query, verbose) {
|
|
145107
145246
|
const yandexApiUrl = requireYandexApi(config);
|
|
145108
|
-
const params = buildYandexAnalysisSearchParams(
|
|
145109
|
-
const url = analysisUrl(yandexApiUrl,
|
|
145247
|
+
const params = buildYandexAnalysisSearchParams(path56, query);
|
|
145248
|
+
const url = analysisUrl(yandexApiUrl, path56, params.toString());
|
|
145110
145249
|
return apiFetch2(url, config, {}, verbose);
|
|
145111
145250
|
}
|
|
145112
145251
|
function unwrapYandexItems(raw) {
|
|
@@ -145170,13 +145309,13 @@ ${args.title}
|
|
|
145170
145309
|
console.log(` ${args.footnote}
|
|
145171
145310
|
`);
|
|
145172
145311
|
}
|
|
145173
|
-
async function fetchPath(opts,
|
|
145312
|
+
async function fetchPath(opts, path56, extra) {
|
|
145174
145313
|
const accountId = assertYandexAccountId(opts.account);
|
|
145175
145314
|
const { startDate, endDate } = resolveRange(opts.start, opts.end);
|
|
145176
145315
|
const config = loadConfig(opts.token);
|
|
145177
145316
|
const raw = await fetchYandexAnalysisPath(
|
|
145178
145317
|
config,
|
|
145179
|
-
|
|
145318
|
+
path56,
|
|
145180
145319
|
{
|
|
145181
145320
|
account: accountId,
|
|
145182
145321
|
start: startDate,
|
|
@@ -145667,9 +145806,9 @@ function interceptAgentCompatArgv(argv) {
|
|
|
145667
145806
|
installProcessHandlers();
|
|
145668
145807
|
function getVersion() {
|
|
145669
145808
|
try {
|
|
145670
|
-
const __dirname3 =
|
|
145671
|
-
const pkgPath =
|
|
145672
|
-
const pkg = JSON.parse(
|
|
145809
|
+
const __dirname3 = path55.dirname(fileURLToPath15(import.meta.url));
|
|
145810
|
+
const pkgPath = path55.join(__dirname3, "..", "package.json");
|
|
145811
|
+
const pkg = JSON.parse(fs44.readFileSync(pkgPath, "utf8"));
|
|
145673
145812
|
return pkg.version ?? "0.0.0";
|
|
145674
145813
|
} catch {
|
|
145675
145814
|
return "0.0.0";
|