@jeffusion/bungee-core 6.8.2 → 6.10.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/dist/config-storage-worker.js +38 -6
- package/dist/main.js +195 -83
- package/dist/observability-worker.js +36 -4
- package/dist/plugins/chatgpt-oauth/control.js +69 -22
- package/dist/plugins/chatgpt-oauth/control.js.map +5 -5
- package/dist/plugins/chatgpt-oauth/manifest.json +100 -17
- package/dist/plugins/chatgpt-oauth/ui/AccountsPage.svelte +137 -69
- package/dist/plugins/chatgpt-oauth/ui/account-model.js +36 -2
- package/package.json +2 -2
|
@@ -15214,6 +15214,7 @@ class LogQueryService {
|
|
|
15214
15214
|
transformer,
|
|
15215
15215
|
success,
|
|
15216
15216
|
transportOutcome,
|
|
15217
|
+
transportType,
|
|
15217
15218
|
searchTerm,
|
|
15218
15219
|
requestType,
|
|
15219
15220
|
sortBy = "timestamp",
|
|
@@ -15229,6 +15230,12 @@ class LogQueryService {
|
|
|
15229
15230
|
whereClauses.push("timestamp < ?");
|
|
15230
15231
|
whereParams.push(endTime);
|
|
15231
15232
|
}
|
|
15233
|
+
if (transportType !== undefined) {
|
|
15234
|
+
if (transportType !== "http" && transportType !== "websocket")
|
|
15235
|
+
throw new Error("Invalid transport type");
|
|
15236
|
+
whereClauses.push("transport_type = ?");
|
|
15237
|
+
whereParams.push(transportType);
|
|
15238
|
+
}
|
|
15232
15239
|
if (method) {
|
|
15233
15240
|
whereClauses.push("method = ?");
|
|
15234
15241
|
whereParams.push(method);
|
|
@@ -15330,6 +15337,7 @@ class LogQueryService {
|
|
|
15330
15337
|
transformer,
|
|
15331
15338
|
success,
|
|
15332
15339
|
transportOutcome,
|
|
15340
|
+
transportType,
|
|
15333
15341
|
searchTerm,
|
|
15334
15342
|
requestType,
|
|
15335
15343
|
sortBy = "timestamp",
|
|
@@ -15342,6 +15350,12 @@ class LogQueryService {
|
|
|
15342
15350
|
} = params;
|
|
15343
15351
|
const rowWhereClauses = [];
|
|
15344
15352
|
const rowWhereParams = [];
|
|
15353
|
+
if (transportType !== undefined) {
|
|
15354
|
+
if (transportType !== "http" && transportType !== "websocket")
|
|
15355
|
+
throw new Error("Invalid transport type");
|
|
15356
|
+
rowWhereClauses.push("transport_type = ?");
|
|
15357
|
+
rowWhereParams.push(transportType);
|
|
15358
|
+
}
|
|
15345
15359
|
if (method) {
|
|
15346
15360
|
rowWhereClauses.push("method = ?");
|
|
15347
15361
|
rowWhereParams.push(method);
|
|
@@ -15673,6 +15687,7 @@ class LogQueryService {
|
|
|
15673
15687
|
const headers = [
|
|
15674
15688
|
"requestId",
|
|
15675
15689
|
"timestamp",
|
|
15690
|
+
"transportType",
|
|
15676
15691
|
"method",
|
|
15677
15692
|
"path",
|
|
15678
15693
|
"query",
|
|
@@ -15699,6 +15714,7 @@ class LogQueryService {
|
|
|
15699
15714
|
return [
|
|
15700
15715
|
entry.requestId,
|
|
15701
15716
|
new Date(entry.timestamp).toISOString(),
|
|
15717
|
+
entry.transportType ?? "",
|
|
15702
15718
|
entry.method,
|
|
15703
15719
|
`"${entry.path}"`,
|
|
15704
15720
|
entry.query ? `"${entry.query}"` : "",
|
|
@@ -15946,6 +15962,7 @@ class LogQueryService {
|
|
|
15946
15962
|
requestId: row.request_id,
|
|
15947
15963
|
timestamp: row.timestamp,
|
|
15948
15964
|
method: row.method,
|
|
15965
|
+
transportType: row.transport_type,
|
|
15949
15966
|
path: row.path,
|
|
15950
15967
|
query: row.query || undefined,
|
|
15951
15968
|
status: row.status,
|
|
@@ -15992,10 +16009,14 @@ function getSingleParam(url, name) {
|
|
|
15992
16009
|
const values = url.searchParams.getAll(name);
|
|
15993
16010
|
return values.length === 0 ? undefined : values.length === 1 && values[0] !== "" ? values[0] : null;
|
|
15994
16011
|
}
|
|
15995
|
-
function
|
|
16012
|
+
function getLogFilters(url) {
|
|
15996
16013
|
const values = url.searchParams.getAll("status");
|
|
15997
16014
|
const statuses = values.map((value) => /^\d{3}$/.test(value) ? Number(value) : NaN);
|
|
15998
16015
|
const transport = getSingleParam(url, "transportOutcome");
|
|
16016
|
+
const transportType = getSingleParam(url, "transportType");
|
|
16017
|
+
if (transportType !== undefined && transportType !== "http" && transportType !== "websocket") {
|
|
16018
|
+
return Response.json({ error: "transportType must be http or websocket" }, { status: 400 });
|
|
16019
|
+
}
|
|
15999
16020
|
if (statuses.some((value) => !Number.isInteger(value) || value < 100 || value > 599)) {
|
|
16000
16021
|
return Response.json({ error: "status must contain HTTP status codes between 100 and 599" }, { status: 400 });
|
|
16001
16022
|
}
|
|
@@ -16004,6 +16025,7 @@ function getOutcomeFilters(url) {
|
|
|
16004
16025
|
}
|
|
16005
16026
|
return {
|
|
16006
16027
|
status: statuses.length === 0 ? undefined : statuses.length === 1 ? statuses[0] : [...new Set(statuses)],
|
|
16028
|
+
transportType,
|
|
16007
16029
|
transportOutcome: transport
|
|
16008
16030
|
};
|
|
16009
16031
|
}
|
|
@@ -16039,7 +16061,7 @@ class LogsHandler {
|
|
|
16039
16061
|
try {
|
|
16040
16062
|
const url = new URL(req.url);
|
|
16041
16063
|
const groupBy = url.searchParams.get("groupBy");
|
|
16042
|
-
const outcomeFilters =
|
|
16064
|
+
const outcomeFilters = getLogFilters(url);
|
|
16043
16065
|
if (outcomeFilters instanceof Response)
|
|
16044
16066
|
return outcomeFilters;
|
|
16045
16067
|
const params = {
|
|
@@ -16277,7 +16299,7 @@ class LogsHandler {
|
|
|
16277
16299
|
const format = url.searchParams.get("format") || "json";
|
|
16278
16300
|
if (format !== "json" && format !== "csv")
|
|
16279
16301
|
return Response.json({ error: "format must be json or csv" }, { status: 400 });
|
|
16280
|
-
const outcomeFilters =
|
|
16302
|
+
const outcomeFilters = getLogFilters(url);
|
|
16281
16303
|
if (outcomeFilters instanceof Response)
|
|
16282
16304
|
return outcomeFilters;
|
|
16283
16305
|
const params = {
|
|
@@ -17604,6 +17626,16 @@ var ACCESS_BASELINE = {
|
|
|
17604
17626
|
}
|
|
17605
17627
|
};
|
|
17606
17628
|
|
|
17629
|
+
// src/migrations/access-log-transport-type.ts
|
|
17630
|
+
var ACCESS_LOG_TRANSPORT_TYPE = {
|
|
17631
|
+
version: "005",
|
|
17632
|
+
name: "access_log_transport_type",
|
|
17633
|
+
up(db) {
|
|
17634
|
+
db.run(`ALTER TABLE access_logs ADD COLUMN transport_type TEXT
|
|
17635
|
+
CHECK (transport_type IS NULL OR transport_type IN ('http', 'websocket'))`);
|
|
17636
|
+
}
|
|
17637
|
+
};
|
|
17638
|
+
|
|
17607
17639
|
// src/migrations/migration-manager.ts
|
|
17608
17640
|
import { Database as Database4 } from "bun:sqlite";
|
|
17609
17641
|
import { mkdirSync as mkdirSync2, existsSync } from "fs";
|
|
@@ -18074,7 +18106,7 @@ class MigrationManager {
|
|
|
18074
18106
|
}
|
|
18075
18107
|
|
|
18076
18108
|
// src/migrations/index.ts
|
|
18077
|
-
var migrations = [ACCESS_BASELINE, LLM_TPS_SAMPLES, LLM_TPS_MODEL, LLM_TPS_UPSTREAM_HOST];
|
|
18109
|
+
var migrations = [ACCESS_BASELINE, LLM_TPS_SAMPLES, LLM_TPS_MODEL, LLM_TPS_UPSTREAM_HOST, ACCESS_LOG_TRANSPORT_TYPE];
|
|
18078
18110
|
|
|
18079
18111
|
// src/master-runtime/observability-worker.ts
|
|
18080
18112
|
function headerEntries(headers) {
|
|
@@ -1281,7 +1281,7 @@ function validStoredAccount(value) {
|
|
|
1281
1281
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
1282
1282
|
return false;
|
|
1283
1283
|
const account = value;
|
|
1284
|
-
return typeof account.id === "string" && account.id.length > 0 && account.id.length <= 128 && typeof account.label === "string" && account.label.length > 0 && account.label.length <= MAX_TEXT && ["active", "disabled", "reauth_required", "revoked"].includes(account.status) && Number.isSafeInteger(account.generation) && account.generation > 0 && (account.loginFence === undefined || Number.isSafeInteger(account.loginFence) && account.loginFence > 0) && (account.credentialValid === undefined || typeof account.credentialValid === "boolean") && (account.autoResetCredits === undefined || typeof account.autoResetCredits === "boolean") && (account.siwc === undefined || validSiwcMetadata(account.siwc)) && validAutoResetAttempts(account.autoResetAttempts) && Number.isFinite(account.createdAt) && Number.isFinite(account.updatedAt);
|
|
1284
|
+
return typeof account.id === "string" && account.id.length > 0 && account.id.length <= 128 && typeof account.label === "string" && account.label.length > 0 && account.label.length <= MAX_TEXT && ["active", "disabled", "reauth_required", "revoked"].includes(account.status) && Number.isSafeInteger(account.generation) && account.generation > 0 && (account.loginFence === undefined || Number.isSafeInteger(account.loginFence) && account.loginFence > 0) && (account.credentialValid === undefined || typeof account.credentialValid === "boolean") && (account.autoResetCredits === undefined || typeof account.autoResetCredits === "boolean") && (account.autoResetLeadMinutes === undefined || Number.isInteger(account.autoResetLeadMinutes) && account.autoResetLeadMinutes >= 1 && account.autoResetLeadMinutes <= 10080) && (account.autoResetOnLowBalance === undefined || typeof account.autoResetOnLowBalance === "boolean") && (account.autoResetRemainingPercent === undefined || Number.isInteger(account.autoResetRemainingPercent) && account.autoResetRemainingPercent >= 0 && account.autoResetRemainingPercent <= 100) && (account.siwc === undefined || validSiwcMetadata(account.siwc)) && validAutoResetAttempts(account.autoResetAttempts) && Number.isFinite(account.createdAt) && Number.isFinite(account.updatedAt);
|
|
1285
1285
|
}
|
|
1286
1286
|
function decode(value) {
|
|
1287
1287
|
if (value === undefined)
|
|
@@ -1326,6 +1326,9 @@ function accountListItem(account) {
|
|
|
1326
1326
|
expiresAt: account.expiresAt,
|
|
1327
1327
|
identity: copyIdentity(account.identity),
|
|
1328
1328
|
autoResetCredits: !account.siwc && account.autoResetCredits === true,
|
|
1329
|
+
autoResetLeadMinutes: account.autoResetLeadMinutes ?? 30,
|
|
1330
|
+
autoResetOnLowBalance: !account.siwc && account.autoResetOnLowBalance === true,
|
|
1331
|
+
autoResetRemainingPercent: account.autoResetRemainingPercent ?? 10,
|
|
1329
1332
|
pendingAutoReset: !account.siwc && pending ? { ...pending } : undefined
|
|
1330
1333
|
};
|
|
1331
1334
|
}
|
|
@@ -1539,8 +1542,8 @@ class AccountStore {
|
|
|
1539
1542
|
return copyAccount(account);
|
|
1540
1543
|
});
|
|
1541
1544
|
}
|
|
1542
|
-
async setAutoResetCredits(id, enabled) {
|
|
1543
|
-
if (typeof enabled !== "boolean")
|
|
1545
|
+
async setAutoResetCredits(id, enabled, options = {}) {
|
|
1546
|
+
if (enabled !== undefined && typeof enabled !== "boolean" || options.lowBalanceEnabled !== undefined && typeof options.lowBalanceEnabled !== "boolean" || options.leadMinutes !== undefined && (!Number.isInteger(options.leadMinutes) || options.leadMinutes < 1 || options.leadMinutes > 10080) || options.remainingPercent !== undefined && (!Number.isInteger(options.remainingPercent) || options.remainingPercent < 0 || options.remainingPercent > 100))
|
|
1544
1547
|
throw new AccountControlError("invalid_input");
|
|
1545
1548
|
return this.mutate((aggregate) => {
|
|
1546
1549
|
const account = aggregate.accounts.find((item) => item.id === id);
|
|
@@ -1550,7 +1553,10 @@ class AccountStore {
|
|
|
1550
1553
|
throw new AccountControlError("revoked");
|
|
1551
1554
|
if (account.siwc)
|
|
1552
1555
|
throw new AccountControlError("unsupported_operation");
|
|
1553
|
-
account.autoResetCredits = enabled;
|
|
1556
|
+
account.autoResetCredits = enabled ?? account.autoResetCredits ?? false;
|
|
1557
|
+
account.autoResetLeadMinutes = options.leadMinutes ?? account.autoResetLeadMinutes ?? 30;
|
|
1558
|
+
account.autoResetOnLowBalance = options.lowBalanceEnabled ?? account.autoResetOnLowBalance ?? false;
|
|
1559
|
+
account.autoResetRemainingPercent = options.remainingPercent ?? account.autoResetRemainingPercent ?? 10;
|
|
1554
1560
|
account.updatedAt = Date.now();
|
|
1555
1561
|
return copyAccount(account);
|
|
1556
1562
|
});
|
|
@@ -1558,7 +1564,7 @@ class AccountStore {
|
|
|
1558
1564
|
async claimAutoReset(id, credit, now) {
|
|
1559
1565
|
return this.mutate((aggregate) => {
|
|
1560
1566
|
const account = aggregate.accounts.find((item) => item.id === id);
|
|
1561
|
-
if (!account || account.siwc || !accountListItem(account).available || account.autoResetCredits
|
|
1567
|
+
if (!account || account.siwc || !accountListItem(account).available || !(account.autoResetCredits || account.autoResetOnLowBalance))
|
|
1562
1568
|
return;
|
|
1563
1569
|
const attempts = account.autoResetAttempts ?? [];
|
|
1564
1570
|
if (attempts.some((item) => !item.completed || item.creditId === credit.id))
|
|
@@ -2554,8 +2560,17 @@ var defaultTimer = {
|
|
|
2554
2560
|
},
|
|
2555
2561
|
cancel: (handle) => clearTimeout(handle)
|
|
2556
2562
|
};
|
|
2557
|
-
function isAutoResetDue(credit, now) {
|
|
2558
|
-
return credit.status === "available" && typeof credit.expiresAt === "number" && Number.isFinite(credit.expiresAt) && credit.expiresAt > now && credit.expiresAt - now <=
|
|
2563
|
+
function isAutoResetDue(credit, now, leadMinutes = 30) {
|
|
2564
|
+
return credit.status === "available" && typeof credit.expiresAt === "number" && Number.isFinite(credit.expiresAt) && credit.expiresAt > now && credit.expiresAt - now <= leadMinutes * 60000;
|
|
2565
|
+
}
|
|
2566
|
+
function isLowBalance(usage, remainingPercent, now) {
|
|
2567
|
+
if (usage.state !== "fresh" || usage.error)
|
|
2568
|
+
return false;
|
|
2569
|
+
const windows = [usage.primary, usage.secondary].filter((window) => window !== undefined && Number.isFinite(window.windowSeconds) && window.windowSeconds > 18000);
|
|
2570
|
+
const longest = Math.max(...windows.map((window) => window.windowSeconds));
|
|
2571
|
+
const candidates = windows.filter((window) => window.windowSeconds === longest);
|
|
2572
|
+
const window = candidates[0];
|
|
2573
|
+
return candidates.length === 1 && window !== undefined && Number.isFinite(window.usedPercent) && window.usedPercent >= 0 && window.usedPercent <= 100 && window.resetAt > now && window.resetAt - now <= window.windowSeconds * 1000 && 100 - window.usedPercent <= remainingPercent;
|
|
2559
2574
|
}
|
|
2560
2575
|
|
|
2561
2576
|
class AutoResetScheduler {
|
|
@@ -2605,7 +2620,7 @@ class AutoResetScheduler {
|
|
|
2605
2620
|
}
|
|
2606
2621
|
async scan() {
|
|
2607
2622
|
const accounts = await this.accounts.list();
|
|
2608
|
-
const eligible = new Set(accounts.filter((account) => account.available && account.autoResetCredits && (!account.pendingAutoReset || this.accountRuns.has(account.id))).map((account) => account.id));
|
|
2623
|
+
const eligible = new Set(accounts.filter((account) => account.available && (account.autoResetCredits || account.autoResetOnLowBalance) && (!account.pendingAutoReset || this.accountRuns.has(account.id))).map((account) => account.id));
|
|
2609
2624
|
for (const id of this.plans.keys())
|
|
2610
2625
|
if (!eligible.has(id))
|
|
2611
2626
|
this.cancelPlan(id);
|
|
@@ -2626,7 +2641,12 @@ class AutoResetScheduler {
|
|
|
2626
2641
|
if ((snapshot.resetCredits.availableCount ?? 0) <= 0)
|
|
2627
2642
|
continue;
|
|
2628
2643
|
const credits = [...snapshot.resetCredits.credits ?? []].filter((credit) => credit.status === "available" && typeof credit.expiresAt === "number" && Number.isFinite(credit.expiresAt) && credit.expiresAt > this.now()).sort((a, b) => a.expiresAt - b.expiresAt);
|
|
2629
|
-
const plan = {
|
|
2644
|
+
const plan = {
|
|
2645
|
+
credits,
|
|
2646
|
+
leadMinutes: account.autoResetLeadMinutes,
|
|
2647
|
+
expiryEnabled: account.autoResetCredits,
|
|
2648
|
+
lowBalance: account.autoResetOnLowBalance && isLowBalance(snapshot.usage, account.autoResetRemainingPercent, this.now())
|
|
2649
|
+
};
|
|
2630
2650
|
this.plans.set(account.id, plan);
|
|
2631
2651
|
await this.executePlan(account.id, plan);
|
|
2632
2652
|
} catch {}
|
|
@@ -2647,7 +2667,11 @@ class AutoResetScheduler {
|
|
|
2647
2667
|
this.cancelPlan(accountRef);
|
|
2648
2668
|
return;
|
|
2649
2669
|
}
|
|
2650
|
-
|
|
2670
|
+
if (!plan.expiryEnabled) {
|
|
2671
|
+
this.cancelPlan(accountRef);
|
|
2672
|
+
return;
|
|
2673
|
+
}
|
|
2674
|
+
const dueAt = plan.credits[0].expiresAt - plan.leadMinutes * 60000;
|
|
2651
2675
|
plan.handle = this.timer.schedule(() => this.executePlan(accountRef, plan), Math.min(MAX_TIMER_DELAY_MS, Math.max(0, dueAt - this.now())));
|
|
2652
2676
|
}
|
|
2653
2677
|
executePlan(accountRef, plan) {
|
|
@@ -2659,32 +2683,51 @@ class AutoResetScheduler {
|
|
|
2659
2683
|
return;
|
|
2660
2684
|
try {
|
|
2661
2685
|
const account = accountListItem(await this.accounts.get(accountRef));
|
|
2662
|
-
if (!account.available || !account.autoResetCredits || account.pendingAutoReset) {
|
|
2686
|
+
if (!account.available || !(account.autoResetCredits || account.autoResetOnLowBalance) || account.pendingAutoReset) {
|
|
2663
2687
|
this.cancelPlan(accountRef, plan);
|
|
2664
2688
|
return;
|
|
2665
2689
|
}
|
|
2690
|
+
plan.leadMinutes = account.autoResetLeadMinutes;
|
|
2691
|
+
plan.expiryEnabled = account.autoResetCredits;
|
|
2666
2692
|
while (this.plans.get(accountRef) === plan && plan.credits.length > 0) {
|
|
2667
2693
|
if (this.disposed || this.signal.aborted)
|
|
2668
2694
|
return;
|
|
2669
2695
|
const credit = plan.credits[0];
|
|
2670
|
-
|
|
2696
|
+
const latestConfig = accountListItem(await this.accounts.get(accountRef));
|
|
2697
|
+
plan.leadMinutes = latestConfig.autoResetLeadMinutes;
|
|
2698
|
+
plan.expiryEnabled = latestConfig.autoResetCredits;
|
|
2699
|
+
const balanceAttempt = plan.lowBalance && latestConfig.autoResetOnLowBalance;
|
|
2700
|
+
if (!balanceAttempt && (!plan.expiryEnabled || credit.expiresAt - plan.leadMinutes * 60000 > this.now()))
|
|
2671
2701
|
break;
|
|
2672
2702
|
plan.credits.shift();
|
|
2673
|
-
if (
|
|
2703
|
+
if (balanceAttempt)
|
|
2704
|
+
plan.lowBalance = false;
|
|
2705
|
+
if (!balanceAttempt && !isAutoResetDue(credit, this.now(), plan.leadMinutes))
|
|
2674
2706
|
continue;
|
|
2675
2707
|
const attempt = await this.accounts.claimAutoReset(accountRef, credit, this.now());
|
|
2676
|
-
if (!attempt)
|
|
2708
|
+
if (!attempt) {
|
|
2677
2709
|
continue;
|
|
2710
|
+
}
|
|
2678
2711
|
let deferred;
|
|
2679
2712
|
try {
|
|
2680
2713
|
const result = await this.usage.consume(accountRef, attempt.redeemRequestId, credit.id, this.signal, {
|
|
2681
2714
|
canConsume: async (selected) => {
|
|
2682
|
-
const
|
|
2683
|
-
|
|
2715
|
+
const fresh = balanceAttempt ? await this.usage.get(accountRef, this.signal, { forceFresh: true }).catch(() => {
|
|
2716
|
+
return;
|
|
2717
|
+
}) : undefined;
|
|
2718
|
+
const latest = accountListItem(await this.accounts.get(accountRef));
|
|
2719
|
+
if (this.disposed || this.signal.aborted || !latest.available)
|
|
2720
|
+
return false;
|
|
2721
|
+
if (balanceAttempt) {
|
|
2722
|
+
const first = fresh?.resetCredits.state === "fresh" && (fresh.resetCredits.availableCount ?? 0) > 0 ? [...fresh.resetCredits.credits ?? []].filter((item) => item.status === "available" && Number.isFinite(item.expiresAt) && item.expiresAt > this.now()).sort((a, b) => a.expiresAt - b.expiresAt)[0] : undefined;
|
|
2723
|
+
if (latest.autoResetOnLowBalance && fresh !== undefined && first?.id === selected.id && isLowBalance(fresh.usage, latest.autoResetRemainingPercent, this.now()))
|
|
2724
|
+
return true;
|
|
2725
|
+
}
|
|
2726
|
+
if (!latest.autoResetCredits)
|
|
2684
2727
|
return false;
|
|
2685
|
-
if (selected.status === "available" && typeof selected.expiresAt === "number" && Number.isFinite(selected.expiresAt) && selected.expiresAt -
|
|
2728
|
+
if (selected.status === "available" && typeof selected.expiresAt === "number" && Number.isFinite(selected.expiresAt) && selected.expiresAt - latest.autoResetLeadMinutes * 60000 > this.now())
|
|
2686
2729
|
deferred = selected;
|
|
2687
|
-
return isAutoResetDue(selected, this.now());
|
|
2730
|
+
return isAutoResetDue(selected, this.now(), latest.autoResetLeadMinutes);
|
|
2688
2731
|
}
|
|
2689
2732
|
});
|
|
2690
2733
|
if (result.outcome === "reset_outcome_unknown") {
|
|
@@ -3202,10 +3245,14 @@ class ChatgptControl {
|
|
|
3202
3245
|
}) },
|
|
3203
3246
|
{ path: "/accounts/auto-reset", methods: ["POST"], handler: "setAutoResetCredits", invoke: invoke(async (context) => {
|
|
3204
3247
|
const body = await this.readJson(context);
|
|
3205
|
-
exactKeys(body, ["accountRef", "enabled"]);
|
|
3206
|
-
if (typeof body.enabled !== "boolean")
|
|
3248
|
+
exactKeys(body, ["accountRef", "enabled", "leadMinutes", "lowBalanceEnabled", "remainingPercent"]);
|
|
3249
|
+
if ("enabled" in body && typeof body.enabled !== "boolean" || "lowBalanceEnabled" in body && typeof body.lowBalanceEnabled !== "boolean" || "leadMinutes" in body && (typeof body.leadMinutes !== "number" || !Number.isInteger(body.leadMinutes) || body.leadMinutes < 1 || body.leadMinutes > 10080) || "remainingPercent" in body && (typeof body.remainingPercent !== "number" || !Number.isInteger(body.remainingPercent) || body.remainingPercent < 0 || body.remainingPercent > 100))
|
|
3207
3250
|
throw new ControlError("invalid_input");
|
|
3208
|
-
return jsonResponse({ account: accountListItem(await this.accounts.setAutoResetCredits(requiredText(body.accountRef, 128), body.enabled
|
|
3251
|
+
return jsonResponse({ account: accountListItem(await this.accounts.setAutoResetCredits(requiredText(body.accountRef, 128), body.enabled, {
|
|
3252
|
+
leadMinutes: body.leadMinutes,
|
|
3253
|
+
lowBalanceEnabled: body.lowBalanceEnabled,
|
|
3254
|
+
remainingPercent: body.remainingPercent
|
|
3255
|
+
})) });
|
|
3209
3256
|
}) },
|
|
3210
3257
|
{ path: "/accounts/draft", methods: ["POST"], handler: "createDraft", invoke: invoke((context) => this.draft(context, "codex")) },
|
|
3211
3258
|
{ path: "/accounts/siwc/draft", methods: ["POST"], handler: "createSiwcDraft", invoke: invoke((context) => this.draft(context, "siwc")) },
|
|
@@ -3381,4 +3428,4 @@ export {
|
|
|
3381
3428
|
rpc
|
|
3382
3429
|
};
|
|
3383
3430
|
|
|
3384
|
-
//# debugId=
|
|
3431
|
+
//# debugId=88F390C0C885560A64756E2164756E21
|