@amerged/ohmyhost-mcp 0.1.41 → 0.1.43

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.
@@ -30,7 +30,7 @@ import {
30
30
  serverIdentityOf,
31
31
  setNegotiatedProtocolVersion,
32
32
  validateEnvelopeMeta
33
- } from "./chunk-6HQPHICK.js";
33
+ } from "./chunk-ACMEMS6N.js";
34
34
 
35
35
  // node_modules/.pnpm/ignore@7.0.12/node_modules/ignore/index.js
36
36
  var require_ignore = __commonJS({
@@ -9034,17 +9034,17 @@ If you're a developer and you believe this is a bug in isomorphic-git, please fi
9034
9034
  var VARIABLE_NAME_REGEX = /^[A-Za-z][A-Za-z-]*$/;
9035
9035
  var VARIABLE_VALUE_COMMENT_REGEX = /^(.*?)( *[#;].*)$/;
9036
9036
  var extractSectionLine = (line) => {
9037
- const matches = SECTION_LINE_REGEX.exec(line);
9038
- if (matches != null) {
9039
- const [section, subsection] = matches.slice(1);
9037
+ const matches2 = SECTION_LINE_REGEX.exec(line);
9038
+ if (matches2 != null) {
9039
+ const [section, subsection] = matches2.slice(1);
9040
9040
  return [section, subsection];
9041
9041
  }
9042
9042
  return null;
9043
9043
  };
9044
9044
  var extractVariableLine = (line) => {
9045
- const matches = VARIABLE_LINE_REGEX.exec(line);
9046
- if (matches != null) {
9047
- const [name, rawValue = "true"] = matches.slice(1);
9045
+ const matches2 = VARIABLE_LINE_REGEX.exec(line);
9046
+ if (matches2 != null) {
9047
+ const [name, rawValue = "true"] = matches2.slice(1);
9048
9048
  const valueWithoutComments = removeComments(rawValue);
9049
9049
  const valueWithoutQuotes = removeQuotes(valueWithoutComments);
9050
9050
  return [name, valueWithoutQuotes];
@@ -10663,14 +10663,14 @@ If you're a developer and you believe this is a bug in isomorphic-git, please fi
10663
10663
  * @param {string} short
10664
10664
  * @param {string[]} matches
10665
10665
  */
10666
- constructor(nouns, short, matches) {
10666
+ constructor(nouns, short, matches2) {
10667
10667
  super(
10668
- `Found multiple ${nouns} matching "${short}" (${matches.join(
10668
+ `Found multiple ${nouns} matching "${short}" (${matches2.join(
10669
10669
  ", "
10670
10670
  )}). Use a longer abbreviation length to disambiguate them.`
10671
10671
  );
10672
10672
  this.code = this.name = _AmbiguousError.code;
10673
- this.data = { nouns, short, matches };
10673
+ this.data = { nouns, short, matches: matches2 };
10674
10674
  }
10675
10675
  };
10676
10676
  AmbiguousError.code = "AmbiguousError";
@@ -11043,9 +11043,9 @@ If you're a developer and you believe this is a bug in isomorphic-git, please fi
11043
11043
  IndexResetError,
11044
11044
  NoCommitError
11045
11045
  });
11046
- function formatAuthor({ name, email, timestamp: timestamp6, timezoneOffset }) {
11046
+ function formatAuthor({ name, email, timestamp: timestamp7, timezoneOffset }) {
11047
11047
  timezoneOffset = formatTimezoneOffset(timezoneOffset);
11048
- return `${name} <${email}> ${timestamp6} ${timezoneOffset}`;
11048
+ return `${name} <${email}> ${timestamp7} ${timezoneOffset}`;
11049
11049
  }
11050
11050
  function formatTimezoneOffset(minutes) {
11051
11051
  const sign = simpleSign(negateExceptForZero(minutes));
@@ -11071,13 +11071,13 @@ If you're a developer and you believe this is a bug in isomorphic-git, please fi
11071
11071
  return str;
11072
11072
  }
11073
11073
  function parseAuthor(author) {
11074
- const [, name, email, timestamp6, offset] = author.match(
11074
+ const [, name, email, timestamp7, offset] = author.match(
11075
11075
  /^(.*) <(.*)> (.*) (.*)$/
11076
11076
  );
11077
11077
  return {
11078
11078
  name,
11079
11079
  email,
11080
- timestamp: Number(timestamp6),
11080
+ timestamp: Number(timestamp7),
11081
11081
  timezoneOffset: parseTimezoneOffset(offset)
11082
11082
  };
11083
11083
  }
@@ -12417,13 +12417,13 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
12417
12417
  return target;
12418
12418
  }
12419
12419
  async function normalizeAuthorObject({ fs: fs3, gitdir, author, commit: commit3 }) {
12420
- const timestamp6 = Math.floor(Date.now() / 1e3);
12420
+ const timestamp7 = Math.floor(Date.now() / 1e3);
12421
12421
  const defaultAuthor = {
12422
12422
  name: await _getConfig({ fs: fs3, gitdir, path: "user.name" }),
12423
12423
  email: await _getConfig({ fs: fs3, gitdir, path: "user.email" }) || "",
12424
12424
  // author.email is allowed to be empty string
12425
- timestamp: timestamp6,
12426
- timezoneOffset: new Date(timestamp6 * 1e3).getTimezoneOffset()
12425
+ timestamp: timestamp7,
12426
+ timezoneOffset: new Date(timestamp7 * 1e3).getTimezoneOffset()
12427
12427
  };
12428
12428
  const normalizedAuthor = assignDefined(
12429
12429
  {},
@@ -12443,13 +12443,13 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
12443
12443
  committer,
12444
12444
  commit: commit3
12445
12445
  }) {
12446
- const timestamp6 = Math.floor(Date.now() / 1e3);
12446
+ const timestamp7 = Math.floor(Date.now() / 1e3);
12447
12447
  const defaultCommitter = {
12448
12448
  name: await _getConfig({ fs: fs3, gitdir, path: "user.name" }),
12449
12449
  email: await _getConfig({ fs: fs3, gitdir, path: "user.email" }) || "",
12450
12450
  // committer.email is allowed to be empty string
12451
- timestamp: timestamp6,
12452
- timezoneOffset: new Date(timestamp6 * 1e3).getTimezoneOffset()
12451
+ timestamp: timestamp7,
12452
+ timezoneOffset: new Date(timestamp7 * 1e3).getTimezoneOffset()
12453
12453
  };
12454
12454
  const normalizedCommitter = assignDefined(
12455
12455
  {},
@@ -14916,18 +14916,18 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
14916
14916
  address: url
14917
14917
  };
14918
14918
  }
14919
- const matches = url.match(/(\w+)(:\/\/|::)(.*)/);
14920
- if (matches === null) return;
14921
- if (matches[2] === "://") {
14919
+ const matches2 = url.match(/(\w+)(:\/\/|::)(.*)/);
14920
+ if (matches2 === null) return;
14921
+ if (matches2[2] === "://") {
14922
14922
  return {
14923
- transport: matches[1],
14924
- address: matches[0]
14923
+ transport: matches2[1],
14924
+ address: matches2[0]
14925
14925
  };
14926
14926
  }
14927
- if (matches[2] === "::") {
14927
+ if (matches2[2] === "::") {
14928
14928
  return {
14929
- transport: matches[1],
14930
- address: matches[3]
14929
+ transport: matches2[1],
14930
+ address: matches2[3]
14931
14931
  };
14932
14932
  }
14933
14933
  }
@@ -15552,12 +15552,12 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
15552
15552
  forAwait(lines, async (line) => {
15553
15553
  if (onMessage) await onMessage(line);
15554
15554
  if (onProgress) {
15555
- const matches = line.match(/([^:]*).*\((\d+?)\/(\d+?)\)/);
15556
- if (matches) {
15555
+ const matches2 = line.match(/([^:]*).*\((\d+?)\/(\d+?)\)/);
15556
+ if (matches2) {
15557
15557
  await onProgress({
15558
- phase: matches[1].trim(),
15559
- loaded: parseInt(matches[2], 10),
15560
- total: parseInt(matches[3], 10)
15558
+ phase: matches2[1].trim(),
15559
+ loaded: parseInt(matches2[2], 10),
15560
+ total: parseInt(matches2[3], 10)
15561
15561
  });
15562
15562
  }
15563
15563
  }
@@ -18626,9 +18626,9 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
18626
18626
  static createStashReflogEntry(author, stashCommit, message) {
18627
18627
  const nameNoSpace = author.name.replace(/\s/g, "");
18628
18628
  const z40 = "0000000000000000000000000000000000000000";
18629
- const timestamp6 = Math.floor(Date.now() / 1e3);
18629
+ const timestamp7 = Math.floor(Date.now() / 1e3);
18630
18630
  const timezoneOffset = _GitRefStash.timezoneOffsetForRefLogEntry;
18631
- return `${z40} ${stashCommit} ${nameNoSpace} ${author.email} ${timestamp6} ${timezoneOffset} ${message}
18631
+ return `${z40} ${stashCommit} ${nameNoSpace} ${author.email} ${timestamp7} ${timezoneOffset} ${message}
18632
18632
  `;
18633
18633
  }
18634
18634
  static getStashReflogEntry(reflogString, parsed = false) {
@@ -24293,14 +24293,14 @@ function isFrameworkConversionDiagnosticCode(value) {
24293
24293
  function parseFrameworkConversionDiagnostic(value) {
24294
24294
  if (typeof value !== "object" || value === null || Array.isArray(value))
24295
24295
  return null;
24296
- const record7 = value;
24297
- const code = Object.hasOwn(record7, "code") ? record7["code"] : void 0;
24298
- const path2 = Object.hasOwn(record7, "path") ? record7["path"] : void 0;
24296
+ const record8 = value;
24297
+ const code = Object.hasOwn(record8, "code") ? record8["code"] : void 0;
24298
+ const path2 = Object.hasOwn(record8, "path") ? record8["path"] : void 0;
24299
24299
  if (!isFrameworkConversionDiagnosticCode(code) || typeof path2 !== "string")
24300
24300
  return null;
24301
24301
  const definition = DETAIL_DEFINITIONS[code];
24302
- const fields = Object.entries(definition.fields ?? {}).map(([name, grammar]) => [name, grammar, Object.hasOwn(record7, name) ? record7[name] : void 0]);
24303
- if (Object.keys(record7).length !== fields.length + 2 || pathClassOf(definition, path2) === null || fields.some(([, grammar, field]) => !fieldMatches(grammar, field)))
24302
+ const fields = Object.entries(definition.fields ?? {}).map(([name, grammar]) => [name, grammar, Object.hasOwn(record8, name) ? record8[name] : void 0]);
24303
+ if (Object.keys(record8).length !== fields.length + 2 || pathClassOf(definition, path2) === null || fields.some(([, grammar, field]) => !fieldMatches(grammar, field)))
24304
24304
  return null;
24305
24305
  return Object.freeze(Object.fromEntries([
24306
24306
  ["code", code],
@@ -24803,8 +24803,8 @@ function ulid(value) {
24803
24803
  if (typeof value !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(value))
24804
24804
  invalid();
24805
24805
  }
24806
- function commit(value, nullable = false) {
24807
- if (nullable && value === null)
24806
+ function commit(value, nullable2 = false) {
24807
+ if (nullable2 && value === null)
24808
24808
  return;
24809
24809
  if (typeof value !== "string" || !/^[a-f0-9]{40}$/u.test(value))
24810
24810
  invalid();
@@ -25408,72 +25408,6 @@ function isSaasCnameTarget(value) {
25408
25408
  return value === "customers.omh.st" || value === "customers.ohmyho.st";
25409
25409
  }
25410
25410
 
25411
- // packages/contracts/dist/credit-pricing.js
25412
- function assertOrganizationCreditUsage(value) {
25413
- const record7 = (input, keys) => {
25414
- if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).sort().join() !== keys.split(",").sort().join())
25415
- throw new TypeError("Invalid usage fields");
25416
- return input;
25417
- };
25418
- const identifier3 = (input) => typeof input === "string" && /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(input);
25419
- const amount = (input) => typeof input === "string" && /^(0|[1-9][0-9]{0,37})$/u.test(input);
25420
- const instant2 = (input) => typeof input === "string" && Number.isFinite(Date.parse(input)) && new Date(input).toISOString() === input;
25421
- const report = record7(value, "organization_id,as_of,unit,period,from,projects,days");
25422
- if (!identifier3(report["organization_id"]) || !instant2(report["as_of"]) || !instant2(report["from"]) || report["unit"] !== "microcredits" || typeof report["period"] !== "string" || !/^20[0-9]{2}-(0[1-9]|1[0-2])$/u.test(report["period"]) || !Array.isArray(report["projects"]) || report["projects"].length > 1e3 || !Array.isArray(report["days"]) || report["days"].length > 15)
25423
- throw new TypeError("Invalid usage report");
25424
- let previous = "";
25425
- for (const input of report["projects"]) {
25426
- const project = record7(input, "project_id,used_micros");
25427
- if (!identifier3(project["project_id"]) || String(project["project_id"]) <= previous || !amount(project["used_micros"]))
25428
- throw new TypeError("Invalid usage project");
25429
- previous = String(project["project_id"]);
25430
- }
25431
- let previousDay = "";
25432
- for (const input of report["days"]) {
25433
- const day = record7(input, "day,projects");
25434
- if (typeof day["day"] !== "string" || !/^20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/u.test(day["day"]) || day["day"] <= previousDay || !Array.isArray(day["projects"]) || day["projects"].length > 1e3)
25435
- throw new TypeError("Invalid usage day");
25436
- previousDay = day["day"];
25437
- previous = "";
25438
- for (const projectInput of day["projects"]) {
25439
- const project = record7(projectInput, "project_id,meters");
25440
- if (!identifier3(project["project_id"]) || String(project["project_id"]) <= previous || !Array.isArray(project["meters"]) || project["meters"].length > 1e3)
25441
- throw new TypeError("Invalid usage project");
25442
- previous = String(project["project_id"]);
25443
- for (const meterInput of project["meters"]) {
25444
- const meter = record7(meterInput, "environment_id,meter,unit,rate_card_id,quantity,charged_micros");
25445
- if (meter["environment_id"] !== null && !identifier3(meter["environment_id"]))
25446
- throw new TypeError("Invalid usage environment");
25447
- for (const key of ["meter", "unit", "rate_card_id"])
25448
- if (typeof meter[key] !== "string" || !/^[A-Za-z0-9_.:/-]{1,128}$/u.test(meter[key]))
25449
- throw new TypeError("Invalid usage meter");
25450
- if (typeof meter["quantity"] !== "string" || !/^(0|[1-9][0-9]{0,29})(\.[0-9]{1,12})?$/u.test(meter["quantity"]) || !amount(meter["charged_micros"]))
25451
- throw new TypeError("Invalid usage amount");
25452
- }
25453
- }
25454
- }
25455
- }
25456
- function assertOrganizationAccount(value) {
25457
- if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join(",") !== "as_of,available_micros,monthly_micros,name,next_expiry,one_time_micros,organization_id,paid_until,plan,plan_source,reserved_micros,workos_organization_id")
25458
- throw new TypeError("Invalid account fields");
25459
- const v = value;
25460
- if (typeof v["organization_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(v["organization_id"]) || typeof v["name"] !== "string" || v["name"].length > 128 || typeof v["workos_organization_id"] !== "string" || !/^org_[A-Za-z0-9_]+$/u.test(v["workos_organization_id"]) || v["plan"] !== "paid" && v["plan"] !== "free" || !["free", "stripe", "granted", "manual"].includes(String(v["plan_source"])) || v["plan"] === "free" !== (v["plan_source"] === "free"))
25461
- throw new TypeError("Invalid account scope");
25462
- for (const field of ["available_micros", "monthly_micros", "one_time_micros", "reserved_micros"])
25463
- if (typeof v[field] !== "string" || !/^(0|[1-9][0-9]{0,18})$/u.test(v[field]))
25464
- throw new TypeError("Invalid account credits");
25465
- const held = BigInt(String(v["reserved_micros"]));
25466
- const balance = BigInt(String(v["monthly_micros"])) + BigInt(String(v["one_time_micros"]));
25467
- if (BigInt(String(v["available_micros"])) !== (balance > held ? balance - held : 0n))
25468
- throw new TypeError("Account credit buckets do not balance");
25469
- for (const field of ["as_of", "paid_until", "next_expiry"]) {
25470
- if (field !== "as_of" && v[field] === null)
25471
- continue;
25472
- if (typeof v[field] !== "string" || !Number.isFinite(Date.parse(v[field])) || new Date(v[field]).toISOString() !== v[field])
25473
- throw new TypeError("Invalid account timestamp");
25474
- }
25475
- }
25476
-
25477
25411
  // packages/contracts/dist/problem-policy.js
25478
25412
  var PROBLEM_POLICY = {
25479
25413
  source_generation_conflict: {
@@ -25614,6 +25548,30 @@ var PROBLEM_POLICY = {
25614
25548
  action: "List the project's database credentials and revoke one you no longer need, then request access again.",
25615
25549
  title: "Database access limit reached"
25616
25550
  },
25551
+ database_webhook_limit: {
25552
+ status: 409,
25553
+ retryable: false,
25554
+ action: "List the project's database webhooks for this environment and delete one you no longer need, then create the webhook again.",
25555
+ title: "Database webhook limit reached"
25556
+ },
25557
+ database_schedule_limit: {
25558
+ status: 409,
25559
+ retryable: false,
25560
+ action: "List the project's database schedules for this environment and delete one you no longer need, then set the schedule again.",
25561
+ title: "Database schedule limit reached"
25562
+ },
25563
+ database_schedule_not_runnable: {
25564
+ status: 409,
25565
+ retryable: false,
25566
+ action: "Read the schedule and its runs. Enable a disabled schedule, or wait until the run already queued has finished, then request the run again.",
25567
+ title: "Database schedule cannot run now"
25568
+ },
25569
+ database_webhook_delivery_pending: {
25570
+ status: 409,
25571
+ retryable: false,
25572
+ action: "The platform is still retrying this webhook delivery. Read the delivery in the delivery list; replay it only if it ends dead_lettered or the receiver needs the event again.",
25573
+ title: "Webhook delivery still pending"
25574
+ },
25617
25575
  project_notes_conflict: {
25618
25576
  status: 409,
25619
25577
  retryable: false,
@@ -26297,8 +26255,8 @@ var isPaidValidationRecord = (value) => {
26297
26255
  if (typeof value !== "object" || value === null || Array.isArray(value) || Object.keys(value).sort().join(",") !== "content,name,purpose,type") {
26298
26256
  return false;
26299
26257
  }
26300
- const record7 = value;
26301
- return (record7["type"] === "CNAME" || record7["type"] === "TXT") && boundedString(record7["name"], 1, 253) && boundedString(record7["content"], 1, 2048) && ["traffic", "ownership", "ssl", "dcv_delegation"].includes(String(record7["purpose"]));
26258
+ const record8 = value;
26259
+ return (record8["type"] === "CNAME" || record8["type"] === "TXT") && boundedString(record8["name"], 1, 253) && boundedString(record8["content"], 1, 2048) && ["traffic", "ownership", "ssl", "dcv_delegation"].includes(String(record8["purpose"]));
26302
26260
  };
26303
26261
 
26304
26262
  // apps/product-cli/dist/source-publisher.js
@@ -26568,7 +26526,7 @@ async function prepareLocalSourcePublication(input) {
26568
26526
  request = { ...request, expected_commit_sha: link2.source.last_confirmed_commit_sha };
26569
26527
  }
26570
26528
  parseManagedSourceRequest("upload", request);
26571
- const record7 = {
26529
+ const record8 = {
26572
26530
  version: 1,
26573
26531
  ...scope,
26574
26532
  operation_id: null,
@@ -26577,16 +26535,16 @@ async function prepareLocalSourcePublication(input) {
26577
26535
  request
26578
26536
  };
26579
26537
  if (original !== null) {
26580
- assertSameAttempt(original, record7);
26538
+ assertSameAttempt(original, record8);
26581
26539
  } else
26582
- await writePending(record7, true);
26540
+ await writePending(record8, true);
26583
26541
  return {
26584
26542
  request,
26585
26543
  accepted: async (operation) => {
26586
26544
  const current = await readPending(scope, replay);
26587
26545
  if (current === null)
26588
26546
  throw new LocalSourcePublicationError("source_publication_missing");
26589
- assertSameAttempt(current, record7);
26547
+ assertSameAttempt(current, record8);
26590
26548
  if (current.operation_id !== null && current.operation_id !== operation.id)
26591
26549
  throw new ResponseContractError();
26592
26550
  if (!replay)
@@ -26605,7 +26563,7 @@ async function prepareLocalSourcePublication(input) {
26605
26563
  const current = await readPending(scope);
26606
26564
  if (current === null || current.operation_id !== null)
26607
26565
  return;
26608
- assertSameAttempt(current, record7);
26566
+ assertSameAttempt(current, record8);
26609
26567
  } catch (error2) {
26610
26568
  if (error2 instanceof LocalSourcePublicationError && (error2.code === "source_publication_scope_mismatch" || error2.code === "source_publication_pending"))
26611
26569
  return;
@@ -26808,12 +26766,12 @@ async function readRecord(path2) {
26808
26766
  await handle?.close();
26809
26767
  }
26810
26768
  }
26811
- async function writePending(record7, create, completed = false) {
26812
- const parent = join3(record7.directory, ".ohmyhost");
26769
+ async function writePending(record8, create, completed = false) {
26770
+ const parent = join3(record8.directory, ".ohmyhost");
26813
26771
  for (const directory of [
26814
26772
  parent,
26815
- record7.metadata_directory,
26816
- join3(record7.metadata_directory, "publications")
26773
+ record8.metadata_directory,
26774
+ join3(record8.metadata_directory, "publications")
26817
26775
  ]) {
26818
26776
  try {
26819
26777
  await fs2.mkdir(directory, { mode: 448 });
@@ -26824,10 +26782,10 @@ async function writePending(record7, create, completed = false) {
26824
26782
  await checkedDirectory(directory);
26825
26783
  await fs2.chmod(directory, 448);
26826
26784
  }
26827
- const target = completed ? completedPath(record7) : pendingPath(record7);
26785
+ const target = completed ? completedPath(record8) : pendingPath(record8);
26828
26786
  const temporary = create ? target : `${target}.${randomUUID()}.tmp`;
26829
26787
  try {
26830
- await fs2.writeFile(temporary, `${JSON.stringify(record7)}
26788
+ await fs2.writeFile(temporary, `${JSON.stringify(record8)}
26831
26789
  `, { mode: 384, flag: "wx" });
26832
26790
  if (!create)
26833
26791
  await fs2.rename(temporary, target);
@@ -26891,6 +26849,9 @@ var ACCESS_KEYS = [
26891
26849
  "mode",
26892
26850
  "role_name",
26893
26851
  "host",
26852
+ "provider",
26853
+ "transport",
26854
+ "websocket_url",
26894
26855
  "database",
26895
26856
  "label",
26896
26857
  "state",
@@ -26901,16 +26862,16 @@ var ACCESS_KEYS = [
26901
26862
  ];
26902
26863
  var ACCESS_ROLE_PATTERN = /^ohmyho_da_[0-7][0-9a-hjkmnp-tv-z]{25}_[0-9a-z]{8}$/u;
26903
26864
  function assertProjectDatabaseAccess(value) {
26904
- if (!record2(value) || !exact2(value, accessKeys(value)))
26865
+ if (!record2(value) || !exact2(value, ACCESS_KEYS))
26905
26866
  throw new TypeError("Invalid database access");
26906
26867
  assertAccessFields(value);
26907
26868
  }
26908
26869
  function assertProjectDatabaseAccessCredential(value) {
26909
- if (!record2(value) || !exact2(value, [...accessKeys(value), "connection_uri", "psql_command"]))
26870
+ if (!record2(value) || !exact2(value, [...ACCESS_KEYS, "connection_uri", "psql_command"]))
26910
26871
  throw new TypeError("Invalid database access credential");
26911
26872
  assertAccessFields(value);
26912
26873
  const uri = value["connection_uri"];
26913
- if (typeof uri !== "string" || (value["provider"] === "pgcf" ? typeof value["psql_command"] !== "string" || !new RegExp(`^ohmyhost database psql --project [0-7][0-9A-HJKMNP-TV-Z]{25} --environment ${value["environment"]} --mode ${value["mode"]}$`, "u").test(value["psql_command"]) : value["psql_command"] !== `psql '${uri}'`))
26874
+ if (typeof uri !== "string" || typeof value["psql_command"] !== "string" || !new RegExp(`^ohmyhost database psql --project [0-7][0-9A-HJKMNP-TV-Z]{25} --environment ${value["environment"]} --mode ${value["mode"]}$`, "u").test(value["psql_command"]))
26914
26875
  throw new TypeError("Invalid database access credential");
26915
26876
  let parsed;
26916
26877
  try {
@@ -26918,7 +26879,7 @@ function assertProjectDatabaseAccessCredential(value) {
26918
26879
  } catch {
26919
26880
  throw new TypeError("Invalid database access credential");
26920
26881
  }
26921
- if ((value["provider"] === "pgcf" ? !["postgres:", "postgresql:"].includes(parsed.protocol) : parsed.protocol !== "postgresql:") || decodeURIComponent(parsed.username) !== value["role_name"] || parsed.password === "" || parsed.hostname !== value["host"] || (value["provider"] === "pgcf" ? parsed.port !== "" && parsed.port !== "5432" : parsed.host !== value["host"]) || decodeURIComponent(parsed.pathname.slice(1)) !== value["database"] || parsed.hash !== "" || (value["provider"] === "pgcf" ? !["", "?sslmode=require", "?sslmode=verify-full"].includes(parsed.search) : parsed.search !== "?sslmode=require"))
26882
+ if (!["postgres:", "postgresql:"].includes(parsed.protocol) || decodeURIComponent(parsed.username) !== value["role_name"] || parsed.password === "" || parsed.hostname !== value["host"] || parsed.port !== "" && parsed.port !== "5432" || decodeURIComponent(parsed.pathname.slice(1)) !== value["database"] || parsed.hash !== "" || !["", "?sslmode=require", "?sslmode=verify-full"].includes(parsed.search))
26922
26883
  throw new TypeError("Invalid database access credential");
26923
26884
  }
26924
26885
  function assertProjectDatabaseAccessPage(value) {
@@ -26927,12 +26888,9 @@ function assertProjectDatabaseAccessPage(value) {
26927
26888
  for (const item of value["items"])
26928
26889
  assertProjectDatabaseAccess(item);
26929
26890
  }
26930
- function accessKeys(value) {
26931
- return value["provider"] === "pgcf" ? [...ACCESS_KEYS, "provider", "transport", "websocket_url"] : ACCESS_KEYS;
26932
- }
26933
26891
  function assertAccessFields(value) {
26934
26892
  const revoked = value["revoked_at"], reason = value["revocation_reason"];
26935
- if (typeof value["access_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(value["access_id"]) || !["dev", "prod"].includes(String(value["environment"])) || !["read", "write"].includes(String(value["mode"])) || typeof value["role_name"] !== "string" || !ACCESS_ROLE_PATTERN.test(value["role_name"]) || typeof value["host"] !== "string" || !/^[a-z0-9]([a-z0-9.-]{0,251}[a-z0-9])?$/u.test(value["host"]) || (value["provider"] === "pgcf" ? typeof value["database"] !== "string" || !/^[a-z][a-z0-9]{19}$/u.test(value["database"]) || value["transport"] !== "wss" || value["websocket_url"] !== `wss://${value["host"]}/` : value["database"] !== "neondb") || value["label"] !== null && accessLabel(value["label"]) !== value["label"] || !["active", "expired", "revoked"].includes(String(value["state"])) || !timestamp2(value["issued_at"]) || !timestamp2(value["expires_at"]) || Date.parse(String(value["expires_at"])) <= Date.parse(String(value["issued_at"])) || revoked !== null && !timestamp2(revoked) || revoked === null !== (reason === null) || reason !== null && !["principal", "expired", "budget", "creation_failed", "data_change"].includes(String(reason)) || value["state"] === "revoked" !== (revoked !== null))
26893
+ if (typeof value["access_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(value["access_id"]) || !["dev", "prod"].includes(String(value["environment"])) || !["read", "write"].includes(String(value["mode"])) || typeof value["role_name"] !== "string" || !ACCESS_ROLE_PATTERN.test(value["role_name"]) || typeof value["host"] !== "string" || !/^[a-z0-9]([a-z0-9.-]{0,251}[a-z0-9])?$/u.test(value["host"]) || value["provider"] !== "pgcf" || value["transport"] !== "wss" || value["websocket_url"] !== `wss://${value["host"]}/` || typeof value["database"] !== "string" || !/^[a-z][a-z0-9]{19}$/u.test(value["database"]) || value["label"] !== null && accessLabel(value["label"]) !== value["label"] || !["active", "expired", "revoked"].includes(String(value["state"])) || !timestamp2(value["issued_at"]) || !timestamp2(value["expires_at"]) || Date.parse(String(value["expires_at"])) <= Date.parse(String(value["issued_at"])) || revoked !== null && !timestamp2(revoked) || revoked === null !== (reason === null) || reason !== null && !["principal", "expired", "budget", "creation_failed", "data_change"].includes(String(reason)) || value["state"] === "revoked" !== (revoked !== null))
26936
26894
  throw new TypeError("Invalid database access");
26937
26895
  }
26938
26896
  function accessLabel(value) {
@@ -26955,6 +26913,72 @@ function exact2(value, keys) {
26955
26913
  return Object.keys(value).sort().join(",") === [...keys].sort().join(",");
26956
26914
  }
26957
26915
 
26916
+ // packages/contracts/dist/credit-pricing.js
26917
+ function assertOrganizationCreditUsage(value) {
26918
+ const record8 = (input, keys) => {
26919
+ if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).sort().join() !== keys.split(",").sort().join())
26920
+ throw new TypeError("Invalid usage fields");
26921
+ return input;
26922
+ };
26923
+ const identifier3 = (input) => typeof input === "string" && /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(input);
26924
+ const amount = (input) => typeof input === "string" && /^(0|[1-9][0-9]{0,37})$/u.test(input);
26925
+ const instant2 = (input) => typeof input === "string" && Number.isFinite(Date.parse(input)) && new Date(input).toISOString() === input;
26926
+ const report = record8(value, "organization_id,as_of,unit,period,from,projects,days");
26927
+ if (!identifier3(report["organization_id"]) || !instant2(report["as_of"]) || !instant2(report["from"]) || report["unit"] !== "microcredits" || typeof report["period"] !== "string" || !/^20[0-9]{2}-(0[1-9]|1[0-2])$/u.test(report["period"]) || !Array.isArray(report["projects"]) || report["projects"].length > 1e3 || !Array.isArray(report["days"]) || report["days"].length > 15)
26928
+ throw new TypeError("Invalid usage report");
26929
+ let previous = "";
26930
+ for (const input of report["projects"]) {
26931
+ const project = record8(input, "project_id,used_micros");
26932
+ if (!identifier3(project["project_id"]) || String(project["project_id"]) <= previous || !amount(project["used_micros"]))
26933
+ throw new TypeError("Invalid usage project");
26934
+ previous = String(project["project_id"]);
26935
+ }
26936
+ let previousDay = "";
26937
+ for (const input of report["days"]) {
26938
+ const day = record8(input, "day,projects");
26939
+ if (typeof day["day"] !== "string" || !/^20[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/u.test(day["day"]) || day["day"] <= previousDay || !Array.isArray(day["projects"]) || day["projects"].length > 1e3)
26940
+ throw new TypeError("Invalid usage day");
26941
+ previousDay = day["day"];
26942
+ previous = "";
26943
+ for (const projectInput of day["projects"]) {
26944
+ const project = record8(projectInput, "project_id,meters");
26945
+ if (!identifier3(project["project_id"]) || String(project["project_id"]) <= previous || !Array.isArray(project["meters"]) || project["meters"].length > 1e3)
26946
+ throw new TypeError("Invalid usage project");
26947
+ previous = String(project["project_id"]);
26948
+ for (const meterInput of project["meters"]) {
26949
+ const meter = record8(meterInput, "environment_id,meter,unit,rate_card_id,quantity,charged_micros");
26950
+ if (meter["environment_id"] !== null && !identifier3(meter["environment_id"]))
26951
+ throw new TypeError("Invalid usage environment");
26952
+ for (const key of ["meter", "unit", "rate_card_id"])
26953
+ if (typeof meter[key] !== "string" || !/^[A-Za-z0-9_.:/-]{1,128}$/u.test(meter[key]))
26954
+ throw new TypeError("Invalid usage meter");
26955
+ if (typeof meter["quantity"] !== "string" || !/^(0|[1-9][0-9]{0,29})(\.[0-9]{1,12})?$/u.test(meter["quantity"]) || !amount(meter["charged_micros"]))
26956
+ throw new TypeError("Invalid usage amount");
26957
+ }
26958
+ }
26959
+ }
26960
+ }
26961
+ function assertOrganizationAccount(value) {
26962
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join(",") !== "as_of,available_micros,monthly_micros,name,next_expiry,one_time_micros,organization_id,paid_until,plan,plan_source,reserved_micros,workos_organization_id")
26963
+ throw new TypeError("Invalid account fields");
26964
+ const v = value;
26965
+ if (typeof v["organization_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(v["organization_id"]) || typeof v["name"] !== "string" || v["name"].length > 128 || typeof v["workos_organization_id"] !== "string" || !/^org_[A-Za-z0-9_]+$/u.test(v["workos_organization_id"]) || v["plan"] !== "paid" && v["plan"] !== "free" || !["free", "stripe", "granted", "manual"].includes(String(v["plan_source"])) || v["plan"] === "free" !== (v["plan_source"] === "free"))
26966
+ throw new TypeError("Invalid account scope");
26967
+ for (const field of ["available_micros", "monthly_micros", "one_time_micros", "reserved_micros"])
26968
+ if (typeof v[field] !== "string" || !/^(0|[1-9][0-9]{0,18})$/u.test(v[field]))
26969
+ throw new TypeError("Invalid account credits");
26970
+ const held = BigInt(String(v["reserved_micros"]));
26971
+ const balance = BigInt(String(v["monthly_micros"])) + BigInt(String(v["one_time_micros"]));
26972
+ if (BigInt(String(v["available_micros"])) !== (balance > held ? balance - held : 0n))
26973
+ throw new TypeError("Account credit buckets do not balance");
26974
+ for (const field of ["as_of", "paid_until", "next_expiry"]) {
26975
+ if (field !== "as_of" && v[field] === null)
26976
+ continue;
26977
+ if (typeof v[field] !== "string" || !Number.isFinite(Date.parse(v[field])) || new Date(v[field]).toISOString() !== v[field])
26978
+ throw new TypeError("Invalid account timestamp");
26979
+ }
26980
+ }
26981
+
26958
26982
  // packages/contracts/dist/database-sizes.js
26959
26983
  var DATABASE_SIZES = Object.freeze([
26960
26984
  Object.freeze({
@@ -27059,10 +27083,234 @@ function exact3(v, keys) {
27059
27083
  return Object.keys(v).sort().join(",") === keys.join(",");
27060
27084
  }
27061
27085
 
27086
+ // packages/contracts/dist/database-events.js
27087
+ var DATABASE_WEBHOOK_EVENT_TYPES = [
27088
+ "database.created",
27089
+ "database.ready",
27090
+ "database.woke",
27091
+ "database.slept",
27092
+ "database.suspended",
27093
+ "database.resized",
27094
+ "database.deleted"
27095
+ ];
27096
+ var DATABASE_WEBHOOK_MAX_EVENT_TYPES = 16;
27097
+ var DATABASE_WEBHOOK_MAX_HEADERS = 8;
27098
+ var DATABASE_WEBHOOK_URL_MAX_LENGTH = 2048;
27099
+ var DATABASE_SCHEDULE_MIN_EVERY_SECONDS = 60;
27100
+ var DATABASE_SCHEDULE_MAX_EVERY_SECONDS = 31 * 86400;
27101
+ var DATABASE_SCHEDULE_CRON_MIN_LENGTH = 9;
27102
+ var DATABASE_SCHEDULE_CRON_MAX_LENGTH = 120;
27103
+ var DATABASE_SCHEDULE_MAX_STATEMENTS = 20;
27104
+ var DATABASE_SCHEDULE_STATEMENT_MAX_BYTES = 16 * 1024;
27105
+ var DATABASE_SCHEDULE_STATEMENTS_MAX_BYTES = 64 * 1024;
27106
+ var DATABASE_SCHEDULE_MIN_TIMEOUT_MS = 1e3;
27107
+ var DATABASE_SCHEDULE_MAX_TIMEOUT_MS = 3e4;
27108
+ var DATABASE_SCHEDULE_OUTCOMES = [
27109
+ "succeeded",
27110
+ "failed",
27111
+ "timed_out",
27112
+ "outcome_unknown",
27113
+ "rejected",
27114
+ "skipped_capacity",
27115
+ "skipped_suspended",
27116
+ "skipped_deleted",
27117
+ "skipped_missed"
27118
+ ];
27119
+ var DATABASE_EXECUTION_METRICS = [
27120
+ "schedule_runs_succeeded",
27121
+ "schedule_runs_failed",
27122
+ "schedule_runs_timed_out",
27123
+ "schedule_runs_outcome_unknown",
27124
+ "schedule_runs_rejected",
27125
+ "schedule_runs_skipped",
27126
+ "events_emitted",
27127
+ "event_bytes",
27128
+ "webhook_attempts",
27129
+ "webhook_deliveries_delivered",
27130
+ "webhook_deliveries_dead_lettered"
27131
+ ];
27132
+ var DATABASE_PAGE_MAX_ITEMS = 100;
27133
+ var USAGE_HOUR_MS = 36e5;
27134
+ var USAGE_MAX_RANGE_MS = 31 * 24 * USAGE_HOUR_MS;
27135
+ var WEBHOOK_KEYS = ["id", "environment", "url", "event_types", "header_names", "created_at"];
27136
+ var WEBHOOK_ID_PATTERN = /^whk_[a-z0-9]{20}$/u;
27137
+ var DELIVERY_ID_PATTERN = /^dlv_[0-9a-f]{20}$/u;
27138
+ var EVENT_ID_PATTERN = /^evt_[0-9a-f]{20}$/u;
27139
+ var SCHEDULE_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,62}$/u;
27140
+ var CURSOR_PATTERN = /^[A-Za-z0-9._|:=+/-]{1,200}$/u;
27141
+ var HEADER_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9-]{0,63}$/u;
27142
+ function assertDatabaseWebhook(value) {
27143
+ if (!record4(value) || !exact4(value, WEBHOOK_KEYS))
27144
+ throw new TypeError("Invalid database webhook");
27145
+ assertWebhookFields(value);
27146
+ }
27147
+ function assertDatabaseWebhookCreated(value) {
27148
+ if (!record4(value) || !exact4(value, [...WEBHOOK_KEYS, "secret"]) || typeof value["secret"] !== "string" || value["secret"].length === 0)
27149
+ throw new TypeError("Invalid database webhook");
27150
+ assertWebhookFields(value);
27151
+ }
27152
+ function assertDatabaseWebhookPage(value) {
27153
+ if (!record4(value) || !exact4(value, ["items"]) || !pageItems(value["items"]))
27154
+ throw new TypeError("Invalid database webhook page");
27155
+ for (const item of value["items"])
27156
+ assertDatabaseWebhook(item);
27157
+ }
27158
+ function assertDatabaseWebhookDeleted(value) {
27159
+ if (!record4(value) || !exact4(value, ["id", "deleted"]) || !matches(value["id"], WEBHOOK_ID_PATTERN) || value["deleted"] !== true)
27160
+ throw new TypeError("Invalid database webhook deletion");
27161
+ }
27162
+ function assertDatabaseWebhookDelivery(value) {
27163
+ if (!record4(value) || !exact4(value, [
27164
+ "id",
27165
+ "event_id",
27166
+ "event_type",
27167
+ "webhook_id",
27168
+ "state",
27169
+ "attempts",
27170
+ "created_at",
27171
+ "next_attempt_at",
27172
+ "delivered_at",
27173
+ "last_status",
27174
+ "last_error"
27175
+ ]) || !matches(value["id"], DELIVERY_ID_PATTERN) || !matches(value["event_id"], EVENT_ID_PATTERN) || !oneOf(DATABASE_WEBHOOK_EVENT_TYPES, value["event_type"]) || !matches(value["webhook_id"], WEBHOOK_ID_PATTERN) || !oneOf(["pending", "delivered", "dead_lettered"], value["state"]) || !nonNegativeInteger(value["attempts"]) || !timestamp3(value["created_at"]) || !nullable(value["next_attempt_at"], timestamp3) || !nullable(value["delivered_at"], timestamp3) || !nullable(value["last_status"], Number.isSafeInteger) || !nullable(value["last_error"], (error) => oneOf(["timeout", "network", "http", "expired", "permanent"], error)))
27176
+ throw new TypeError("Invalid database webhook delivery");
27177
+ }
27178
+ function assertDatabaseWebhookDeliveryPage(value) {
27179
+ if (!record4(value) || !exact4(value, ["items", "next_cursor"]) || !pageItems(value["items"]))
27180
+ throw new TypeError("Invalid database webhook delivery page");
27181
+ for (const item of value["items"])
27182
+ assertDatabaseWebhookDelivery(item);
27183
+ if (!nullable(value["next_cursor"], isCursor))
27184
+ throw new TypeError("Invalid database webhook delivery page");
27185
+ }
27186
+ function assertDatabaseWebhookTest(value) {
27187
+ if (!record4(value) || !exact4(value, ["delivered", "status", "error", "duration_ms"]) || typeof value["delivered"] !== "boolean" || !nullable(value["status"], Number.isSafeInteger) || !nullable(value["error"], (error) => oneOf(["timeout", "network", "http"], error)) || !nonNegativeInteger(value["duration_ms"]))
27188
+ throw new TypeError("Invalid database webhook test result");
27189
+ }
27190
+ function assertDatabaseWebhookReplayAccepted(value) {
27191
+ if (!record4(value) || !exact4(value, ["delivery_id", "state"]) || !matches(value["delivery_id"], DELIVERY_ID_PATTERN) || value["state"] !== "pending")
27192
+ throw new TypeError("Invalid database webhook replay");
27193
+ }
27194
+ function assertDatabaseSchedule(value) {
27195
+ if (!record4(value) || !exact4(value, [
27196
+ "name",
27197
+ "environment",
27198
+ "cron",
27199
+ "every_seconds",
27200
+ "statements",
27201
+ "timeout_ms",
27202
+ "enabled",
27203
+ "next_run_at",
27204
+ "created_at"
27205
+ ]) || !matches(value["name"], SCHEDULE_NAME_PATTERN) || !oneOf(["dev", "prod"], value["environment"]) || value["cron"] === null === (value["every_seconds"] === null) || !nullable(value["cron"], isCronText) || !nullable(value["every_seconds"], isEverySeconds) || !Array.isArray(value["statements"]) || value["statements"].length > DATABASE_SCHEDULE_MAX_STATEMENTS || !value["statements"].every((statement) => typeof statement === "string") || !isTimeout(value["timeout_ms"]) || typeof value["enabled"] !== "boolean" || !nullable(value["next_run_at"], timestamp3) || !timestamp3(value["created_at"]))
27206
+ throw new TypeError("Invalid database schedule");
27207
+ }
27208
+ function assertDatabaseSchedulePage(value) {
27209
+ if (!record4(value) || !exact4(value, ["items"]) || !pageItems(value["items"]))
27210
+ throw new TypeError("Invalid database schedule page");
27211
+ for (const item of value["items"])
27212
+ assertDatabaseSchedule(item);
27213
+ }
27214
+ function assertDatabaseScheduleDeleted(value) {
27215
+ if (!record4(value) || !exact4(value, ["name", "deleted"]) || !matches(value["name"], SCHEDULE_NAME_PATTERN) || value["deleted"] !== true)
27216
+ throw new TypeError("Invalid database schedule deletion");
27217
+ }
27218
+ function assertDatabaseScheduleRunPage(value) {
27219
+ if (!record4(value) || !exact4(value, ["items"]) || !pageItems(value["items"]))
27220
+ throw new TypeError("Invalid database schedule run page");
27221
+ for (const item of value["items"])
27222
+ assertDatabaseScheduleRun(item);
27223
+ }
27224
+ function assertDatabaseScheduleRunAccepted(value) {
27225
+ if (!record4(value) || !exact4(value, ["schedule", "state"]) || !matches(value["schedule"], SCHEDULE_NAME_PATTERN) || value["state"] !== "queued")
27226
+ throw new TypeError("Invalid database schedule run");
27227
+ }
27228
+ function assertDatabaseExecutionUsagePage(value) {
27229
+ if (!record4(value) || !exact4(value, ["items", "next_cursor"]) || !pageItems(value["items"]))
27230
+ throw new TypeError("Invalid database execution usage page");
27231
+ for (const row of value["items"])
27232
+ assertUsageRow(row);
27233
+ if (!nullable(value["next_cursor"], isCursor))
27234
+ throw new TypeError("Invalid database execution usage page");
27235
+ }
27236
+ function assertDatabaseScheduleRun(value) {
27237
+ if (!record4(value) || !exact4(value, [
27238
+ "id",
27239
+ "schedule",
27240
+ "scheduled_at",
27241
+ "started_at",
27242
+ "finished_at",
27243
+ "outcome",
27244
+ "sqlstate",
27245
+ "attempts",
27246
+ "manual"
27247
+ ]) || !nonNegativeInteger(value["id"]) || !matches(value["schedule"], SCHEDULE_NAME_PATTERN) || !timestamp3(value["scheduled_at"]) || !nullable(value["started_at"], timestamp3) || !timestamp3(value["finished_at"]) || !oneOf(DATABASE_SCHEDULE_OUTCOMES, value["outcome"]) || !nullable(value["sqlstate"], (state) => typeof state === "string") || !nonNegativeInteger(value["attempts"]) || typeof value["manual"] !== "boolean")
27248
+ throw new TypeError("Invalid database schedule run");
27249
+ }
27250
+ function assertUsageRow(value) {
27251
+ if (!record4(value) || !exact4(value, ["start", "end", "final", "metrics"]) || !timestamp3(value["start"]) || !timestamp3(value["end"]) || typeof value["final"] !== "boolean" || !record4(value["metrics"]) || !exact4(value["metrics"], DATABASE_EXECUTION_METRICS))
27252
+ throw new TypeError("Invalid database execution usage row");
27253
+ const metrics = value["metrics"];
27254
+ if (!DATABASE_EXECUTION_METRICS.every((metric) => nonNegativeInteger(metrics[metric])))
27255
+ throw new TypeError("Invalid database execution usage row");
27256
+ }
27257
+ function assertWebhookFields(value) {
27258
+ if (!matches(value["id"], WEBHOOK_ID_PATTERN) || !oneOf(["dev", "prod"], value["environment"]) || !isHttpsUrl2(value["url"]) || !Array.isArray(value["event_types"]) || value["event_types"].length < 1 || value["event_types"].length > DATABASE_WEBHOOK_MAX_EVENT_TYPES || !value["event_types"].every((type) => oneOf(DATABASE_WEBHOOK_EVENT_TYPES, type)) || !Array.isArray(value["header_names"]) || value["header_names"].length > DATABASE_WEBHOOK_MAX_HEADERS || !value["header_names"].every((name) => matches(name, HEADER_NAME_PATTERN)) || !timestamp3(value["created_at"]))
27259
+ throw new TypeError("Invalid database webhook");
27260
+ }
27261
+ function isHttpsUrl2(value) {
27262
+ if (typeof value !== "string" || value.length > DATABASE_WEBHOOK_URL_MAX_LENGTH)
27263
+ return false;
27264
+ try {
27265
+ return new URL(value).protocol === "https:";
27266
+ } catch {
27267
+ return false;
27268
+ }
27269
+ }
27270
+ function isCronText(value) {
27271
+ return typeof value === "string" && value.length >= DATABASE_SCHEDULE_CRON_MIN_LENGTH && value.length <= DATABASE_SCHEDULE_CRON_MAX_LENGTH;
27272
+ }
27273
+ function isEverySeconds(value) {
27274
+ return Number.isSafeInteger(value) && value >= DATABASE_SCHEDULE_MIN_EVERY_SECONDS && value <= DATABASE_SCHEDULE_MAX_EVERY_SECONDS;
27275
+ }
27276
+ function isTimeout(value) {
27277
+ return Number.isSafeInteger(value) && value >= DATABASE_SCHEDULE_MIN_TIMEOUT_MS && value <= DATABASE_SCHEDULE_MAX_TIMEOUT_MS;
27278
+ }
27279
+ function isCursor(value) {
27280
+ return matches(value, CURSOR_PATTERN);
27281
+ }
27282
+ function pageItems(value) {
27283
+ return Array.isArray(value) && value.length <= DATABASE_PAGE_MAX_ITEMS;
27284
+ }
27285
+ function nonNegativeInteger(value) {
27286
+ return Number.isSafeInteger(value) && value >= 0;
27287
+ }
27288
+ function nullable(value, check) {
27289
+ return value === null || check(value);
27290
+ }
27291
+ function matches(value, pattern) {
27292
+ return typeof value === "string" && pattern.test(value);
27293
+ }
27294
+ function oneOf(allowed, value) {
27295
+ return typeof value === "string" && allowed.includes(value);
27296
+ }
27297
+ function timestamp3(value) {
27298
+ if (typeof value !== "string")
27299
+ return false;
27300
+ const time3 = Date.parse(value);
27301
+ return Number.isFinite(time3) && new Date(time3).toISOString() === value;
27302
+ }
27303
+ function record4(value) {
27304
+ return typeof value === "object" && value !== null && !Array.isArray(value);
27305
+ }
27306
+ function exact4(value, keys) {
27307
+ return Object.keys(value).sort().join(",") === [...keys].sort().join(",");
27308
+ }
27309
+
27062
27310
  // apps/product-cli/package.json
27063
27311
  var package_default2 = {
27064
27312
  name: "@ohmyhost/product-cli",
27065
- version: "0.1.41",
27313
+ version: "0.1.43",
27066
27314
  private: true,
27067
27315
  ohmyhost: {
27068
27316
  deployment: "production",
@@ -27132,32 +27380,32 @@ function isUserSecretName(value, action = "set") {
27132
27380
  }
27133
27381
 
27134
27382
  // packages/contracts/dist/project-context.js
27135
- var record4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
27136
- var timestamp3 = (v) => typeof v === "string" && Number.isFinite(Date.parse(v)) && new Date(v).toISOString() === v;
27383
+ var record5 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
27384
+ var timestamp4 = (v) => typeof v === "string" && Number.isFinite(Date.parse(v)) && new Date(v).toISOString() === v;
27137
27385
  var version = (v) => Number.isInteger(v) && Number(v) >= 0 && Number(v) <= 2147483647;
27138
27386
  var bounded = (v, lines, bytes) => typeof v === "string" && !/[\r\u2028\u2029]/u.test(v) && !new RegExp("\\p{Cc}", "u").test(v.replace(/[\n\t]/gu, "")) && v.split("\n").length <= lines && new TextEncoder().encode(v).length <= bytes;
27139
27387
  function assertProjectNotesReceipt(v) {
27140
- if (!record4(v) || Object.keys(v).sort().join(",") !== "updated_at,version" || !version(v["version"]) || v["version"] === 0 || !timestamp3(v["updated_at"]))
27388
+ if (!record5(v) || Object.keys(v).sort().join(",") !== "updated_at,version" || !version(v["version"]) || v["version"] === 0 || !timestamp4(v["updated_at"]))
27141
27389
  throw new TypeError("Invalid project notes receipt");
27142
27390
  }
27143
27391
  function assertProjectContext(v) {
27144
- if (!record4(v) || Object.keys(v).sort().join(",") !== "credit_access,generated_at,markdown,notes,project_id" || typeof v["project_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(v["project_id"]) || !timestamp3(v["generated_at"]) || !["included", "not_authorized"].includes(String(v["credit_access"])) || !bounded(v["markdown"], 500, 32768))
27392
+ if (!record5(v) || Object.keys(v).sort().join(",") !== "credit_access,generated_at,markdown,notes,project_id" || typeof v["project_id"] !== "string" || !/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(v["project_id"]) || !timestamp4(v["generated_at"]) || !["included", "not_authorized"].includes(String(v["credit_access"])) || !bounded(v["markdown"], 500, 32768))
27145
27393
  throw new TypeError("Invalid project context");
27146
27394
  const notes = v["notes"];
27147
- if (!record4(notes) || Object.keys(notes).sort().join(",") !== "markdown,updated_at,version" || !version(notes["version"]) || !bounded(notes["markdown"], 250, 16384) || (notes["version"] === 0 ? notes["updated_at"] !== null || notes["markdown"] !== "" : !timestamp3(notes["updated_at"])))
27395
+ if (!record5(notes) || Object.keys(notes).sort().join(",") !== "markdown,updated_at,version" || !version(notes["version"]) || !bounded(notes["markdown"], 250, 16384) || (notes["version"] === 0 ? notes["updated_at"] !== null || notes["markdown"] !== "" : !timestamp4(notes["updated_at"])))
27148
27396
  throw new TypeError("Invalid project notes");
27149
27397
  }
27150
27398
 
27151
27399
  // packages/contracts/dist/project-exports.js
27152
27400
  function assertProjectExport(value) {
27153
- if (!record5(value) || Object.keys(value).sort().join(",") !== "archive,error,id,next_poll_after_seconds,next_request_at,project_id,requested_at,state" || typeof value["id"] !== "string" || !id.test(value["id"]) || typeof value["project_id"] !== "string" || !id.test(value["project_id"]) || !["queued", "running", "succeeded", "failed", "cancelled"].includes(String(value["state"])) || !timestamp4(value["requested_at"]) || !timestamp4(value["next_request_at"]))
27401
+ if (!record6(value) || Object.keys(value).sort().join(",") !== "archive,error,id,next_poll_after_seconds,next_request_at,project_id,requested_at,state" || typeof value["id"] !== "string" || !id.test(value["id"]) || typeof value["project_id"] !== "string" || !id.test(value["project_id"]) || !["queued", "running", "succeeded", "failed", "cancelled"].includes(String(value["state"])) || !timestamp5(value["requested_at"]) || !timestamp5(value["next_request_at"]))
27154
27402
  invalid4();
27155
27403
  const active = value["state"] === "queued" || value["state"] === "running";
27156
27404
  if (value["next_poll_after_seconds"] !== (active ? 5 : null))
27157
27405
  invalid4();
27158
27406
  if (value["state"] === "failed") {
27159
27407
  const error = value["error"];
27160
- if (!record5(error) || Object.keys(error).sort().join(",") !== "code,message,retryable,suggested_action" || typeof error["code"] !== "string")
27408
+ if (!record6(error) || Object.keys(error).sort().join(",") !== "code,message,retryable,suggested_action" || typeof error["code"] !== "string")
27161
27409
  invalid4();
27162
27410
  const expected = publicOperationFailure(error["code"]);
27163
27411
  for (const key of Object.keys(expected))
@@ -27171,14 +27419,14 @@ function assertProjectExport(value) {
27171
27419
  invalid4();
27172
27420
  return;
27173
27421
  }
27174
- if (value["state"] !== "succeeded" || !record5(archive) || Object.keys(archive).sort().join(",") !== "bytes,captured_at,download_expires_at,download_url,expires_at,sha256,sql_files" || !Number.isSafeInteger(archive["bytes"]) || Number(archive["bytes"]) < 1 || Number(archive["bytes"]) > 536870912 || typeof archive["sha256"] !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(archive["sha256"]) || !['["dev.sql"]', '["prod.sql"]', '["dev.sql","prod.sql"]', '["shared.sql"]'].includes(JSON.stringify(archive["sql_files"])) || !timestamp4(archive["captured_at"]) || !timestamp4(archive["expires_at"]))
27422
+ if (value["state"] !== "succeeded" || !record6(archive) || Object.keys(archive).sort().join(",") !== "bytes,captured_at,download_expires_at,download_url,expires_at,sha256,sql_files" || !Number.isSafeInteger(archive["bytes"]) || Number(archive["bytes"]) < 1 || Number(archive["bytes"]) > 536870912 || typeof archive["sha256"] !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(archive["sha256"]) || !['["dev.sql"]', '["prod.sql"]', '["dev.sql","prod.sql"]', '["shared.sql"]'].includes(JSON.stringify(archive["sql_files"])) || !timestamp5(archive["captured_at"]) || !timestamp5(archive["expires_at"]))
27175
27423
  invalid4();
27176
27424
  if (archive["download_url"] === null) {
27177
27425
  if (archive["download_expires_at"] !== null)
27178
27426
  invalid4();
27179
27427
  return;
27180
27428
  }
27181
- if (typeof archive["download_url"] !== "string" || !timestamp4(archive["download_expires_at"]) || Date.parse(archive["download_expires_at"]) > Date.parse(archive["expires_at"]))
27429
+ if (typeof archive["download_url"] !== "string" || !timestamp5(archive["download_expires_at"]) || Date.parse(archive["download_expires_at"]) > Date.parse(archive["expires_at"]))
27182
27430
  invalid4();
27183
27431
  let url;
27184
27432
  try {
@@ -27190,10 +27438,10 @@ function assertProjectExport(value) {
27190
27438
  invalid4();
27191
27439
  }
27192
27440
  var id = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
27193
- function record5(value) {
27441
+ function record6(value) {
27194
27442
  return typeof value === "object" && value !== null && !Array.isArray(value);
27195
27443
  }
27196
- function timestamp4(value) {
27444
+ function timestamp5(value) {
27197
27445
  return typeof value === "string" && Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
27198
27446
  }
27199
27447
  function invalid4() {
@@ -27432,11 +27680,11 @@ function assertBillingTaxIssue(value) {
27432
27680
  "billing_tax_location_required",
27433
27681
  "billing_tax_calculation_failed",
27434
27682
  "billing_tax_configuration_required"
27435
- ].includes(String(v["code"])) || typeof v["invoice_id"] !== "string" || !/^in_[A-Za-z0-9_]{1,253}$/u.test(v["invoice_id"]) || !timestamp5(v["observed_at"]) || v["required_action"] !== (v["code"] === "billing_tax_location_required" ? "open_billing_portal" : "contact_support"))
27683
+ ].includes(String(v["code"])) || typeof v["invoice_id"] !== "string" || !/^in_[A-Za-z0-9_]{1,253}$/u.test(v["invoice_id"]) || !timestamp6(v["observed_at"]) || v["required_action"] !== (v["code"] === "billing_tax_location_required" ? "open_billing_portal" : "contact_support"))
27436
27684
  throw new Error("billing_response_invalid");
27437
27685
  }
27438
27686
  var ulid4 = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
27439
- var timestamp5 = (v) => typeof v === "string" && Number.isFinite(Date.parse(v)) && new Date(v).toISOString() === v;
27687
+ var timestamp6 = (v) => typeof v === "string" && Number.isFinite(Date.parse(v)) && new Date(v).toISOString() === v;
27440
27688
  function stripeUrl(value, host2) {
27441
27689
  if (typeof value !== "string" || value.length > 8192)
27442
27690
  return false;
@@ -27451,7 +27699,7 @@ function assertBillingCheckout(value) {
27451
27699
  if (!value || typeof value !== "object" || Array.isArray(value))
27452
27700
  throw new Error("billing_response_invalid");
27453
27701
  const v = value;
27454
- if (Object.keys(v).sort().join(",") !== "billing_issue,checkout_id,credited_micros,expires_at,offer,organization_id,packs,paid_until,payment_confirmed,required_action,revoked_micros,state,url" || typeof v["organization_id"] !== "string" || !ulid4.test(v["organization_id"]) || typeof v["checkout_id"] !== "string" || !ulid4.test(v["checkout_id"]) || typeof v["offer"] !== "string" || !["topup", "paid"].includes(v["offer"]) || typeof v["state"] !== "string" || !["open", "complete", "expired"].includes(v["state"]) || typeof v["payment_confirmed"] !== "boolean" || typeof v["required_action"] !== "string" || !["none", "complete_checkout", "open_billing_portal", "contact_support"].includes(v["required_action"]) || v["url"] !== null && !stripeUrl(v["url"], "checkout.stripe.com") || !timestamp5(v["expires_at"]) || v["paid_until"] !== null && !timestamp5(v["paid_until"]) || !Number.isInteger(v["packs"]) || Number(v["packs"]) < 1 || Number(v["packs"]) > 100 || v["offer"] === "paid" && v["packs"] !== 1 || ![v["credited_micros"], v["revoked_micros"]].every((x) => typeof x === "string" && /^(0|[1-9][0-9]{0,18})$/u.test(x)))
27702
+ if (Object.keys(v).sort().join(",") !== "billing_issue,checkout_id,credited_micros,expires_at,offer,organization_id,packs,paid_until,payment_confirmed,required_action,revoked_micros,state,url" || typeof v["organization_id"] !== "string" || !ulid4.test(v["organization_id"]) || typeof v["checkout_id"] !== "string" || !ulid4.test(v["checkout_id"]) || typeof v["offer"] !== "string" || !["topup", "paid"].includes(v["offer"]) || typeof v["state"] !== "string" || !["open", "complete", "expired"].includes(v["state"]) || typeof v["payment_confirmed"] !== "boolean" || typeof v["required_action"] !== "string" || !["none", "complete_checkout", "open_billing_portal", "contact_support"].includes(v["required_action"]) || v["url"] !== null && !stripeUrl(v["url"], "checkout.stripe.com") || !timestamp6(v["expires_at"]) || v["paid_until"] !== null && !timestamp6(v["paid_until"]) || !Number.isInteger(v["packs"]) || Number(v["packs"]) < 1 || Number(v["packs"]) > 100 || v["offer"] === "paid" && v["packs"] !== 1 || ![v["credited_micros"], v["revoked_micros"]].every((x) => typeof x === "string" && /^(0|[1-9][0-9]{0,18})$/u.test(x)))
27455
27703
  throw new Error("billing_response_invalid");
27456
27704
  assertBillingTaxIssue(v["billing_issue"]);
27457
27705
  }
@@ -27459,7 +27707,7 @@ function assertBillingPortal(value) {
27459
27707
  if (!value || typeof value !== "object" || Array.isArray(value))
27460
27708
  throw new Error("billing_response_invalid");
27461
27709
  const v = value;
27462
- if (Object.keys(v).sort().join(",") !== "created_at,organization_id,url" || typeof v["organization_id"] !== "string" || !ulid4.test(v["organization_id"]) || !timestamp5(v["created_at"]) || !stripeUrl(v["url"], "billing.stripe.com"))
27710
+ if (Object.keys(v).sort().join(",") !== "created_at,organization_id,url" || typeof v["organization_id"] !== "string" || !ulid4.test(v["organization_id"]) || !timestamp6(v["created_at"]) || !stripeUrl(v["url"], "billing.stripe.com"))
27463
27711
  throw new Error("billing_response_invalid");
27464
27712
  }
27465
27713
  function assertRecharge(value) {
@@ -28176,6 +28424,20 @@ var HELP_USAGE = Object.freeze({
28176
28424
  "database access create": "ohmyhost database access create --project ULID --environment dev|prod [--mode read|write] [--ttl 5m|1h|24h|SECONDS] [--label TEXT] --yes --json\n The connection URI is shown once. Use it immediately, never store it in files, notes or source, and revoke it when finished.",
28177
28425
  "database access list": "ohmyhost database access list --project ULID [--environment dev|prod] --json",
28178
28426
  "database access revoke": "ohmyhost database access revoke --project ULID --access ULID --yes --json",
28427
+ "database webhook create": "ohmyhost database webhook create --project ULID --environment dev|prod --url HTTPS_URL --event-types TYPE[,TYPE] [--headers-file PATH] --idempotency-key KEY --yes --json (the signing secret is shown once in this answer; types: database.created, database.ready, database.woke, database.slept, database.suspended, database.resized, database.deleted; the headers file is a UTF-8 JSON object of at most 8 KiB)",
28428
+ "database webhook list": "ohmyhost database webhook list --project ULID [--environment dev|prod] --json (dev when omitted; the secret is never listed)",
28429
+ "database webhook get": "ohmyhost database webhook get --project ULID [--environment dev|prod] --webhook ID --json",
28430
+ "database webhook delete": "ohmyhost database webhook delete --project ULID --environment dev|prod --webhook ID --yes --json",
28431
+ "database webhook test": "ohmyhost database webhook test --project ULID --environment dev|prod --webhook ID --yes --json (sends one signed test request to the receiver; nothing is stored)",
28432
+ "database webhook deliveries": "ohmyhost database webhook deliveries --project ULID [--environment dev|prod] [--webhook ID] [--limit 1..100] [--cursor CURSOR] --json",
28433
+ "database webhook replay": "ohmyhost database webhook replay --project ULID --environment dev|prod --delivery ID --yes --json",
28434
+ "database schedule set": "ohmyhost database schedule set --project ULID --environment dev|prod --name NAME (--cron EXPR | --every-seconds N) --statements-file PATH [--timeout-ms N] [--enabled true|false] --yes --json (runs the statements in the file, a UTF-8 JSON array of 1 to 20 SQL strings, as the runtime role of the application; cron has five fields in UTC; every-seconds is 60 to 2678400; timeout-ms is 1000 to 30000, default 10000)",
28435
+ "database schedule list": "ohmyhost database schedule list --project ULID [--environment dev|prod] --json (dev when omitted)",
28436
+ "database schedule get": "ohmyhost database schedule get --project ULID [--environment dev|prod] --name NAME --json",
28437
+ "database schedule delete": "ohmyhost database schedule delete --project ULID --environment dev|prod --name NAME --yes --json",
28438
+ "database schedule runs": "ohmyhost database schedule runs --project ULID [--environment dev|prod] --name NAME [--limit 1..50] --json",
28439
+ "database schedule run": "ohmyhost database schedule run --project ULID --environment dev|prod --name NAME --yes --json (queues one run now, in addition to the timer)",
28440
+ "database executions": "ohmyhost database executions --project ULID [--environment dev|prod] --from ISO --to ISO --granularity hour|day [--limit 1..100] [--cursor CURSOR] --json (UTC timestamps like 2026-10-30T00:00:00.000Z aligned to the granularity, at most 31 days; counts schedule runs, webhook attempts and events per hour or day; usage counters only, nothing is charged for them until the operator prices them)",
28179
28441
  "database psql": "ohmyhost database psql --project ULID --environment dev|prod [--mode read|write] [--ttl 5m|1h|24h|SECONDS] [--json] (starts local psql with a temporary credential and revokes it on exit)",
28180
28442
  link: "ohmyhost link --project ULID --repository-owner OWNER --repository-name REPOSITORY --idempotency-key KEY --json (uses the workspace GitHub connection and waits for the source-link operation)",
28181
28443
  "source auto-deploy set": "ohmyhost source auto-deploy set --project ULID --branch BRANCH --enabled true|false --idempotency-key KEY --json",
@@ -28304,12 +28566,12 @@ function buildClientParams(args, fields) {
28304
28566
  };
28305
28567
  const map = buildKeyMap(fields);
28306
28568
  function writeSlot(slot, key, value) {
28307
- let record7 = params[slot];
28308
- if (record7 === void 0) {
28309
- record7 = /* @__PURE__ */ Object.create(null);
28310
- params[slot] = record7;
28569
+ let record8 = params[slot];
28570
+ if (record8 === void 0) {
28571
+ record8 = /* @__PURE__ */ Object.create(null);
28572
+ params[slot] = record8;
28311
28573
  }
28312
- record7[key] = value;
28574
+ record8[key] = value;
28313
28575
  }
28314
28576
  let config;
28315
28577
  for (const [index, arg] of args.entries()) {
@@ -28586,9 +28848,9 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
28586
28848
  var PATH_PARAM_RE = /\{[^{}]+\}/g;
28587
28849
  var defaultPathSerializer = ({ path: path2, url: _url }) => {
28588
28850
  let url = _url;
28589
- const matches = _url.match(PATH_PARAM_RE);
28590
- if (matches) {
28591
- for (const match of matches) {
28851
+ const matches2 = _url.match(PATH_PARAM_RE);
28852
+ if (matches2) {
28853
+ for (const match of matches2) {
28592
28854
  let explode = false;
28593
28855
  let name = match.substring(1, match.length - 1);
28594
28856
  let style = "simple";
@@ -30956,6 +31218,289 @@ var revokeProjectDatabaseAccess = (parameters, options) => {
30956
31218
  ...params
30957
31219
  });
30958
31220
  };
31221
+ var listProjectDatabaseWebhooks = (parameters, options) => {
31222
+ const params = buildClientParams([parameters], [
31223
+ {
31224
+ args: [
31225
+ { in: "headers", key: "X-Request-Id" },
31226
+ { in: "path", key: "project_id" },
31227
+ { in: "query", key: "environment" }
31228
+ ]
31229
+ }
31230
+ ]);
31231
+ return (options?.client ?? client).get({
31232
+ responseStyle: "data",
31233
+ security: [{ scheme: "bearer", type: "http" }],
31234
+ url: "/v1/projects/{project_id}/database/webhooks",
31235
+ ...options,
31236
+ ...params
31237
+ });
31238
+ };
31239
+ var createProjectDatabaseWebhook = (parameters, options) => {
31240
+ const params = buildClientParams([parameters], [
31241
+ {
31242
+ args: [
31243
+ { in: "headers", key: "X-Request-Id" },
31244
+ { in: "headers", key: "Idempotency-Key" },
31245
+ { in: "path", key: "project_id" },
31246
+ { in: "query", key: "environment" },
31247
+ { key: "databaseWebhookCreateRequest", map: "body" }
31248
+ ]
31249
+ }
31250
+ ]);
31251
+ return (options?.client ?? client).post({
31252
+ responseStyle: "data",
31253
+ security: [{ scheme: "bearer", type: "http" }],
31254
+ url: "/v1/projects/{project_id}/database/webhooks",
31255
+ ...options,
31256
+ ...params,
31257
+ headers: {
31258
+ "Content-Type": "application/json",
31259
+ ...options?.headers,
31260
+ ...params.headers
31261
+ }
31262
+ });
31263
+ };
31264
+ var deleteProjectDatabaseWebhook = (parameters, options) => {
31265
+ const params = buildClientParams([parameters], [
31266
+ {
31267
+ args: [
31268
+ { in: "headers", key: "X-Request-Id" },
31269
+ { in: "path", key: "project_id" },
31270
+ { in: "path", key: "webhook_id" },
31271
+ { in: "query", key: "environment" }
31272
+ ]
31273
+ }
31274
+ ]);
31275
+ return (options?.client ?? client).delete({
31276
+ responseStyle: "data",
31277
+ security: [{ scheme: "bearer", type: "http" }],
31278
+ url: "/v1/projects/{project_id}/database/webhooks/{webhook_id}",
31279
+ ...options,
31280
+ ...params
31281
+ });
31282
+ };
31283
+ var getProjectDatabaseWebhook = (parameters, options) => {
31284
+ const params = buildClientParams([parameters], [
31285
+ {
31286
+ args: [
31287
+ { in: "headers", key: "X-Request-Id" },
31288
+ { in: "path", key: "project_id" },
31289
+ { in: "path", key: "webhook_id" },
31290
+ { in: "query", key: "environment" }
31291
+ ]
31292
+ }
31293
+ ]);
31294
+ return (options?.client ?? client).get({
31295
+ responseStyle: "data",
31296
+ security: [{ scheme: "bearer", type: "http" }],
31297
+ url: "/v1/projects/{project_id}/database/webhooks/{webhook_id}",
31298
+ ...options,
31299
+ ...params
31300
+ });
31301
+ };
31302
+ var testProjectDatabaseWebhook = (parameters, options) => {
31303
+ const params = buildClientParams([parameters], [
31304
+ {
31305
+ args: [
31306
+ { in: "headers", key: "X-Request-Id" },
31307
+ { in: "path", key: "project_id" },
31308
+ { in: "path", key: "webhook_id" },
31309
+ { in: "query", key: "environment" }
31310
+ ]
31311
+ }
31312
+ ]);
31313
+ return (options?.client ?? client).post({
31314
+ responseStyle: "data",
31315
+ security: [{ scheme: "bearer", type: "http" }],
31316
+ url: "/v1/projects/{project_id}/database/webhooks/{webhook_id}/test",
31317
+ ...options,
31318
+ ...params
31319
+ });
31320
+ };
31321
+ var listProjectDatabaseWebhookDeliveries = (parameters, options) => {
31322
+ const params = buildClientParams([parameters], [
31323
+ {
31324
+ args: [
31325
+ { in: "headers", key: "X-Request-Id" },
31326
+ { in: "path", key: "project_id" },
31327
+ { in: "query", key: "environment" },
31328
+ { in: "query", key: "webhook_id" },
31329
+ { in: "query", key: "limit" },
31330
+ { in: "query", key: "cursor" }
31331
+ ]
31332
+ }
31333
+ ]);
31334
+ return (options?.client ?? client).get({
31335
+ responseStyle: "data",
31336
+ security: [{ scheme: "bearer", type: "http" }],
31337
+ url: "/v1/projects/{project_id}/database/webhook-deliveries",
31338
+ ...options,
31339
+ ...params
31340
+ });
31341
+ };
31342
+ var replayProjectDatabaseWebhookDelivery = (parameters, options) => {
31343
+ const params = buildClientParams([parameters], [
31344
+ {
31345
+ args: [
31346
+ { in: "headers", key: "X-Request-Id" },
31347
+ { in: "path", key: "project_id" },
31348
+ { in: "path", key: "delivery_id" },
31349
+ { in: "query", key: "environment" }
31350
+ ]
31351
+ }
31352
+ ]);
31353
+ return (options?.client ?? client).post({
31354
+ responseStyle: "data",
31355
+ security: [{ scheme: "bearer", type: "http" }],
31356
+ url: "/v1/projects/{project_id}/database/webhook-deliveries/{delivery_id}/replay",
31357
+ ...options,
31358
+ ...params
31359
+ });
31360
+ };
31361
+ var listProjectDatabaseSchedules = (parameters, options) => {
31362
+ const params = buildClientParams([parameters], [
31363
+ {
31364
+ args: [
31365
+ { in: "headers", key: "X-Request-Id" },
31366
+ { in: "path", key: "project_id" },
31367
+ { in: "query", key: "environment" }
31368
+ ]
31369
+ }
31370
+ ]);
31371
+ return (options?.client ?? client).get({
31372
+ responseStyle: "data",
31373
+ security: [{ scheme: "bearer", type: "http" }],
31374
+ url: "/v1/projects/{project_id}/database/schedules",
31375
+ ...options,
31376
+ ...params
31377
+ });
31378
+ };
31379
+ var deleteProjectDatabaseSchedule = (parameters, options) => {
31380
+ const params = buildClientParams([parameters], [
31381
+ {
31382
+ args: [
31383
+ { in: "headers", key: "X-Request-Id" },
31384
+ { in: "path", key: "project_id" },
31385
+ { in: "path", key: "name" },
31386
+ { in: "query", key: "environment" }
31387
+ ]
31388
+ }
31389
+ ]);
31390
+ return (options?.client ?? client).delete({
31391
+ responseStyle: "data",
31392
+ security: [{ scheme: "bearer", type: "http" }],
31393
+ url: "/v1/projects/{project_id}/database/schedules/{name}",
31394
+ ...options,
31395
+ ...params
31396
+ });
31397
+ };
31398
+ var getProjectDatabaseSchedule = (parameters, options) => {
31399
+ const params = buildClientParams([parameters], [
31400
+ {
31401
+ args: [
31402
+ { in: "headers", key: "X-Request-Id" },
31403
+ { in: "path", key: "project_id" },
31404
+ { in: "path", key: "name" },
31405
+ { in: "query", key: "environment" }
31406
+ ]
31407
+ }
31408
+ ]);
31409
+ return (options?.client ?? client).get({
31410
+ responseStyle: "data",
31411
+ security: [{ scheme: "bearer", type: "http" }],
31412
+ url: "/v1/projects/{project_id}/database/schedules/{name}",
31413
+ ...options,
31414
+ ...params
31415
+ });
31416
+ };
31417
+ var setProjectDatabaseSchedule = (parameters, options) => {
31418
+ const params = buildClientParams([parameters], [
31419
+ {
31420
+ args: [
31421
+ { in: "headers", key: "X-Request-Id" },
31422
+ { in: "path", key: "project_id" },
31423
+ { in: "path", key: "name" },
31424
+ { in: "query", key: "environment" },
31425
+ { key: "databaseScheduleSetRequest", map: "body" }
31426
+ ]
31427
+ }
31428
+ ]);
31429
+ return (options?.client ?? client).put({
31430
+ responseStyle: "data",
31431
+ security: [{ scheme: "bearer", type: "http" }],
31432
+ url: "/v1/projects/{project_id}/database/schedules/{name}",
31433
+ ...options,
31434
+ ...params,
31435
+ headers: {
31436
+ "Content-Type": "application/json",
31437
+ ...options?.headers,
31438
+ ...params.headers
31439
+ }
31440
+ });
31441
+ };
31442
+ var listProjectDatabaseScheduleRuns = (parameters, options) => {
31443
+ const params = buildClientParams([parameters], [
31444
+ {
31445
+ args: [
31446
+ { in: "headers", key: "X-Request-Id" },
31447
+ { in: "path", key: "project_id" },
31448
+ { in: "path", key: "name" },
31449
+ { in: "query", key: "environment" },
31450
+ { in: "query", key: "limit" }
31451
+ ]
31452
+ }
31453
+ ]);
31454
+ return (options?.client ?? client).get({
31455
+ responseStyle: "data",
31456
+ security: [{ scheme: "bearer", type: "http" }],
31457
+ url: "/v1/projects/{project_id}/database/schedules/{name}/runs",
31458
+ ...options,
31459
+ ...params
31460
+ });
31461
+ };
31462
+ var runProjectDatabaseSchedule = (parameters, options) => {
31463
+ const params = buildClientParams([parameters], [
31464
+ {
31465
+ args: [
31466
+ { in: "headers", key: "X-Request-Id" },
31467
+ { in: "path", key: "project_id" },
31468
+ { in: "path", key: "name" },
31469
+ { in: "query", key: "environment" }
31470
+ ]
31471
+ }
31472
+ ]);
31473
+ return (options?.client ?? client).post({
31474
+ responseStyle: "data",
31475
+ security: [{ scheme: "bearer", type: "http" }],
31476
+ url: "/v1/projects/{project_id}/database/schedules/{name}/run",
31477
+ ...options,
31478
+ ...params
31479
+ });
31480
+ };
31481
+ var getProjectDatabaseExecutionUsage = (parameters, options) => {
31482
+ const params = buildClientParams([parameters], [
31483
+ {
31484
+ args: [
31485
+ { in: "headers", key: "X-Request-Id" },
31486
+ { in: "path", key: "project_id" },
31487
+ { in: "query", key: "environment" },
31488
+ { in: "query", key: "from" },
31489
+ { in: "query", key: "to" },
31490
+ { in: "query", key: "granularity" },
31491
+ { in: "query", key: "limit" },
31492
+ { in: "query", key: "cursor" }
31493
+ ]
31494
+ }
31495
+ ]);
31496
+ return (options?.client ?? client).get({
31497
+ responseStyle: "data",
31498
+ security: [{ scheme: "bearer", type: "http" }],
31499
+ url: "/v1/projects/{project_id}/database/execution-usage",
31500
+ ...options,
31501
+ ...params
31502
+ });
31503
+ };
30959
31504
  var planDeploymentRollback = (parameters, options) => {
30960
31505
  const params = buildClientParams([parameters], [
30961
31506
  {
@@ -31407,7 +31952,7 @@ var ULID3 = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
31407
31952
  function assertManagedMailResponse(value, input) {
31408
31953
  const r = object2(value);
31409
31954
  if (input.action === "configure" || input.action === "status" || input.action === "webhook_verify") {
31410
- exact4(r, [
31955
+ exact5(r, [
31411
31956
  "domain_id",
31412
31957
  "domain",
31413
31958
  "environment_id",
@@ -31437,14 +31982,14 @@ function assertManagedMailResponse(value, input) {
31437
31982
  invalid5();
31438
31983
  if (r["webhook"] !== null) {
31439
31984
  const hook = object2(r["webhook"]);
31440
- exact4(hook, ["url", "verified"]);
31985
+ exact5(hook, ["url", "verified"]);
31441
31986
  https(hook["url"]);
31442
31987
  if (typeof hook["verified"] !== "boolean")
31443
31988
  invalid5();
31444
31989
  }
31445
31990
  if (r["dns"] !== void 0) {
31446
31991
  const dns = object2(r["dns"]);
31447
- exact4(dns, ["status", "records"]);
31992
+ exact5(dns, ["status", "records"]);
31448
31993
  if (!["configured", "action_required", "conflict"].includes(String(dns["status"])))
31449
31994
  invalid5();
31450
31995
  records(dns["records"]);
@@ -31452,19 +31997,19 @@ function assertManagedMailResponse(value, input) {
31452
31997
  return;
31453
31998
  }
31454
31999
  if (input.action === "webhook_set") {
31455
- exact4(r, ["url", "signing_secret", "status"]);
32000
+ exact5(r, ["url", "signing_secret", "status"]);
31456
32001
  if (r["url"] !== input.url || r["status"] !== "verification_required" || typeof r["signing_secret"] !== "string" || !/^whsec_[A-Za-z0-9+/]{43}=$/u.test(r["signing_secret"]))
31457
32002
  invalid5();
31458
32003
  return;
31459
32004
  }
31460
32005
  if (input.action === "webhook_disable") {
31461
- exact4(r, ["status"]);
32006
+ exact5(r, ["status"]);
31462
32007
  if (r["status"] !== "disabled")
31463
32008
  invalid5();
31464
32009
  return;
31465
32010
  }
31466
32011
  if (input.action === "domain_delete") {
31467
- exact4(r, ["status", "domain", "dns_records"]);
32012
+ exact5(r, ["status", "domain", "dns_records"]);
31468
32013
  if (r["status"] !== "deleted")
31469
32014
  invalid5();
31470
32015
  domain(r["domain"]);
@@ -31472,12 +32017,12 @@ function assertManagedMailResponse(value, input) {
31472
32017
  return;
31473
32018
  }
31474
32019
  if (input.action === "messages_list") {
31475
- exact4(r, ["items"]);
32020
+ exact5(r, ["items"]);
31476
32021
  if (!Array.isArray(r["items"]) || r["items"].length > 50)
31477
32022
  invalid5();
31478
32023
  for (const value2 of r["items"]) {
31479
32024
  const item = object2(value2);
31480
- exact4(item, ["message_id", "received_at", "state", "attempts"]);
32025
+ exact5(item, ["message_id", "received_at", "state", "attempts"]);
31481
32026
  id2(item["message_id"]);
31482
32027
  time(item["received_at"]);
31483
32028
  if (!["pending", "delivering", "delivered", "delivery_failed", "expired"].includes(String(item["state"])) || !Number.isInteger(item["attempts"]) || Number(item["attempts"]) < 0 || Number(item["attempts"]) > 4)
@@ -31486,7 +32031,7 @@ function assertManagedMailResponse(value, input) {
31486
32031
  return;
31487
32032
  }
31488
32033
  if (input.action === "message_retry") {
31489
- exact4(r, ["attempted"], ["delivered"]);
32034
+ exact5(r, ["attempted"], ["delivered"]);
31490
32035
  if (typeof r["attempted"] !== "boolean" || r["delivered"] !== void 0 && typeof r["delivered"] !== "boolean")
31491
32036
  invalid5();
31492
32037
  return;
@@ -31494,10 +32039,10 @@ function assertManagedMailResponse(value, input) {
31494
32039
  if (input.action !== "message_get")
31495
32040
  invalid5();
31496
32041
  if (r["status"] === "expired") {
31497
- exact4(r, ["status"]);
32042
+ exact5(r, ["status"]);
31498
32043
  return;
31499
32044
  }
31500
- exact4(r, [
32045
+ exact5(r, [
31501
32046
  "id",
31502
32047
  "domain",
31503
32048
  "received_at",
@@ -31529,7 +32074,7 @@ function assertManagedMailResponse(value, input) {
31529
32074
  invalid5();
31530
32075
  for (const value2 of r["attachments"]) {
31531
32076
  const a = object2(value2);
31532
- exact4(a, ["id", "filename", "content_type", "download_path"]);
32077
+ exact5(a, ["id", "filename", "content_type", "download_path"]);
31533
32078
  if (typeof a["id"] !== "string" || !/^[A-Za-z0-9_-]{1,128}$/u.test(a["id"]) || a["filename"] !== null && typeof a["filename"] !== "string" || typeof a["content_type"] !== "string" || a["download_path"] !== `/v1/projects/${input.projectId}/environments/${input.environmentId}/mail/messages/${input.messageId}/attachments/${a["id"]}`)
31534
32079
  invalid5();
31535
32080
  }
@@ -31539,7 +32084,7 @@ function object2(v) {
31539
32084
  invalid5();
31540
32085
  return v;
31541
32086
  }
31542
- function exact4(v, required, optional = []) {
32087
+ function exact5(v, required, optional = []) {
31543
32088
  if (required.some((k) => !(k in v)) || Object.keys(v).some((k) => !required.includes(k) && !optional.includes(k)))
31544
32089
  invalid5();
31545
32090
  }
@@ -31564,7 +32109,7 @@ function records(v) {
31564
32109
  invalid5();
31565
32110
  for (const value of v) {
31566
32111
  const r = object2(value);
31567
- exact4(r, ["type", "name", "value", "purpose", "status"], ["priority"]);
32112
+ exact5(r, ["type", "name", "value", "purpose", "status"], ["priority"]);
31568
32113
  if (!["TXT", "CNAME", "MX"].includes(String(r["type"])) || ["name", "value", "purpose", "status"].some((k) => typeof r[k] !== "string") || r["type"] === "MX" && (!Number.isInteger(r["priority"]) || Number(r["priority"]) < 0 || Number(r["priority"]) > 65535))
31569
32114
  invalid5();
31570
32115
  }
@@ -31621,7 +32166,7 @@ var HOST = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}
31621
32166
  function assertSharedMailResponse(value, input) {
31622
32167
  const v = object3(value);
31623
32168
  if (input.action === "domains_list") {
31624
- exact5(v, ["items"]);
32169
+ exact6(v, ["items"]);
31625
32170
  if (!Array.isArray(v["items"]) || v["items"].length > 100)
31626
32171
  invalid6();
31627
32172
  for (const item of v["items"])
@@ -31633,7 +32178,7 @@ function assertSharedMailResponse(value, input) {
31633
32178
  return;
31634
32179
  }
31635
32180
  if (["domain_get", "domain_create", "domain_retire"].includes(input.action)) {
31636
- exact5(v, [
32181
+ exact6(v, [
31637
32182
  "domain_id",
31638
32183
  "organization_id",
31639
32184
  "domain",
@@ -31666,7 +32211,7 @@ function assertSharedMailResponse(value, input) {
31666
32211
  invalid6();
31667
32212
  for (const entry of v["dns_records"]) {
31668
32213
  const r = object3(entry);
31669
- exact5(r, ["type", "name", "value", "purpose", "status"], ["priority"]);
32214
+ exact6(r, ["type", "name", "value", "purpose", "status"], ["priority"]);
31670
32215
  member(r["type"], ["TXT", "MX", "CNAME"]);
31671
32216
  for (const k of ["name", "value", "purpose", "status"])
31672
32217
  if (typeof r[k] !== "string" || /[\r\n\0]/u.test(r[k]))
@@ -31679,7 +32224,7 @@ function assertSharedMailResponse(value, input) {
31679
32224
  return;
31680
32225
  }
31681
32226
  if (["binding_get", "binding_set", "binding_detach"].includes(input.action)) {
31682
- exact5(v, [
32227
+ exact6(v, [
31683
32228
  "mail_domain_id",
31684
32229
  "organization_id",
31685
32230
  "project_id",
@@ -31713,7 +32258,7 @@ function assertSharedMailResponse(value, input) {
31713
32258
  invalid6();
31714
32259
  if (v["application_domain_identity"] !== null) {
31715
32260
  const identity = object3(v["application_domain_identity"]);
31716
- exact5(identity, ["hostname", "registrable_domain", "revision", "status"]);
32261
+ exact6(identity, ["hostname", "registrable_domain", "revision", "status"]);
31717
32262
  host(identity["hostname"]);
31718
32263
  host(identity["registrable_domain"]);
31719
32264
  positive(identity["revision"]);
@@ -31722,7 +32267,7 @@ function assertSharedMailResponse(value, input) {
31722
32267
  return;
31723
32268
  }
31724
32269
  if (["identity_get", "identity_declare", "identity_verify", "identity_revoke"].includes(input.action)) {
31725
- exact5(v, [
32270
+ exact6(v, [
31726
32271
  "organization_id",
31727
32272
  "project_id",
31728
32273
  "hostname",
@@ -31742,7 +32287,7 @@ function assertSharedMailResponse(value, input) {
31742
32287
  positive(v["revision"]);
31743
32288
  member(v["status"], ["pending", "verified", "expired", "revoked"]);
31744
32289
  const challenge = object3(v["challenge"]);
31745
- exact5(challenge, ["type", "name", "value"]);
32290
+ exact6(challenge, ["type", "name", "value"]);
31746
32291
  if (challenge["type"] !== "TXT" || typeof challenge["name"] !== "string" || challenge["name"] !== `_omh-project.${v["hostname"]}` || typeof challenge["value"] !== "string" || challenge["value"].length < 16 || challenge["value"].length > 255 || /[\r\n\0]/u.test(challenge["value"]))
31747
32292
  invalid6();
31748
32293
  if (v["verified_at"] !== null)
@@ -31751,14 +32296,14 @@ function assertSharedMailResponse(value, input) {
31751
32296
  return;
31752
32297
  }
31753
32298
  if (input.action === "domain_dns_authorize" || input.action === "identity_authorize") {
31754
- exact5(v, ["authorization_id", "authorization_url", "expires_at"]);
32299
+ exact6(v, ["authorization_id", "authorization_url", "expires_at"]);
31755
32300
  id3(v["authorization_id"]);
31756
32301
  time2(v["expires_at"]);
31757
32302
  if (typeof v["authorization_url"] !== "string" || !/^https:\/\/dash\.cloudflare\.com\/oauth2\/auth\?/u.test(v["authorization_url"]))
31758
32303
  invalid6();
31759
32304
  return;
31760
32305
  }
31761
- exact5(v, ["status", "zone", "scopes", "expires_at"]);
32306
+ exact6(v, ["status", "zone", "scopes", "expires_at"]);
31762
32307
  member(v["status"], ["not_authorized", "pending", "authorized", "expired", "revoked"]);
31763
32308
  if (!Array.isArray(v["scopes"]) || v["scopes"].length > 2 || new Set(v["scopes"]).size !== v["scopes"].length || v["scopes"].some((s) => s !== "dns.write" && s !== "zone.read"))
31764
32309
  invalid6();
@@ -31774,7 +32319,7 @@ function object3(v) {
31774
32319
  invalid6();
31775
32320
  return v;
31776
32321
  }
31777
- function exact5(v, required, optional = []) {
32322
+ function exact6(v, required, optional = []) {
31778
32323
  if (required.some((k) => !(k in v)) || Object.keys(v).some((k) => !required.includes(k) && !optional.includes(k)))
31779
32324
  invalid6();
31780
32325
  }
@@ -32076,6 +32621,8 @@ function checkedResponse(kind, value) {
32076
32621
  }
32077
32622
 
32078
32623
  // apps/product-cli/dist/product-api.js
32624
+ var WEBHOOK_SCOPE_MISMATCH = "Webhook response scope mismatch";
32625
+ var SCHEDULE_SCOPE_MISMATCH = "Schedule response scope mismatch";
32079
32626
  var GeneratedSdkProductApi = class {
32080
32627
  #client;
32081
32628
  managedSource;
@@ -32272,6 +32819,159 @@ var GeneratedSdkProductApi = class {
32272
32819
  assertProjectDatabaseAccess(value);
32273
32820
  return value;
32274
32821
  }
32822
+ /** The signing secret exists only in this answer; the CLI prints it once and stores nothing. */
32823
+ async createProjectDatabaseWebhook(input) {
32824
+ const value = await createProjectDatabaseWebhook({
32825
+ project_id: input.projectId,
32826
+ environment: input.environment,
32827
+ "Idempotency-Key": input.idempotencyKey,
32828
+ databaseWebhookCreateRequest: {
32829
+ url: input.url,
32830
+ event_types: [...input.eventTypes],
32831
+ headers: { ...input.headers }
32832
+ }
32833
+ }, { client: this.#client });
32834
+ assertDatabaseWebhookCreated(value);
32835
+ if (value.environment !== input.environment)
32836
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
32837
+ return value;
32838
+ }
32839
+ async listProjectDatabaseWebhooks(input) {
32840
+ const value = await listProjectDatabaseWebhooks({ project_id: input.projectId, environment: input.environment }, { client: this.#client });
32841
+ assertDatabaseWebhookPage(value);
32842
+ if (value.items.some((item) => item.environment !== input.environment))
32843
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
32844
+ return value;
32845
+ }
32846
+ async getProjectDatabaseWebhook(input) {
32847
+ const value = await getProjectDatabaseWebhook({
32848
+ project_id: input.projectId,
32849
+ environment: input.environment,
32850
+ webhook_id: input.webhookId
32851
+ }, { client: this.#client });
32852
+ assertDatabaseWebhook(value);
32853
+ if (value.id !== input.webhookId || value.environment !== input.environment)
32854
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
32855
+ return value;
32856
+ }
32857
+ async deleteProjectDatabaseWebhook(input) {
32858
+ const value = await deleteProjectDatabaseWebhook({
32859
+ project_id: input.projectId,
32860
+ environment: input.environment,
32861
+ webhook_id: input.webhookId
32862
+ }, { client: this.#client });
32863
+ assertDatabaseWebhookDeleted(value);
32864
+ if (value.id !== input.webhookId)
32865
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
32866
+ return value;
32867
+ }
32868
+ async testProjectDatabaseWebhook(input) {
32869
+ const value = await testProjectDatabaseWebhook({
32870
+ project_id: input.projectId,
32871
+ environment: input.environment,
32872
+ webhook_id: input.webhookId
32873
+ }, { client: this.#client });
32874
+ assertDatabaseWebhookTest(value);
32875
+ return value;
32876
+ }
32877
+ async listProjectDatabaseWebhookDeliveries(input) {
32878
+ const value = await listProjectDatabaseWebhookDeliveries({
32879
+ project_id: input.projectId,
32880
+ environment: input.environment,
32881
+ ...input.webhookId === void 0 ? {} : { webhook_id: input.webhookId },
32882
+ ...input.limit === void 0 ? {} : { limit: input.limit },
32883
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor }
32884
+ }, { client: this.#client });
32885
+ assertDatabaseWebhookDeliveryPage(value);
32886
+ if (input.webhookId !== void 0 && value.items.some((item) => item.webhook_id !== input.webhookId))
32887
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
32888
+ return value;
32889
+ }
32890
+ async replayProjectDatabaseWebhookDelivery(input) {
32891
+ const value = await replayProjectDatabaseWebhookDelivery({
32892
+ project_id: input.projectId,
32893
+ environment: input.environment,
32894
+ delivery_id: input.deliveryId
32895
+ }, { client: this.#client });
32896
+ assertDatabaseWebhookReplayAccepted(value);
32897
+ if (value.delivery_id !== input.deliveryId)
32898
+ throw new TypeError(WEBHOOK_SCOPE_MISMATCH);
32899
+ return value;
32900
+ }
32901
+ /** A schedule runs the statements as the application's runtime role; the request confirms it. */
32902
+ async setProjectDatabaseSchedule(input) {
32903
+ const request = input.request;
32904
+ const value = await setProjectDatabaseSchedule({
32905
+ project_id: input.projectId,
32906
+ environment: input.environment,
32907
+ name: input.name,
32908
+ databaseScheduleSetRequest: {
32909
+ ...request.cron === null ? {} : { cron: request.cron },
32910
+ ...request.every_seconds === null ? {} : { every_seconds: request.every_seconds },
32911
+ statements: [...request.statements],
32912
+ timeout_ms: request.timeout_ms,
32913
+ enabled: request.enabled,
32914
+ confirm: true
32915
+ }
32916
+ }, { client: this.#client });
32917
+ assertDatabaseSchedule(value);
32918
+ if (value.name !== input.name || value.environment !== input.environment)
32919
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
32920
+ return value;
32921
+ }
32922
+ async listProjectDatabaseSchedules(input) {
32923
+ const value = await listProjectDatabaseSchedules({ project_id: input.projectId, environment: input.environment }, { client: this.#client });
32924
+ assertDatabaseSchedulePage(value);
32925
+ if (value.items.some((item) => item.environment !== input.environment))
32926
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
32927
+ return value;
32928
+ }
32929
+ async getProjectDatabaseSchedule(input) {
32930
+ const value = await getProjectDatabaseSchedule({ project_id: input.projectId, environment: input.environment, name: input.name }, { client: this.#client });
32931
+ assertDatabaseSchedule(value);
32932
+ if (value.name !== input.name || value.environment !== input.environment)
32933
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
32934
+ return value;
32935
+ }
32936
+ async deleteProjectDatabaseSchedule(input) {
32937
+ const value = await deleteProjectDatabaseSchedule({ project_id: input.projectId, environment: input.environment, name: input.name }, { client: this.#client });
32938
+ assertDatabaseScheduleDeleted(value);
32939
+ if (value.name !== input.name)
32940
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
32941
+ return value;
32942
+ }
32943
+ async listProjectDatabaseScheduleRuns(input) {
32944
+ const value = await listProjectDatabaseScheduleRuns({
32945
+ project_id: input.projectId,
32946
+ environment: input.environment,
32947
+ name: input.name,
32948
+ ...input.limit === void 0 ? {} : { limit: input.limit }
32949
+ }, { client: this.#client });
32950
+ assertDatabaseScheduleRunPage(value);
32951
+ if (value.items.some((item) => item.schedule !== input.name))
32952
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
32953
+ return value;
32954
+ }
32955
+ async runProjectDatabaseSchedule(input) {
32956
+ const value = await runProjectDatabaseSchedule({ project_id: input.projectId, environment: input.environment, name: input.name }, { client: this.#client });
32957
+ assertDatabaseScheduleRunAccepted(value);
32958
+ if (value.schedule !== input.name)
32959
+ throw new TypeError(SCHEDULE_SCOPE_MISMATCH);
32960
+ return value;
32961
+ }
32962
+ async getProjectDatabaseExecutionUsage(input) {
32963
+ const value = await getProjectDatabaseExecutionUsage({
32964
+ project_id: input.projectId,
32965
+ environment: input.environment,
32966
+ from: input.from,
32967
+ to: input.to,
32968
+ granularity: input.granularity,
32969
+ ...input.limit === void 0 ? {} : { limit: input.limit },
32970
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor }
32971
+ }, { client: this.#client });
32972
+ assertDatabaseExecutionUsagePage(value);
32973
+ return value;
32974
+ }
32275
32975
  async planPaidDomain(input) {
32276
32976
  return planPaidProjectDomain({ project_id: input.projectId, paidDomainRequest: { hostname: input.hostname } }, { client: this.#client });
32277
32977
  }
@@ -33006,6 +33706,10 @@ async function createAuthenticatedLocalMcpClient(signal, overrides = {}) {
33006
33706
  throw error;
33007
33707
  }
33008
33708
  }
33709
+ function requireScope(matches2) {
33710
+ if (!matches2)
33711
+ throw new TypeError("Database event scope mismatch");
33712
+ }
33009
33713
  var GeneratedSdkLocalMcpClient = class {
33010
33714
  managedSource;
33011
33715
  productApiOrigin;
@@ -33385,6 +34089,131 @@ var GeneratedSdkLocalMcpClient = class {
33385
34089
  assertProjectDatabaseAccess(value);
33386
34090
  return value;
33387
34091
  }
34092
+ async listDatabaseWebhooks(input) {
34093
+ const environment2 = input.environment ?? "dev";
34094
+ const value = await listProjectDatabaseWebhooks({ project_id: input.projectId, environment: environment2 }, { client: this.#client });
34095
+ assertDatabaseWebhookPage(value);
34096
+ requireScope(value.items.every((webhook) => webhook.environment === environment2));
34097
+ return value;
34098
+ }
34099
+ /** The signing secret exists only in this response and is never stored by the client. */
34100
+ async createDatabaseWebhook(input) {
34101
+ const value = await createProjectDatabaseWebhook({
34102
+ project_id: input.projectId,
34103
+ environment: input.environment,
34104
+ "Idempotency-Key": input.idempotencyKey,
34105
+ databaseWebhookCreateRequest: {
34106
+ url: input.url,
34107
+ event_types: [...input.eventTypes],
34108
+ headers: { ...input.headers }
34109
+ }
34110
+ }, { client: this.#client });
34111
+ assertDatabaseWebhookCreated(value);
34112
+ requireScope(value.environment === input.environment);
34113
+ return value;
34114
+ }
34115
+ async testDatabaseWebhook(input) {
34116
+ const value = await testProjectDatabaseWebhook({
34117
+ project_id: input.projectId,
34118
+ environment: input.environment,
34119
+ webhook_id: input.webhookId
34120
+ }, { client: this.#client });
34121
+ assertDatabaseWebhookTest(value);
34122
+ return value;
34123
+ }
34124
+ async deleteDatabaseWebhook(input) {
34125
+ const value = await deleteProjectDatabaseWebhook({
34126
+ project_id: input.projectId,
34127
+ environment: input.environment,
34128
+ webhook_id: input.webhookId
34129
+ }, { client: this.#client });
34130
+ assertDatabaseWebhookDeleted(value);
34131
+ requireScope(value.id === input.webhookId);
34132
+ return value;
34133
+ }
34134
+ async listDatabaseWebhookDeliveries(input) {
34135
+ const value = await listProjectDatabaseWebhookDeliveries({
34136
+ project_id: input.projectId,
34137
+ environment: input.environment ?? "dev",
34138
+ ...input.webhookId === void 0 ? {} : { webhook_id: input.webhookId },
34139
+ ...input.limit === void 0 ? {} : { limit: input.limit },
34140
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor }
34141
+ }, { client: this.#client });
34142
+ assertDatabaseWebhookDeliveryPage(value);
34143
+ requireScope(input.webhookId === void 0 || value.items.every((delivery) => delivery.webhook_id === input.webhookId));
34144
+ return value;
34145
+ }
34146
+ async replayDatabaseWebhookDelivery(input) {
34147
+ const value = await replayProjectDatabaseWebhookDelivery({
34148
+ project_id: input.projectId,
34149
+ environment: input.environment,
34150
+ delivery_id: input.deliveryId
34151
+ }, { client: this.#client });
34152
+ assertDatabaseWebhookReplayAccepted(value);
34153
+ requireScope(value.delivery_id === input.deliveryId);
34154
+ return value;
34155
+ }
34156
+ async listDatabaseSchedules(input) {
34157
+ const environment2 = input.environment ?? "dev";
34158
+ const value = await listProjectDatabaseSchedules({ project_id: input.projectId, environment: environment2 }, { client: this.#client });
34159
+ assertDatabaseSchedulePage(value);
34160
+ requireScope(value.items.every((schedule) => schedule.environment === environment2));
34161
+ return value;
34162
+ }
34163
+ async setDatabaseSchedule(input) {
34164
+ const value = await setProjectDatabaseSchedule({
34165
+ project_id: input.projectId,
34166
+ name: input.name,
34167
+ environment: input.environment,
34168
+ databaseScheduleSetRequest: {
34169
+ ...input.cron === void 0 ? {} : { cron: input.cron },
34170
+ ...input.everySeconds === void 0 ? {} : { every_seconds: input.everySeconds },
34171
+ statements: [...input.statements],
34172
+ ...input.timeoutMs === void 0 ? {} : { timeout_ms: input.timeoutMs },
34173
+ ...input.enabled === void 0 ? {} : { enabled: input.enabled },
34174
+ confirm: true
34175
+ }
34176
+ }, { client: this.#client });
34177
+ assertDatabaseSchedule(value);
34178
+ requireScope(value.name === input.name && value.environment === input.environment);
34179
+ return value;
34180
+ }
34181
+ async deleteDatabaseSchedule(input) {
34182
+ const value = await deleteProjectDatabaseSchedule({ project_id: input.projectId, name: input.name, environment: input.environment }, { client: this.#client });
34183
+ assertDatabaseScheduleDeleted(value);
34184
+ requireScope(value.name === input.name);
34185
+ return value;
34186
+ }
34187
+ async listDatabaseScheduleRuns(input) {
34188
+ const value = await listProjectDatabaseScheduleRuns({
34189
+ project_id: input.projectId,
34190
+ name: input.name,
34191
+ environment: input.environment ?? "dev",
34192
+ ...input.limit === void 0 ? {} : { limit: input.limit }
34193
+ }, { client: this.#client });
34194
+ assertDatabaseScheduleRunPage(value);
34195
+ requireScope(value.items.every((run) => run.schedule === input.name));
34196
+ return value;
34197
+ }
34198
+ async runDatabaseSchedule(input) {
34199
+ const value = await runProjectDatabaseSchedule({ project_id: input.projectId, name: input.name, environment: input.environment }, { client: this.#client });
34200
+ assertDatabaseScheduleRunAccepted(value);
34201
+ requireScope(value.schedule === input.name);
34202
+ return value;
34203
+ }
34204
+ async getDatabaseExecutionUsage(input) {
34205
+ const value = await getProjectDatabaseExecutionUsage({
34206
+ project_id: input.projectId,
34207
+ environment: input.environment ?? "dev",
34208
+ from: input.from,
34209
+ to: input.to,
34210
+ granularity: input.granularity,
34211
+ ...input.limit === void 0 ? {} : { limit: input.limit },
34212
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor }
34213
+ }, { client: this.#client });
34214
+ assertDatabaseExecutionUsagePage(value);
34215
+ return value;
34216
+ }
33388
34217
  planPromotion(input) {
33389
34218
  return planDeploymentPromotion({ project_id: input.projectId, source_deployment_id: input.sourceDeploymentId }, { client: this.#client });
33390
34219
  }
@@ -33616,13 +34445,13 @@ function normalizeMcpSourceChanges(value) {
33616
34445
  }
33617
34446
  }
33618
34447
  function normalizeSourceChanges(value) {
33619
- const body = record6(value);
34448
+ const body = record7(value);
33620
34449
  const changes = body["changes"];
33621
34450
  if (!Array.isArray(changes) || changes.length < 1 || changes.length > MANAGED_SOURCE_LIMITS.files)
33622
34451
  invalid7();
33623
34452
  let textBytes = 0;
33624
34453
  const normalized = changes.map((change) => {
33625
- const entry = record6(change);
34454
+ const entry = record7(change);
33626
34455
  const hasText = Object.hasOwn(entry, "content_text");
33627
34456
  if (hasText === Object.hasOwn(entry, "content_base64"))
33628
34457
  invalid7();
@@ -33681,7 +34510,7 @@ function encodeBase64(bytes) {
33681
34510
  binary += String.fromCharCode(...bytes.subarray(offset, offset + 32768));
33682
34511
  return btoa(binary);
33683
34512
  }
33684
- function record6(value) {
34513
+ function record7(value) {
33685
34514
  if (typeof value !== "object" || value === null || Array.isArray(value))
33686
34515
  invalid7();
33687
34516
  return value;
@@ -33692,6 +34521,10 @@ function invalid7() {
33692
34521
 
33693
34522
  // apps/mcp/dist/local-server.js
33694
34523
  var identifier2 = external_exports.string().min(1).max(256);
34524
+ var databaseEnvironment = external_exports.enum(["dev", "prod"]);
34525
+ var databaseWebhookId = external_exports.string().regex(/^whk_[a-z0-9]{20}$/u);
34526
+ var databaseDeliveryId = external_exports.string().regex(/^dlv_[0-9a-f]{20}$/u);
34527
+ var databaseScheduleName = external_exports.string().regex(/^[a-z][a-z0-9_-]{0,62}$/u);
33695
34528
  var profileName = external_exports.string().regex(/^[a-z0-9][a-z0-9_-]{0,62}$/u).optional().describe("Saved login to act as (profile_list shows them). Needed only when several logins could run this call; OHMYHOST_PROFILE of this server must match it.");
33696
34529
  var idempotencyKey = external_exports.string().min(1).max(128);
33697
34530
  var commitSha = external_exports.string().regex(/^[a-f0-9]{40}$/u);
@@ -33851,7 +34684,7 @@ function createLocalOhmyhostMcpServer(dependencies) {
33851
34684
  registerProductTool(server, dependencies, "organization_usage_get", "Read the billed usage of the last up to 14 UTC days (today included) grouped by day, project and meter, and what each project has used so far this UTC month. One credit is 1000000 microcredits. Null environment means shared project cost. Charges can arrive late and unmetered usage is not zero consumption. Owner-only; works at zero credit without new charges.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationCreditUsage(input.organization_id));
33852
34685
  registerProductTool(server, dependencies, "organization_account_get", "Owner-only: read the effective Free/Paid plan, its Stripe or granted source, the monthly credits that expire at next_expiry, the top-up and bonus credits that never expire, the reservations that hold part of them, and available_micros (monthly plus one-time minus reservations). Granted Paid features do not imply a Stripe subscription or extra monthly Paid allowance. paid_until is the end of the paid coverage, which includes the 14-day renewal grace of a Stripe subscription; null on Free. This read grants no access or credits.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationAccount(input.organization_id));
33853
34686
  registerProductTool(server, dependencies, "referral_link_get", "Read the workspace's referral link to share. A new user whose first workspace comes from it starts with 30 days of Paid and 1,000 credits; that workspace's first payment gives this workspace 1,000 credits, plus 30 days of Paid unless a Stripe subscription or an unbounded grant already covers it. Any member may read it.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationReferral(input.organization_id));
33854
- registerProductTool(server, dependencies, "organization_credits_get", "Read the owner's shared organization credit pool (available_micros is monthly plus one-time credit minus reservations), the seven-day grace_started_at/grace_expires_at that begins when the credit is used up, and published rate_cards. Existing services/domains are not immediately shut down at zero credit; an explicit project stop budget is separate. One credit is 1000000 microcredits. Each rate states credit_micros for units_per_charge; publication alone does not enable billing. active_meters identifies billed sources; provider outages are not customer debt. Works at zero credit. Top-ups and enabling auto-recharge require active Paid access.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationCredits(input.organization_id));
34687
+ registerProductTool(server, dependencies, "organization_credits_get", "Read the owner's shared organization credit balance (available_micros is monthly plus one-time credit minus reservations) and the seven-day grace_started_at/grace_expires_at that begins when the credit is used up. It states what is left, not what the credit was spent on; read organization_usage_get for the recent charges. Existing services/domains are not immediately shut down at zero credit; an explicit project stop budget is separate. One credit is 1000000 microcredits. Provider outages are not customer debt. Works at zero credit. Top-ups and enabling auto-recharge require active Paid access.", external_exports.object({ organization_id: identifier2 }), (client2, input) => client2.getOrganizationCredits(input.organization_id));
33855
34688
  registerProductTool(server, dependencies, "project_budget_get", "Read the owner's project UTC-month budget, this month's use and open reservations. A budget never allocates a second wallet.", external_exports.object({ project_id: identifier2 }), (client2, input) => client2.getProjectCreditBudget(input.project_id));
33856
34689
  registerProductTool(server, dependencies, "project_budget_set", "Set an owner's optional monthly project budget in microcredits (1000000 = one credit). continue is the default and uses the org pool after the threshold; stop blocks new billable work. null clears the budget and requires continue. Changing it never resets usage or adds credits. Replay the same key after uncertainty; read the budget again for current usage.", external_exports.object({
33857
34690
  project_id: identifier2,
@@ -33941,6 +34774,142 @@ function createLocalOhmyhostMcpServer(dependencies) {
33941
34774
  ...input.environment === void 0 ? {} : { environment: input.environment }
33942
34775
  }));
33943
34776
  registerProductTool(server, dependencies, "database_access_revoke", "Revoke one issued database credential immediately: open sessions end and its PostgreSQL role is removed. Revocation is idempotent and never touches application roles or data.", external_exports.object({ project_id: identifier2, access_id: identifier2 }), (client2, input) => client2.revokeDatabaseAccess({ projectId: input.project_id, accessId: input.access_id }), destructiveAnnotations());
34777
+ registerProductTool(server, dependencies, "database_webhook_list", "List this project's database webhooks of one Dev or Prod environment (dev when omitted), without signing secrets. Each webhook lists its event types and header names only.", external_exports.object({ project_id: identifier2, environment: databaseEnvironment.optional() }), (client2, input) => client2.listDatabaseWebhooks({
34778
+ projectId: input.project_id,
34779
+ ...input.environment === void 0 ? {} : { environment: input.environment }
34780
+ }));
34781
+ registerProductTool(server, dependencies, "database_webhook_create", "Subscribe one HTTPS receiver to database lifecycle events (database.created, ready, woke, slept, suspended, resized, deleted) of one Dev or Prod database. The signing secret is RETURNED EXACTLY ONCE: store it in a secret manager and never write it into files, notes, source, commit messages or later messages. Deliveries are signed, retried and dead-lettered when retries stop. At most five webhooks exist per project environment. Requires confirmed: true and an idempotency key; the same key with the same request returns the stored answer.", external_exports.object({
34782
+ project_id: identifier2,
34783
+ environment: databaseEnvironment,
34784
+ url: external_exports.string().max(2048).regex(/^https:\/\//u),
34785
+ event_types: external_exports.array(external_exports.enum(DATABASE_WEBHOOK_EVENT_TYPES)).min(1).max(16),
34786
+ headers: external_exports.record(external_exports.string(), external_exports.string()).optional(),
34787
+ idempotency_key: idempotencyKey,
34788
+ confirmed: external_exports.literal(true)
34789
+ }), (client2, input) => client2.createDatabaseWebhook({
34790
+ projectId: input.project_id,
34791
+ environment: input.environment,
34792
+ url: input.url,
34793
+ eventTypes: input.event_types,
34794
+ headers: input.headers ?? {},
34795
+ idempotencyKey: input.idempotency_key
34796
+ }), mutationAnnotations());
34797
+ registerProductTool(server, dependencies, "database_webhook_test", "Send one signed test request to a database webhook and report the outcome synchronously. Each call sends one request to the receiver; the platform allows one test per webhook every five seconds. If the answer is lost, read database_webhook_delivery_list before calling again; a second call sends another request.", external_exports.object({
34798
+ project_id: identifier2,
34799
+ environment: databaseEnvironment,
34800
+ webhook_id: databaseWebhookId
34801
+ }), (client2, input) => client2.testDatabaseWebhook({
34802
+ projectId: input.project_id,
34803
+ environment: input.environment,
34804
+ webhookId: input.webhook_id
34805
+ }), { ...mutationAnnotations(), idempotentHint: false });
34806
+ registerProductTool(server, dependencies, "database_webhook_delete", "Stop all deliveries to one database webhook. Destructive: requires confirmed: true. Deleting an already deleted webhook answers not found.", external_exports.object({
34807
+ project_id: identifier2,
34808
+ environment: databaseEnvironment,
34809
+ webhook_id: databaseWebhookId,
34810
+ confirmed: external_exports.literal(true)
34811
+ }), (client2, input) => client2.deleteDatabaseWebhook({
34812
+ projectId: input.project_id,
34813
+ environment: input.environment,
34814
+ webhookId: input.webhook_id
34815
+ }), destructiveAnnotations());
34816
+ registerProductTool(server, dependencies, "database_webhook_delivery_list", "List recent database webhook deliveries, newest first, optionally for one webhook. Each delivery shows its state (pending, delivered or dead_lettered), attempts and last error.", external_exports.object({
34817
+ project_id: identifier2,
34818
+ environment: databaseEnvironment.optional(),
34819
+ webhook_id: databaseWebhookId.optional(),
34820
+ limit: external_exports.number().int().min(1).max(100).optional(),
34821
+ cursor: external_exports.string().min(1).max(200).optional()
34822
+ }), (client2, input) => client2.listDatabaseWebhookDeliveries({
34823
+ projectId: input.project_id,
34824
+ ...input.environment === void 0 ? {} : { environment: input.environment },
34825
+ ...input.webhook_id === void 0 ? {} : { webhookId: input.webhook_id },
34826
+ ...input.limit === void 0 ? {} : { limit: input.limit },
34827
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor }
34828
+ }));
34829
+ registerProductTool(server, dependencies, "database_webhook_delivery_replay", "Queue one more attempt for a database webhook delivery that is no longer being retried. Each call queues one attempt; the delivery returns to pending until it is delivered or dead-lettered again. If the answer is lost, read database_webhook_delivery_list before calling again; a second call queues another attempt.", external_exports.object({
34830
+ project_id: identifier2,
34831
+ environment: databaseEnvironment,
34832
+ delivery_id: databaseDeliveryId
34833
+ }), (client2, input) => client2.replayDatabaseWebhookDelivery({
34834
+ projectId: input.project_id,
34835
+ environment: input.environment,
34836
+ deliveryId: input.delivery_id
34837
+ }), { ...mutationAnnotations(), idempotentHint: false });
34838
+ registerProductTool(server, dependencies, "database_schedule_list", "List this project's database schedules of one Dev or Prod environment (dev when omitted), with their cadence, statements, timeout and next run.", external_exports.object({ project_id: identifier2, environment: databaseEnvironment.optional() }), (client2, input) => client2.listDatabaseSchedules({
34839
+ projectId: input.project_id,
34840
+ ...input.environment === void 0 ? {} : { environment: input.environment }
34841
+ }));
34842
+ registerProductTool(server, dependencies, "database_schedule_set", "Create or replace a named database schedule that runs SQL statements repeatedly on a timer, as the application's own runtime role, so row-level security applies. Send exactly one of cron (five-field UTC expression) or every_seconds (60 to 2678400). Each run is cancelled after timeout_ms (1000 to 30000, default 10000). Statements run in order and must be safe to repeat: write idempotent statements. Destructive: requires confirmed: true.", external_exports.object({
34843
+ project_id: identifier2,
34844
+ environment: databaseEnvironment,
34845
+ name: databaseScheduleName,
34846
+ cron: external_exports.string().min(9).max(120).optional(),
34847
+ every_seconds: external_exports.number().int().min(DATABASE_SCHEDULE_MIN_EVERY_SECONDS).max(DATABASE_SCHEDULE_MAX_EVERY_SECONDS).optional(),
34848
+ statements: external_exports.array(external_exports.string().min(1).max(DATABASE_SCHEDULE_STATEMENT_MAX_BYTES)).min(1).max(DATABASE_SCHEDULE_MAX_STATEMENTS),
34849
+ timeout_ms: external_exports.number().int().min(DATABASE_SCHEDULE_MIN_TIMEOUT_MS).max(DATABASE_SCHEDULE_MAX_TIMEOUT_MS).optional(),
34850
+ enabled: external_exports.boolean().optional(),
34851
+ confirmed: external_exports.literal(true)
34852
+ }).refine((value) => value.cron === void 0 !== (value.every_seconds === void 0), {
34853
+ message: "Send exactly one of cron or every_seconds",
34854
+ path: ["every_seconds"]
34855
+ }), (client2, input) => client2.setDatabaseSchedule({
34856
+ projectId: input.project_id,
34857
+ environment: input.environment,
34858
+ name: input.name,
34859
+ cron: input.cron,
34860
+ everySeconds: input.every_seconds,
34861
+ statements: input.statements,
34862
+ timeoutMs: input.timeout_ms,
34863
+ enabled: input.enabled
34864
+ }), destructiveAnnotations());
34865
+ registerProductTool(server, dependencies, "database_schedule_delete", "Remove one database schedule so it never runs again. Destructive: requires confirmed: true.", external_exports.object({
34866
+ project_id: identifier2,
34867
+ environment: databaseEnvironment,
34868
+ name: databaseScheduleName,
34869
+ confirmed: external_exports.literal(true)
34870
+ }), (client2, input) => client2.deleteDatabaseSchedule({
34871
+ projectId: input.project_id,
34872
+ environment: input.environment,
34873
+ name: input.name
34874
+ }), destructiveAnnotations());
34875
+ registerProductTool(server, dependencies, "database_schedule_run_list", "List the newest runs of one database schedule, newest first, with each run's outcome (succeeded, failed, timed_out, outcome_unknown, rejected or a skipped reason) and SQLSTATE when one applies.", external_exports.object({
34876
+ project_id: identifier2,
34877
+ environment: databaseEnvironment.optional(),
34878
+ name: databaseScheduleName,
34879
+ limit: external_exports.number().int().min(1).max(50).optional()
34880
+ }), (client2, input) => client2.listDatabaseScheduleRuns({
34881
+ projectId: input.project_id,
34882
+ ...input.environment === void 0 ? {} : { environment: input.environment },
34883
+ name: input.name,
34884
+ ...input.limit === void 0 ? {} : { limit: input.limit }
34885
+ }));
34886
+ registerProductTool(server, dependencies, "database_schedule_run_now", "Queue one immediate run of a database schedule. Refused while the schedule is disabled or a run is already queued. Destructive: the statements execute against the database; requires confirmed: true. If the answer is lost, read database_schedule_run_list before calling again; a second call queues another run.", external_exports.object({
34887
+ project_id: identifier2,
34888
+ environment: databaseEnvironment,
34889
+ name: databaseScheduleName,
34890
+ confirmed: external_exports.literal(true)
34891
+ }), (client2, input) => client2.runDatabaseSchedule({
34892
+ projectId: input.project_id,
34893
+ environment: input.environment,
34894
+ name: input.name
34895
+ }), { ...destructiveAnnotations(), idempotentHint: false });
34896
+ registerProductTool(server, dependencies, "database_execution_usage_get", "Read metered database execution usage: schedule runs and webhook attempts per UTC hour or day window. from and to are UTC timestamps with milliseconds (Z), aligned to the granularity, at most 31 days apart. Only completed windows are final. Rejected, skipped, event and delivery counts are reported but not billed.", external_exports.object({
34897
+ project_id: identifier2,
34898
+ environment: databaseEnvironment.optional(),
34899
+ from: external_exports.string().regex(/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$/u),
34900
+ to: external_exports.string().regex(/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$/u),
34901
+ granularity: external_exports.enum(["hour", "day"]),
34902
+ limit: external_exports.number().int().min(1).max(100).optional(),
34903
+ cursor: external_exports.string().min(1).max(200).optional()
34904
+ }), (client2, input) => client2.getDatabaseExecutionUsage({
34905
+ projectId: input.project_id,
34906
+ ...input.environment === void 0 ? {} : { environment: input.environment },
34907
+ from: input.from,
34908
+ to: input.to,
34909
+ granularity: input.granularity,
34910
+ ...input.limit === void 0 ? {} : { limit: input.limit },
34911
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor }
34912
+ }));
33944
34913
  registerProductTool(server, dependencies, "promotion_plan", "Plan promotion of the current Dev artifact to Prod without a rebuild.", external_exports.object({ project_id: identifier2, source_deployment_id: identifier2 }), (client2, input) => client2.planPromotion({
33945
34914
  projectId: input.project_id,
33946
34915
  sourceDeploymentId: input.source_deployment_id
@@ -34869,7 +35838,7 @@ function safeFailure(error, commandPrefix) {
34869
35838
  return {
34870
35839
  code: "request_timeout",
34871
35840
  retryable: true,
34872
- suggestedAction: "The ohmyho.st API did not answer within 30 seconds. Call this tool again; for a change use the same idempotency_key, because it may already be under way."
35841
+ suggestedAction: "The ohmyho.st API did not answer within 30 seconds. Call this tool again; for a change that takes an idempotency_key use the same key, because it may already be under way. A change without a key (webhook delete, test or replay, schedule set, delete or run) is repeated only after a read tool shows the current state."
34873
35842
  };
34874
35843
  if (error instanceof Error) {
34875
35844
  const local = localFailure(error, commandPrefix);
@@ -34936,7 +35905,7 @@ function localFailure(error, commandPrefix) {
34936
35905
  return {
34937
35906
  code: "network_error",
34938
35907
  retryable: true,
34939
- suggestedAction: "The request did not reach the ohmyho.st API, or its answer was cut off. Call this tool again; for a change use the same idempotency_key, because it may already have been applied."
35908
+ suggestedAction: "The request did not reach the ohmyho.st API, or its answer was cut off. Call this tool again; for a change that takes an idempotency_key use the same key, because it may already have been applied. A change without a key (webhook delete, test or replay, schedule set, delete or run) is repeated only after a read tool shows the current state."
34940
35909
  };
34941
35910
  case "ResponseContractError":
34942
35911
  return {