pixivflow 2.16.1 → 2.18.0
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_EN.md → README.en.md} +8 -6
- package/README.md +8 -6
- package/config/examples/README.md +218 -0
- package/config/examples/multi-tag-or-limit.zh.json +49 -0
- package/config/examples/specific-download.example.json +173 -0
- package/config/examples/standalone.config.example.json +167 -0
- package/config/examples/standalone.config.novel-chinese.json +124 -0
- package/config/examples/standalone.config.ranking.json +135 -0
- package/config/examples/standalone.config.simple.json +52 -0
- package/config/examples/yesterday-popular-novel.zh.json +48 -0
- package/config/examples/yesterday-ranking-illustration.json +43 -0
- package/dist/auth/PixivAuth.d.ts +12 -0
- package/dist/auth/PixivAuth.d.ts.map +1 -1
- package/dist/auth/PixivAuth.js +26 -0
- package/dist/auth/PixivAuth.js.map +1 -1
- package/dist/batch/executionResult.d.ts +85 -0
- package/dist/batch/executionResult.d.ts.map +1 -0
- package/dist/batch/executionResult.js +102 -0
- package/dist/batch/executionResult.js.map +1 -0
- package/dist/batch/runDiagnostics.d.ts +48 -0
- package/dist/batch/runDiagnostics.d.ts.map +1 -0
- package/dist/batch/runDiagnostics.js +103 -0
- package/dist/batch/runDiagnostics.js.map +1 -0
- package/dist/commands/Command.d.ts +5 -0
- package/dist/commands/Command.d.ts.map +1 -1
- package/dist/commands/Command.js +7 -0
- package/dist/commands/Command.js.map +1 -1
- package/dist/commands/DiagnoseEgressCommand.d.ts +98 -0
- package/dist/commands/DiagnoseEgressCommand.d.ts.map +1 -0
- package/dist/commands/DiagnoseEgressCommand.js +327 -0
- package/dist/commands/DiagnoseEgressCommand.js.map +1 -0
- package/dist/commands/ExecuteSlotCommand.d.ts +37 -0
- package/dist/commands/ExecuteSlotCommand.d.ts.map +1 -0
- package/dist/commands/ExecuteSlotCommand.js +267 -0
- package/dist/commands/ExecuteSlotCommand.js.map +1 -0
- package/dist/commands/MaintainCommand.d.ts.map +1 -1
- package/dist/commands/MaintainCommand.js +10 -15
- package/dist/commands/MaintainCommand.js.map +1 -1
- package/dist/commands/index.d.ts +3 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +7 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/scheduler-runtime.d.ts +37 -1
- package/dist/commands/scheduler-runtime.d.ts.map +1 -1
- package/dist/commands/scheduler-runtime.js +52 -19
- package/dist/commands/scheduler-runtime.js.map +1 -1
- package/dist/commands/types.d.ts +6 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/config/types.d.ts +33 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/validation.d.ts +14 -1
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +109 -33
- package/dist/config/validation.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/delivery/DeliveryDispatcher.d.ts.map +1 -1
- package/dist/delivery/DeliveryDispatcher.js +7 -0
- package/dist/delivery/DeliveryDispatcher.js.map +1 -1
- package/dist/delivery/HttpMultipartDelivery.d.ts +12 -0
- package/dist/delivery/HttpMultipartDelivery.d.ts.map +1 -1
- package/dist/delivery/HttpMultipartDelivery.js +89 -70
- package/dist/delivery/HttpMultipartDelivery.js.map +1 -1
- package/dist/delivery/LegacyOutboxMigration.js +1 -1
- package/dist/delivery/LegacyOutboxMigration.js.map +1 -1
- package/dist/delivery/TelegramReviewDelivery.d.ts +49 -0
- package/dist/delivery/TelegramReviewDelivery.d.ts.map +1 -0
- package/dist/delivery/TelegramReviewDelivery.js +307 -0
- package/dist/delivery/TelegramReviewDelivery.js.map +1 -0
- package/dist/download/DownloadManager.d.ts +10 -0
- package/dist/download/DownloadManager.d.ts.map +1 -1
- package/dist/download/DownloadManager.js +21 -0
- package/dist/download/DownloadManager.js.map +1 -1
- package/dist/download/plan/DownloadPlanner.d.ts +10 -0
- package/dist/download/plan/DownloadPlanner.d.ts.map +1 -1
- package/dist/download/plan/DownloadPlanner.js +19 -0
- package/dist/download/plan/DownloadPlanner.js.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/notification/NotificationPolicy.d.ts.map +1 -1
- package/dist/notification/NotificationPolicy.js +4 -1
- package/dist/notification/NotificationPolicy.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/pixiv-token-getter-adapter.d.ts +27 -7
- package/dist/pixiv-token-getter-adapter.d.ts.map +1 -1
- package/dist/pixiv-token-getter-adapter.js +44 -27
- package/dist/pixiv-token-getter-adapter.js.map +1 -1
- package/dist/puppeteer-login-adapter/auth-code.d.ts +1 -1
- package/dist/puppeteer-login-adapter/auth-code.d.ts.map +1 -1
- package/dist/puppeteer-login-adapter/browser-launch.d.ts +21 -0
- package/dist/puppeteer-login-adapter/browser-launch.d.ts.map +1 -0
- package/dist/puppeteer-login-adapter/browser-launch.js +46 -0
- package/dist/puppeteer-login-adapter/browser-launch.js.map +1 -0
- package/dist/puppeteer-login-adapter/environment.js +2 -2
- package/dist/puppeteer-login-adapter/environment.js.map +1 -1
- package/dist/puppeteer-login-adapter/login-headless.d.ts.map +1 -1
- package/dist/puppeteer-login-adapter/login-headless.js +2 -5
- package/dist/puppeteer-login-adapter/login-headless.js.map +1 -1
- package/dist/puppeteer-login-adapter/login-interactive.d.ts.map +1 -1
- package/dist/puppeteer-login-adapter/login-interactive.js +2 -5
- package/dist/puppeteer-login-adapter/login-interactive.js.map +1 -1
- package/dist/storage/Database.d.ts +2 -0
- package/dist/storage/Database.d.ts.map +1 -1
- package/dist/storage/Database.js +7 -6
- package/dist/storage/Database.js.map +1 -1
- package/dist/storage/DatabaseMigration.d.ts +2 -2
- package/dist/storage/DatabaseMigration.d.ts.map +1 -1
- package/dist/storage/DatabaseMigration.js.map +1 -1
- package/dist/storage/drivers/NodeSqliteDriver.d.ts +14 -0
- package/dist/storage/drivers/NodeSqliteDriver.d.ts.map +1 -0
- package/dist/storage/drivers/NodeSqliteDriver.js +123 -0
- package/dist/storage/drivers/NodeSqliteDriver.js.map +1 -0
- package/dist/storage/drivers/SqliteDriver.d.ts +55 -0
- package/dist/storage/drivers/SqliteDriver.d.ts.map +1 -0
- package/dist/storage/drivers/SqliteDriver.js +21 -0
- package/dist/storage/drivers/SqliteDriver.js.map +1 -0
- package/dist/storage/repositories/BaseRepository.d.ts +4 -4
- package/dist/storage/repositories/BaseRepository.d.ts.map +1 -1
- package/dist/storage/repositories/BaseRepository.js.map +1 -1
- package/dist/storage/repositories/DownloadRepository.d.ts +2 -1
- package/dist/storage/repositories/DownloadRepository.d.ts.map +1 -1
- package/dist/storage/repositories/DownloadRepository.js.map +1 -1
- package/dist/storage/repositories/RateLimitStateRepository.d.ts +1 -1
- package/dist/storage/repositories/RateLimitStateRepository.js +1 -1
- package/dist/utils/concurrency.d.ts.map +1 -1
- package/dist/utils/concurrency.js +9 -2
- package/dist/utils/concurrency.js.map +1 -1
- package/dist/utils/config-validator-unified.d.ts.map +1 -1
- package/dist/utils/config-validator-unified.js +15 -1
- package/dist/utils/config-validator-unified.js.map +1 -1
- package/dist/utils/token-maintenance.d.ts +0 -4
- package/dist/utils/token-maintenance.d.ts.map +1 -1
- package/dist/utils/token-maintenance.js +5 -25
- package/dist/utils/token-maintenance.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/webui/package.json +1 -1
- package/node_modules/@redtidev/pixiv-client/README.en.md +105 -0
- package/node_modules/@redtidev/pixiv-client/README.md +67 -73
- package/node_modules/@redtidev/pixiv-client/dist/rate-limit/RateLimitGate.d.ts +1 -1
- package/node_modules/@redtidev/pixiv-client/dist/rate-limit/RateLimitGate.js +1 -1
- package/node_modules/@redtidev/pixiv-client/src/rate-limit/RateLimitGate.ts +1 -1
- package/package.json +7 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PixivAuth.js","sourceRoot":"","sources":["../../src/auth/PixivAuth.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"PixivAuth.js","sourceRoot":"","sources":["../../src/auth/PixivAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine-readable result of one batch execution.
|
|
3
|
+
*
|
|
4
|
+
* The batch runner is a disposable CI job: it cannot leave its state behind in a
|
|
5
|
+
* process, so its *only* handoff is this document. Everything a control plane
|
|
6
|
+
* needs to roll the occurrence up — and everything a human needs to debug a
|
|
7
|
+
* night's failure — has to be in here.
|
|
8
|
+
*
|
|
9
|
+
* Two rules the shape enforces:
|
|
10
|
+
* - a target that produced NO outcome is reported as `missing`, never omitted and
|
|
11
|
+
* never assumed successful;
|
|
12
|
+
* - the exit code IS the execution status (0 success / 2 partial / 3 failed /
|
|
13
|
+
* 4 uncertain), so a supervisor that only reads the exit code still cannot
|
|
14
|
+
* mistake "some targets failed" for "everything worked".
|
|
15
|
+
*/
|
|
16
|
+
import type { TargetOutcome } from '../scheduler/TargetOutcome';
|
|
17
|
+
export type BatchTargetStatus = 'submitted' | 'stored' | 'delivery_pending' | 'no_candidate' | 'duplicate' | 'failed'
|
|
18
|
+
/** The run produced no outcome for this target at all (aborted mid-way). */
|
|
19
|
+
| 'missing';
|
|
20
|
+
export type BatchExecutionStatus = 'success' | 'partial' | 'failed' | 'uncertain';
|
|
21
|
+
export interface BatchTargetResult {
|
|
22
|
+
targetId: string;
|
|
23
|
+
status: BatchTargetStatus;
|
|
24
|
+
workId?: string;
|
|
25
|
+
error?: string;
|
|
26
|
+
/** Only meaningful for `failed`: a later attempt may still succeed. */
|
|
27
|
+
retryable?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface BatchOutboxSummary {
|
|
30
|
+
processed: number;
|
|
31
|
+
done: number;
|
|
32
|
+
retried: number;
|
|
33
|
+
dead: number;
|
|
34
|
+
}
|
|
35
|
+
export interface BatchExecutionResult {
|
|
36
|
+
slotId: string;
|
|
37
|
+
scheduleId: string;
|
|
38
|
+
botId?: string;
|
|
39
|
+
attempt: number;
|
|
40
|
+
mode: 'live' | 'shadow' | 'dry-run';
|
|
41
|
+
occurrenceAt?: number;
|
|
42
|
+
status: BatchExecutionStatus;
|
|
43
|
+
exitCode: number;
|
|
44
|
+
startedAt: string;
|
|
45
|
+
finishedAt: string;
|
|
46
|
+
durationMs: number;
|
|
47
|
+
targets: BatchTargetResult[];
|
|
48
|
+
outbox?: BatchOutboxSummary;
|
|
49
|
+
/** Process-level failure (config, auth, crash): not a per-target outcome. */
|
|
50
|
+
error?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The category that best explains a failed run, and the server's own cooldown
|
|
53
|
+
* hint when it gave one.
|
|
54
|
+
*
|
|
55
|
+
* The control plane needs these to choose a retry delay: a rate-limited account
|
|
56
|
+
* should wait for the server, while a broken provider should not be retried on the
|
|
57
|
+
* same schedule. Exit codes alone cannot express that difference.
|
|
58
|
+
*/
|
|
59
|
+
errorClass?: string;
|
|
60
|
+
retryAfterMs?: number | null;
|
|
61
|
+
/** How many Pixiv 429s this run observed; 0 or absent means none. */
|
|
62
|
+
rateLimitHits?: number;
|
|
63
|
+
}
|
|
64
|
+
export declare const EXIT_SUCCESS = 0;
|
|
65
|
+
export declare const EXIT_ERROR = 1;
|
|
66
|
+
export declare const EXIT_PARTIAL = 2;
|
|
67
|
+
export declare const EXIT_FAILED = 3;
|
|
68
|
+
export declare const EXIT_UNCERTAIN = 4;
|
|
69
|
+
export declare function outcomeToTargetResult(targetId: string, outcome: TargetOutcome): BatchTargetResult;
|
|
70
|
+
export interface ExecutionSummary {
|
|
71
|
+
status: BatchExecutionStatus;
|
|
72
|
+
exitCode: number;
|
|
73
|
+
targets: BatchTargetResult[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Combine per-target results into the execution's status.
|
|
77
|
+
*
|
|
78
|
+
* `expectedTargetIds` is what makes this honest: a target that never reported is
|
|
79
|
+
* added as `missing` instead of being dropped, so a run that died halfway cannot
|
|
80
|
+
* come out as `success`.
|
|
81
|
+
*/
|
|
82
|
+
export declare function summarizeExecution(results: readonly BatchTargetResult[], expectedTargetIds: readonly string[]): ExecutionSummary;
|
|
83
|
+
/** Exit code → execution status, the contract the control plane relies on. */
|
|
84
|
+
export declare function executionStatusForExitCode(exitCode: number): BatchExecutionStatus;
|
|
85
|
+
//# sourceMappingURL=executionResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executionResult.d.ts","sourceRoot":"","sources":["../../src/batch/executionResult.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,QAAQ,GACR,kBAAkB,GAClB,cAAc,GACd,WAAW,GACX,QAAQ;AACV,4EAA4E;GAC1E,SAAS,CAAC;AAEd,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,cAAc,IAAI,CAAC;AAKhC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,iBAAiB,CAoBjG;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,iBAAiB,EAAE,SAAS,MAAM,EAAE,GACnC,gBAAgB,CAmClB;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAWjF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Machine-readable result of one batch execution.
|
|
4
|
+
*
|
|
5
|
+
* The batch runner is a disposable CI job: it cannot leave its state behind in a
|
|
6
|
+
* process, so its *only* handoff is this document. Everything a control plane
|
|
7
|
+
* needs to roll the occurrence up — and everything a human needs to debug a
|
|
8
|
+
* night's failure — has to be in here.
|
|
9
|
+
*
|
|
10
|
+
* Two rules the shape enforces:
|
|
11
|
+
* - a target that produced NO outcome is reported as `missing`, never omitted and
|
|
12
|
+
* never assumed successful;
|
|
13
|
+
* - the exit code IS the execution status (0 success / 2 partial / 3 failed /
|
|
14
|
+
* 4 uncertain), so a supervisor that only reads the exit code still cannot
|
|
15
|
+
* mistake "some targets failed" for "everything worked".
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.EXIT_UNCERTAIN = exports.EXIT_FAILED = exports.EXIT_PARTIAL = exports.EXIT_ERROR = exports.EXIT_SUCCESS = void 0;
|
|
19
|
+
exports.outcomeToTargetResult = outcomeToTargetResult;
|
|
20
|
+
exports.summarizeExecution = summarizeExecution;
|
|
21
|
+
exports.executionStatusForExitCode = executionStatusForExitCode;
|
|
22
|
+
exports.EXIT_SUCCESS = 0;
|
|
23
|
+
exports.EXIT_ERROR = 1;
|
|
24
|
+
exports.EXIT_PARTIAL = 2;
|
|
25
|
+
exports.EXIT_FAILED = 3;
|
|
26
|
+
exports.EXIT_UNCERTAIN = 4;
|
|
27
|
+
/** Outcomes that mean "this target is done and content went somewhere". */
|
|
28
|
+
const OK_STATUSES = ['submitted', 'stored', 'duplicate'];
|
|
29
|
+
function outcomeToTargetResult(targetId, outcome) {
|
|
30
|
+
switch (outcome.kind) {
|
|
31
|
+
case 'submitted':
|
|
32
|
+
return { targetId, status: 'submitted', workId: outcome.workId };
|
|
33
|
+
case 'stored':
|
|
34
|
+
return { targetId, status: 'stored', workId: outcome.workId };
|
|
35
|
+
case 'delivery_pending':
|
|
36
|
+
return { targetId, status: 'delivery_pending', workId: outcome.workId };
|
|
37
|
+
case 'duplicate':
|
|
38
|
+
return { targetId, status: 'duplicate', workId: outcome.workId, error: outcome.reason };
|
|
39
|
+
case 'no_candidate':
|
|
40
|
+
return { targetId, status: 'no_candidate', error: outcome.reason };
|
|
41
|
+
case 'failed':
|
|
42
|
+
return {
|
|
43
|
+
targetId,
|
|
44
|
+
status: 'failed',
|
|
45
|
+
error: outcome.error,
|
|
46
|
+
retryable: outcome.retryable,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Combine per-target results into the execution's status.
|
|
52
|
+
*
|
|
53
|
+
* `expectedTargetIds` is what makes this honest: a target that never reported is
|
|
54
|
+
* added as `missing` instead of being dropped, so a run that died halfway cannot
|
|
55
|
+
* come out as `success`.
|
|
56
|
+
*/
|
|
57
|
+
function summarizeExecution(results, expectedTargetIds) {
|
|
58
|
+
const byTarget = new Map(results.map((result) => [result.targetId, result]));
|
|
59
|
+
const targets = expectedTargetIds.map((targetId) => byTarget.get(targetId) ?? {
|
|
60
|
+
targetId,
|
|
61
|
+
status: 'missing',
|
|
62
|
+
error: 'no outcome was produced for this target',
|
|
63
|
+
});
|
|
64
|
+
for (const result of results) {
|
|
65
|
+
if (!expectedTargetIds.includes(result.targetId))
|
|
66
|
+
targets.push(result);
|
|
67
|
+
}
|
|
68
|
+
const ok = targets.filter((target) => OK_STATUSES.includes(target.status));
|
|
69
|
+
const uncertain = targets.filter((target) => target.status === 'delivery_pending');
|
|
70
|
+
if (uncertain.length > 0) {
|
|
71
|
+
// An unconfirmed Telegram send must never be retried automatically: the
|
|
72
|
+
// control plane treats this as terminal and a human resolves it.
|
|
73
|
+
return { status: 'uncertain', exitCode: exports.EXIT_UNCERTAIN, targets };
|
|
74
|
+
}
|
|
75
|
+
if (targets.length === 0) {
|
|
76
|
+
return { status: 'failed', exitCode: exports.EXIT_FAILED, targets };
|
|
77
|
+
}
|
|
78
|
+
if (ok.length === targets.length) {
|
|
79
|
+
return { status: 'success', exitCode: exports.EXIT_SUCCESS, targets };
|
|
80
|
+
}
|
|
81
|
+
if (ok.length === 0) {
|
|
82
|
+
// Nothing was delivered. All-empty-candidates is a business outcome (retrying
|
|
83
|
+
// the same day rarely helps) but it is still "nothing published", not success.
|
|
84
|
+
const allNoCandidate = targets.every((target) => target.status === 'no_candidate');
|
|
85
|
+
return { status: allNoCandidate ? 'partial' : 'failed', exitCode: allNoCandidate ? exports.EXIT_PARTIAL : exports.EXIT_FAILED, targets };
|
|
86
|
+
}
|
|
87
|
+
return { status: 'partial', exitCode: exports.EXIT_PARTIAL, targets };
|
|
88
|
+
}
|
|
89
|
+
/** Exit code → execution status, the contract the control plane relies on. */
|
|
90
|
+
function executionStatusForExitCode(exitCode) {
|
|
91
|
+
switch (exitCode) {
|
|
92
|
+
case exports.EXIT_SUCCESS:
|
|
93
|
+
return 'success';
|
|
94
|
+
case exports.EXIT_PARTIAL:
|
|
95
|
+
return 'partial';
|
|
96
|
+
case exports.EXIT_UNCERTAIN:
|
|
97
|
+
return 'uncertain';
|
|
98
|
+
default:
|
|
99
|
+
return 'failed';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=executionResult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executionResult.js","sourceRoot":"","sources":["../../src/batch/executionResult.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-scoped diagnostics for the business errors a batch execution hits.
|
|
3
|
+
*
|
|
4
|
+
* The control plane needs to tell a rate-limited run apart from a broken one: they
|
|
5
|
+
* share an exit code but not a remedy. A batch runner has no daemon behind it, so
|
|
6
|
+
* the only way that distinction survives is if this process records it and the
|
|
7
|
+
* result file carries it back.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately module-level and reset per run: the runner is a fresh process each
|
|
10
|
+
* time, and a long-lived caller (tests, the scheduler) must not inherit counts.
|
|
11
|
+
*/
|
|
12
|
+
/** Stable categories the control plane understands. */
|
|
13
|
+
export type RunErrorCategory = 'pixiv_rate_limit' | 'network_timeout' | 'download_failed' | 'provider_error' | 'internal_error';
|
|
14
|
+
export interface RunDiagnostics {
|
|
15
|
+
categories: Partial<Record<RunErrorCategory, number>>;
|
|
16
|
+
/** How many times a Pixiv 429 was observed. */
|
|
17
|
+
rateLimitHits: number;
|
|
18
|
+
/** The longest cooldown the server asked for, if it said. */
|
|
19
|
+
maxRetryAfterMs: number | null;
|
|
20
|
+
/** The category that best explains a failed run, if any. */
|
|
21
|
+
dominantCategory: RunErrorCategory | null;
|
|
22
|
+
}
|
|
23
|
+
/** Called at the start of a run so counts cannot leak between runs. */
|
|
24
|
+
export declare function resetRunDiagnostics(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Record one observed Pixiv rate limit.
|
|
27
|
+
*
|
|
28
|
+
* `waitMs` is the server's own hint when it provided one (Retry-After); the longest
|
|
29
|
+
* hint seen during the run is what the report carries, because it is the one that
|
|
30
|
+
* governs when this account may be used again.
|
|
31
|
+
*/
|
|
32
|
+
export declare function recordRateLimit(waitMs?: number): void;
|
|
33
|
+
/**
|
|
34
|
+
* Classify a failure message into a category.
|
|
35
|
+
*
|
|
36
|
+
* Message matching is the fallback, not the primary mechanism: the Pixiv client
|
|
37
|
+
* raises typed errors and the paths that see them call `recordRateLimit` directly.
|
|
38
|
+
* This exists for the places where only a string survives, and it is intentionally
|
|
39
|
+
* narrower than a generic "is this retryable" test — the point is to keep a rate
|
|
40
|
+
* limit from being confused with a broken provider.
|
|
41
|
+
*/
|
|
42
|
+
export declare function classifyRunError(message: string): RunErrorCategory;
|
|
43
|
+
/** Record a failure the run actually hit, from its message. */
|
|
44
|
+
export declare function recordRunError(message: string): RunErrorCategory;
|
|
45
|
+
/** Record an explicit category (used where the caller already knows it). */
|
|
46
|
+
export declare function recordRunCategory(category: RunErrorCategory): void;
|
|
47
|
+
export declare function runDiagnostics(): RunDiagnostics;
|
|
48
|
+
//# sourceMappingURL=runDiagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runDiagnostics.d.ts","sourceRoot":"","sources":["../../src/batch/runDiagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GACxB,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,4DAA4D;IAC5D,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC3C;AAWD,uEAAuE;AACvE,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAMrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAOlE;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAShE;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAKlE;AAED,wBAAgB,cAAc,IAAI,cAAc,CAiB/C"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Run-scoped diagnostics for the business errors a batch execution hits.
|
|
4
|
+
*
|
|
5
|
+
* The control plane needs to tell a rate-limited run apart from a broken one: they
|
|
6
|
+
* share an exit code but not a remedy. A batch runner has no daemon behind it, so
|
|
7
|
+
* the only way that distinction survives is if this process records it and the
|
|
8
|
+
* result file carries it back.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately module-level and reset per run: the runner is a fresh process each
|
|
11
|
+
* time, and a long-lived caller (tests, the scheduler) must not inherit counts.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.resetRunDiagnostics = resetRunDiagnostics;
|
|
15
|
+
exports.recordRateLimit = recordRateLimit;
|
|
16
|
+
exports.classifyRunError = classifyRunError;
|
|
17
|
+
exports.recordRunError = recordRunError;
|
|
18
|
+
exports.recordRunCategory = recordRunCategory;
|
|
19
|
+
exports.runDiagnostics = runDiagnostics;
|
|
20
|
+
const empty = () => ({
|
|
21
|
+
categories: {},
|
|
22
|
+
rateLimitHits: 0,
|
|
23
|
+
maxRetryAfterMs: null,
|
|
24
|
+
dominantCategory: null,
|
|
25
|
+
});
|
|
26
|
+
let state = empty();
|
|
27
|
+
/** Called at the start of a run so counts cannot leak between runs. */
|
|
28
|
+
function resetRunDiagnostics() {
|
|
29
|
+
state = empty();
|
|
30
|
+
}
|
|
31
|
+
function record(category) {
|
|
32
|
+
state.categories[category] = (state.categories[category] ?? 0) + 1;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Record one observed Pixiv rate limit.
|
|
36
|
+
*
|
|
37
|
+
* `waitMs` is the server's own hint when it provided one (Retry-After); the longest
|
|
38
|
+
* hint seen during the run is what the report carries, because it is the one that
|
|
39
|
+
* governs when this account may be used again.
|
|
40
|
+
*/
|
|
41
|
+
function recordRateLimit(waitMs) {
|
|
42
|
+
state.rateLimitHits += 1;
|
|
43
|
+
if (typeof waitMs === 'number' && Number.isFinite(waitMs) && waitMs > 0) {
|
|
44
|
+
state.maxRetryAfterMs = Math.max(state.maxRetryAfterMs ?? 0, waitMs);
|
|
45
|
+
}
|
|
46
|
+
record('pixiv_rate_limit');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Classify a failure message into a category.
|
|
50
|
+
*
|
|
51
|
+
* Message matching is the fallback, not the primary mechanism: the Pixiv client
|
|
52
|
+
* raises typed errors and the paths that see them call `recordRateLimit` directly.
|
|
53
|
+
* This exists for the places where only a string survives, and it is intentionally
|
|
54
|
+
* narrower than a generic "is this retryable" test — the point is to keep a rate
|
|
55
|
+
* limit from being confused with a broken provider.
|
|
56
|
+
*/
|
|
57
|
+
function classifyRunError(message) {
|
|
58
|
+
if (/\b429\b|rate.?limit|too many requests|cooldown/i.test(message))
|
|
59
|
+
return 'pixiv_rate_limit';
|
|
60
|
+
if (/timeout|timed out|abort|econnreset|econnrefused|enotfound|socket hang up/i.test(message)) {
|
|
61
|
+
return 'network_timeout';
|
|
62
|
+
}
|
|
63
|
+
if (/download|file|write|disk|enospc/i.test(message))
|
|
64
|
+
return 'download_failed';
|
|
65
|
+
return 'internal_error';
|
|
66
|
+
}
|
|
67
|
+
/** Record a failure the run actually hit, from its message. */
|
|
68
|
+
function recordRunError(message) {
|
|
69
|
+
const category = classifyRunError(message);
|
|
70
|
+
if (category === 'pixiv_rate_limit') {
|
|
71
|
+
state.rateLimitHits += 1;
|
|
72
|
+
record(category);
|
|
73
|
+
return category;
|
|
74
|
+
}
|
|
75
|
+
record(category);
|
|
76
|
+
return category;
|
|
77
|
+
}
|
|
78
|
+
/** Record an explicit category (used where the caller already knows it). */
|
|
79
|
+
function recordRunCategory(category) {
|
|
80
|
+
if (category === 'pixiv_rate_limit') {
|
|
81
|
+
state.rateLimitHits += 1;
|
|
82
|
+
}
|
|
83
|
+
record(category);
|
|
84
|
+
}
|
|
85
|
+
function runDiagnostics() {
|
|
86
|
+
const rank = [
|
|
87
|
+
'pixiv_rate_limit',
|
|
88
|
+
'network_timeout',
|
|
89
|
+
'download_failed',
|
|
90
|
+
'provider_error',
|
|
91
|
+
'internal_error',
|
|
92
|
+
];
|
|
93
|
+
// A rate limit outranks everything: it is the one category with a server-provided
|
|
94
|
+
// remedy, and reporting it as "internal_error" would hide that.
|
|
95
|
+
const dominant = rank.find((category) => (state.categories[category] ?? 0) > 0) ?? null;
|
|
96
|
+
return {
|
|
97
|
+
categories: { ...state.categories },
|
|
98
|
+
rateLimitHits: state.rateLimitHits,
|
|
99
|
+
maxRetryAfterMs: state.maxRetryAfterMs,
|
|
100
|
+
dominantCategory: dominant,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=runDiagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runDiagnostics.js","sourceRoot":"","sources":["../../src/batch/runDiagnostics.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AA8BH,kDAEC;AAaD,0CAMC;AAWD,4CAOC;AAGD,wCASC;AAGD,8CAKC;AAED,wCAiBC;AAxFD,MAAM,KAAK,GAAG,GAAmB,EAAE,CAAC,CAAC;IACnC,UAAU,EAAE,EAAE;IACd,aAAa,EAAE,CAAC;IAChB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;CACvB,CAAC,CAAC;AAEH,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;AAEpB,uEAAuE;AACvE,SAAgB,mBAAmB;IACjC,KAAK,GAAG,KAAK,EAAE,CAAC;AAClB,CAAC;AAED,SAAS,MAAM,CAAC,QAA0B;IACxC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,MAAe;IAC7C,KAAK,CAAC,aAAa,IAAI,CAAC,CAAC;IACzB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACxE,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,IAAI,iDAAiD,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAC/F,IAAI,2EAA2E,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9F,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IACD,IAAI,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAC/E,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,+DAA+D;AAC/D,SAAgB,cAAc,CAAC,OAAe;IAC5C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QACpC,KAAK,CAAC,aAAa,IAAI,CAAC,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjB,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,4EAA4E;AAC5E,SAAgB,iBAAiB,CAAC,QAA0B;IAC1D,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QACpC,KAAK,CAAC,aAAa,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,CAAC,QAAQ,CAAC,CAAC;AACnB,CAAC;AAED,SAAgB,cAAc;IAC5B,MAAM,IAAI,GAAuB;QAC/B,kBAAkB;QAClB,iBAAiB;QACjB,iBAAiB;QACjB,gBAAgB;QAChB,gBAAgB;KACjB,CAAC;IACF,kFAAkF;IAClF,gEAAgE;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;IACxF,OAAO;QACL,UAAU,EAAE,EAAE,GAAG,KAAK,CAAC,UAAU,EAAE;QACnC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,gBAAgB,EAAE,QAAQ;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -67,6 +67,11 @@ export declare abstract class BaseCommand implements Command {
|
|
|
67
67
|
* Create a failure result
|
|
68
68
|
*/
|
|
69
69
|
protected failure(error: Error | string, data?: unknown): CommandResult;
|
|
70
|
+
/**
|
|
71
|
+
* Attach an explicit process exit code (batch/CI commands: a partial run and a
|
|
72
|
+
* failed run are different outcomes for a supervisor).
|
|
73
|
+
*/
|
|
74
|
+
protected withExitCode(result: CommandResult, exitCode: number): CommandResult;
|
|
70
75
|
/**
|
|
71
76
|
* Check if command name or alias matches
|
|
72
77
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.d.ts","sourceRoot":"","sources":["../../src/commands/Command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,eAAe,EAAoB,MAAM,YAAY,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAE5E;;;;OAIG;IACH,QAAQ,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB,CAAC;IAE/C;;;OAGG;IACH,QAAQ,CAAC,IAAI,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,8BAAsB,WAAY,YAAW,OAAO;IAClD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAQ;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAEpC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAEpF,QAAQ,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB;IAI9C,QAAQ,CAAC,IAAI,MAAM;IAInB;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,aAAa;IAIlE;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,aAAa;IAKvE;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAU9B;;OAEG;IACH,WAAW,IAAI,eAAe;CAG/B"}
|
|
1
|
+
{"version":3,"file":"Command.d.ts","sourceRoot":"","sources":["../../src/commands/Command.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,eAAe,EAAoB,MAAM,YAAY,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAE5E;;;;OAIG;IACH,QAAQ,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB,CAAC;IAE/C;;;OAGG;IACH,QAAQ,CAAC,IAAI,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,8BAAsB,WAAY,YAAW,OAAO;IAClD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAQ;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAEpC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAEpF,QAAQ,CAAC,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB;IAI9C,QAAQ,CAAC,IAAI,MAAM;IAInB;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,aAAa;IAIlE;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,aAAa;IAKvE;;;OAGG;IACH,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa;IAI9E;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAU9B;;OAEG;IACH,WAAW,IAAI,eAAe;CAG/B"}
|
package/dist/commands/Command.js
CHANGED
|
@@ -31,6 +31,13 @@ class BaseCommand {
|
|
|
31
31
|
const errorObj = error instanceof Error ? error : new Error(error);
|
|
32
32
|
return { success: false, error: errorObj, data };
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Attach an explicit process exit code (batch/CI commands: a partial run and a
|
|
36
|
+
* failed run are different outcomes for a supervisor).
|
|
37
|
+
*/
|
|
38
|
+
withExitCode(result, exitCode) {
|
|
39
|
+
return { ...result, exitCode };
|
|
40
|
+
}
|
|
34
41
|
/**
|
|
35
42
|
* Check if command name or alias matches
|
|
36
43
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Command.js","sourceRoot":"","sources":["../../src/commands/Command.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAGH,yCAA+D;AAsD/D;;GAEG;AACH,MAAsB,WAAW;IAGtB,OAAO,CAAY;IACnB,aAAa,GAAY,IAAI,CAAC;IAC9B,QAAQ,CAAmB;IAIpC,QAAQ,CAAE,IAAiB;QACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,OAAgB,EAAE,IAAc;QAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,KAAqB,EAAE,IAAc;QACrD,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;QACnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAY;QAClB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,IAAI,2BAAgB,CAAC;IAC3C,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"Command.js","sourceRoot":"","sources":["../../src/commands/Command.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAGH,yCAA+D;AAsD/D;;GAEG;AACH,MAAsB,WAAW;IAGtB,OAAO,CAAY;IACnB,aAAa,GAAY,IAAI,CAAC;IAC9B,QAAQ,CAAmB;IAIpC,QAAQ,CAAE,IAAiB;QACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,OAAgB,EAAE,IAAc;QAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,KAAqB,EAAE,IAAc;QACrD,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;QACnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IAED;;;OAGG;IACO,YAAY,CAAC,MAAqB,EAAE,QAAgB;QAC5D,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAY;QAClB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,IAAI,2BAAgB,CAAC;IAC3C,CAAC;CACF;AA3DD,kCA2DC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `pixivflow diagnose egress` — minimal Pixiv data-plane egress probe.
|
|
3
|
+
*
|
|
4
|
+
* Reachability is not suitability: a datacenter egress can pass OAuth and still be
|
|
5
|
+
* rate-limit-starved on the production search workload (2026-09-11, GitHub-hosted
|
|
6
|
+
* runners). This command answers, with a handful of tiny requests, three INDEPENDENT
|
|
7
|
+
* questions about the network it runs on:
|
|
8
|
+
*
|
|
9
|
+
* 1. OAuth oauth.secure.pixiv.net — one real refresh-token exchange
|
|
10
|
+
* 2. App API app-api.pixiv.net — 1 small fixed request, status + Retry-After
|
|
11
|
+
* 3. Media i.pximg.net — 64 KiB Range request with the app Referer
|
|
12
|
+
*
|
|
13
|
+
* It never runs the business workload (no 12 tags / 100 samples / pagination), so it
|
|
14
|
+
* cannot by itself drive the account into a penalty. Output is a findings list plus a
|
|
15
|
+
* uniform verdict (PASS / DEGRADED / FAIL) suitable for a provider-qualification matrix.
|
|
16
|
+
*
|
|
17
|
+
* Exit codes: 0 = no findings above warn, 1 = warn (degraded evidence), 2 = critical
|
|
18
|
+
* (a data plane is unusable from this egress).
|
|
19
|
+
*
|
|
20
|
+
* The OAuth probe performs ONE real token refresh. PixivAuth persists a rotated refresh
|
|
21
|
+
* token (database + unified storage + config), which is the desired durable behaviour —
|
|
22
|
+
* run this probe only when no production execution holds the credential, exactly like
|
|
23
|
+
* `account rotate`.
|
|
24
|
+
*/
|
|
25
|
+
import { BaseCommand } from './Command';
|
|
26
|
+
import { CommandCategory } from './metadata';
|
|
27
|
+
import { CommandArgs, CommandContext, CommandResult } from './types';
|
|
28
|
+
type FindingLevel = 'ok' | 'warn' | 'critical' | 'skipped';
|
|
29
|
+
interface Finding {
|
|
30
|
+
level: FindingLevel;
|
|
31
|
+
code: string;
|
|
32
|
+
message: string;
|
|
33
|
+
data?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
export type EgressVerdict = 'PASS' | 'DEGRADED' | 'FAIL' | 'INCOMPLETE';
|
|
36
|
+
export interface EgressProbeSummary {
|
|
37
|
+
provider: string;
|
|
38
|
+
region: string;
|
|
39
|
+
network: string;
|
|
40
|
+
oauth: {
|
|
41
|
+
status: string;
|
|
42
|
+
latencyMs: number | null;
|
|
43
|
+
refreshed: boolean;
|
|
44
|
+
};
|
|
45
|
+
appApi: {
|
|
46
|
+
status: number | null;
|
|
47
|
+
ttfbMs: number | null;
|
|
48
|
+
durationMs: number | null;
|
|
49
|
+
rateLimited: boolean;
|
|
50
|
+
retryAfterMs: number | null;
|
|
51
|
+
};
|
|
52
|
+
media: {
|
|
53
|
+
status: number | null;
|
|
54
|
+
ttfbMs: number | null;
|
|
55
|
+
bytes64kDurationMs: number | null;
|
|
56
|
+
timedOut: boolean;
|
|
57
|
+
};
|
|
58
|
+
verdict: EgressVerdict;
|
|
59
|
+
incomplete: boolean;
|
|
60
|
+
findings: Finding[];
|
|
61
|
+
}
|
|
62
|
+
export declare class DiagnoseEgressCommand extends BaseCommand {
|
|
63
|
+
/** Injectable for tests; defaults to a this-safe global fetch. */
|
|
64
|
+
private readonly deps;
|
|
65
|
+
readonly name = "diagnose";
|
|
66
|
+
readonly description = "Minimal Pixiv data-plane egress probe (usage: diagnose egress)";
|
|
67
|
+
readonly aliases: string[];
|
|
68
|
+
readonly requiresToken = false;
|
|
69
|
+
readonly metadata: {
|
|
70
|
+
category: CommandCategory;
|
|
71
|
+
requiresAuth: boolean;
|
|
72
|
+
longRunning: boolean;
|
|
73
|
+
examples: string[];
|
|
74
|
+
relatedCommands: string[];
|
|
75
|
+
};
|
|
76
|
+
constructor(
|
|
77
|
+
/** Injectable for tests; defaults to a this-safe global fetch. */
|
|
78
|
+
deps?: {
|
|
79
|
+
fetchImpl?: typeof fetch;
|
|
80
|
+
provider?: string;
|
|
81
|
+
region?: string;
|
|
82
|
+
});
|
|
83
|
+
getUsage(): string;
|
|
84
|
+
execute(context: CommandContext, args: CommandArgs): Promise<CommandResult>;
|
|
85
|
+
/** pixiv.net answers 403 to anonymous probes; any HTTP response proves reachability. */
|
|
86
|
+
private probeReachable;
|
|
87
|
+
/**
|
|
88
|
+
* One small App API request. Any HTTP response proves the data plane is reachable;
|
|
89
|
+
* 429 is the starvation signal this probe exists to surface.
|
|
90
|
+
*/
|
|
91
|
+
private probeAppApi;
|
|
92
|
+
/** 64 KiB Range request — never a full media download. */
|
|
93
|
+
private probeMedia;
|
|
94
|
+
private summarize;
|
|
95
|
+
private print;
|
|
96
|
+
}
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=DiagnoseEgressCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnoseEgressCommand.d.ts","sourceRoot":"","sources":["../../src/commands/DiagnoseEgressCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMrE,KAAK,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAE3D,UAAU,OAAO;IACf,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,YAAY,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IACxE,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACvI,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9G,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAaD,qBAAa,qBAAsB,SAAQ,WAAW;IAclD,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI;IAdvB,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,oEAAoE;IACxF,QAAQ,CAAC,OAAO,WAAY;IAC5B,QAAQ,CAAC,aAAa,SAAS;IAC/B,QAAQ,CAAC,QAAQ;;;;;;MAMf;;IAGA,kEAAkE;IACjD,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAK9F,QAAQ,IAAI,MAAM;IAQZ,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IA4FjF,wFAAwF;YAC1E,cAAc;IAoC5B;;;OAGG;YACW,WAAW;IA4DzB,0DAA0D;YAC5C,UAAU;IA4CxB,OAAO,CAAC,SAAS;IAmCjB,OAAO,CAAC,KAAK;CAed"}
|