@amerged/ohmyhost-cli 0.1.11 → 0.1.14

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.
@@ -2209,10 +2209,10 @@ var require_resolve = __commonJS({
2209
2209
  }
2210
2210
  return count;
2211
2211
  }
2212
- function getFullPath(resolver, id2 = "", normalize) {
2212
+ function getFullPath(resolver, id3 = "", normalize) {
2213
2213
  if (normalize !== false)
2214
- id2 = normalizeId(id2);
2215
- const p = resolver.parse(id2);
2214
+ id3 = normalizeId(id3);
2215
+ const p = resolver.parse(id3);
2216
2216
  return _getFullPath(resolver, p);
2217
2217
  }
2218
2218
  exports.getFullPath = getFullPath;
@@ -2222,13 +2222,13 @@ var require_resolve = __commonJS({
2222
2222
  }
2223
2223
  exports._getFullPath = _getFullPath;
2224
2224
  var TRAILING_SLASH_HASH = /#\/?$/;
2225
- function normalizeId(id2) {
2226
- return id2 ? id2.replace(TRAILING_SLASH_HASH, "") : "";
2225
+ function normalizeId(id3) {
2226
+ return id3 ? id3.replace(TRAILING_SLASH_HASH, "") : "";
2227
2227
  }
2228
2228
  exports.normalizeId = normalizeId;
2229
- function resolveUrl(resolver, baseId, id2) {
2230
- id2 = normalizeId(id2);
2231
- return resolver.resolve(baseId, id2);
2229
+ function resolveUrl(resolver, baseId, id3) {
2230
+ id3 = normalizeId(id3);
2231
+ return resolver.resolve(baseId, id3);
2232
2232
  }
2233
2233
  exports.resolveUrl = resolveUrl;
2234
2234
  var ANCHOR = /^[a-z_][-a-z0-9._]*$/i;
@@ -2998,8 +2998,8 @@ var require_compile = __commonJS({
2998
2998
  if (Object.keys(root.schema).length > 0 && refPath === baseId) {
2999
2999
  return getJsonPointer.call(this, p, root);
3000
3000
  }
3001
- const id2 = (0, resolve_1.normalizeId)(refPath);
3002
- const schOrRef = this.refs[id2] || this.schemas[id2];
3001
+ const id3 = (0, resolve_1.normalizeId)(refPath);
3002
+ const schOrRef = this.refs[id3] || this.schemas[id3];
3003
3003
  if (typeof schOrRef == "string") {
3004
3004
  const sch = resolveSchema.call(this, root, schOrRef);
3005
3005
  if (typeof (sch === null || sch === void 0 ? void 0 : sch.schema) !== "object")
@@ -3010,7 +3010,7 @@ var require_compile = __commonJS({
3010
3010
  return;
3011
3011
  if (!schOrRef.validate)
3012
3012
  compileSchema.call(this, schOrRef);
3013
- if (id2 === (0, resolve_1.normalizeId)(ref)) {
3013
+ if (id3 === (0, resolve_1.normalizeId)(ref)) {
3014
3014
  const { schema } = schOrRef;
3015
3015
  const { schemaId } = this.opts;
3016
3016
  const schId = schema[schemaId];
@@ -3710,7 +3710,7 @@ var require_schemes = __commonJS({
3710
3710
  serialize: httpSerialize
3711
3711
  }
3712
3712
  );
3713
- var https = (
3713
+ var https2 = (
3714
3714
  /** @type {SchemeHandler} */
3715
3715
  {
3716
3716
  scheme: "https",
@@ -3759,7 +3759,7 @@ var require_schemes = __commonJS({
3759
3759
  /** @type {Record<SchemeName, SchemeHandler>} */
3760
3760
  {
3761
3761
  http,
3762
- https,
3762
+ https: https2,
3763
3763
  ws,
3764
3764
  wss,
3765
3765
  urn,
@@ -4425,15 +4425,15 @@ var require_core = __commonJS({
4425
4425
  this.addSchema(sch, void 0, _meta, _validateSchema);
4426
4426
  return this;
4427
4427
  }
4428
- let id2;
4428
+ let id3;
4429
4429
  if (typeof schema === "object") {
4430
4430
  const { schemaId } = this.opts;
4431
- id2 = schema[schemaId];
4432
- if (id2 !== void 0 && typeof id2 != "string") {
4431
+ id3 = schema[schemaId];
4432
+ if (id3 !== void 0 && typeof id3 != "string") {
4433
4433
  throw new Error(`schema ${schemaId} must be string`);
4434
4434
  }
4435
4435
  }
4436
- key = (0, resolve_1.normalizeId)(key || id2);
4436
+ key = (0, resolve_1.normalizeId)(key || id3);
4437
4437
  this._checkUnique(key);
4438
4438
  this.schemas[key] = this._addSchema(schema, _meta, key, _validateSchema, true);
4439
4439
  return this;
@@ -4512,11 +4512,11 @@ var require_core = __commonJS({
4512
4512
  case "object": {
4513
4513
  const cacheKey = schemaKeyRef;
4514
4514
  this._cache.delete(cacheKey);
4515
- let id2 = schemaKeyRef[this.opts.schemaId];
4516
- if (id2) {
4517
- id2 = (0, resolve_1.normalizeId)(id2);
4518
- delete this.schemas[id2];
4519
- delete this.refs[id2];
4515
+ let id3 = schemaKeyRef[this.opts.schemaId];
4516
+ if (id3) {
4517
+ id3 = (0, resolve_1.normalizeId)(id3);
4518
+ delete this.schemas[id3];
4519
+ delete this.refs[id3];
4520
4520
  }
4521
4521
  return this;
4522
4522
  }
@@ -4623,10 +4623,10 @@ var require_core = __commonJS({
4623
4623
  }
4624
4624
  }
4625
4625
  _addSchema(schema, meta, baseId, validateSchema = this.opts.validateSchema, addSchema = this.opts.addUsedSchema) {
4626
- let id2;
4626
+ let id3;
4627
4627
  const { schemaId } = this.opts;
4628
4628
  if (typeof schema == "object") {
4629
- id2 = schema[schemaId];
4629
+ id3 = schema[schemaId];
4630
4630
  } else {
4631
4631
  if (this.opts.jtd)
4632
4632
  throw new Error("schema must be object");
@@ -4636,7 +4636,7 @@ var require_core = __commonJS({
4636
4636
  let sch = this._cache.get(schema);
4637
4637
  if (sch !== void 0)
4638
4638
  return sch;
4639
- baseId = (0, resolve_1.normalizeId)(id2 || baseId);
4639
+ baseId = (0, resolve_1.normalizeId)(id3 || baseId);
4640
4640
  const localRefs = resolve_1.getSchemaRefs.call(this, schema, baseId);
4641
4641
  sch = new compile_1.SchemaEnv({ schema, schemaId, meta, baseId, localRefs });
4642
4642
  this._cache.set(sch.schema, sch);
@@ -4649,9 +4649,9 @@ var require_core = __commonJS({
4649
4649
  this.validateSchema(schema, true);
4650
4650
  return sch;
4651
4651
  }
4652
- _checkUnique(id2) {
4653
- if (this.schemas[id2] || this.refs[id2]) {
4654
- throw new Error(`schema with key or id "${id2}" already exists`);
4652
+ _checkUnique(id3) {
4653
+ if (this.schemas[id3] || this.refs[id3]) {
4654
+ throw new Error(`schema with key or id "${id3}" already exists`);
4655
4655
  }
4656
4656
  }
4657
4657
  _compileSchemaEnv(sch) {
@@ -5016,8 +5016,8 @@ var require_multipleOf = __commonJS({
5016
5016
  const { gen, data, schemaCode, it } = cxt;
5017
5017
  const prec = it.opts.multipleOfPrecision;
5018
5018
  const res = gen.let("res");
5019
- const invalid3 = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
5020
- cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid3}))`);
5019
+ const invalid4 = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
5020
+ cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid4}))`);
5021
5021
  }
5022
5022
  };
5023
5023
  exports.default = def;
@@ -15002,6 +15002,8 @@ var recognizedCommandLabel = (argv) => {
15002
15002
  return "project status";
15003
15003
  if (value === "project" && values[0] === "handle" && values[1] === "check")
15004
15004
  return "project handle check";
15005
+ if (value === "project" && values[0] === "handle" && values[1] === "set")
15006
+ return "project handle set";
15005
15007
  if (value === "project" && values[0] === "dev-access" && values[1] === "create")
15006
15008
  return "project dev-access create";
15007
15009
  if (value === "database" && values[0] === "compute" && values[1] === "set")
@@ -15066,6 +15068,28 @@ var recognizedCommandLabel = (argv) => {
15066
15068
  }
15067
15069
  if (value === "function" && values[0] === "runs")
15068
15070
  return "function runs";
15071
+ if (value === "mail") {
15072
+ if (values[0] === "setup")
15073
+ return "mail setup";
15074
+ if (values[0] === "status")
15075
+ return "mail status";
15076
+ if (values[0] === "webhook") {
15077
+ if (values[1] === "set")
15078
+ return "mail webhook set";
15079
+ if (values[1] === "verify")
15080
+ return "mail webhook verify";
15081
+ if (values[1] === "disable")
15082
+ return "mail webhook disable";
15083
+ }
15084
+ if (values[0] === "messages") {
15085
+ if (values[1] === "list")
15086
+ return "mail messages list";
15087
+ if (values[1] === "get")
15088
+ return "mail messages get";
15089
+ if (values[1] === "retry")
15090
+ return "mail messages retry";
15091
+ }
15092
+ }
15069
15093
  if (value === "mail" && values[0] === "domain") {
15070
15094
  if (values[1] === "set")
15071
15095
  return "mail domain set";
@@ -15444,6 +15468,25 @@ var parseProductCliCommand = (argv) => {
15444
15468
  }
15445
15469
  if (first === "project") {
15446
15470
  const subcommand = values.shift();
15471
+ if (subcommand === "handle" && values[0] === "set") {
15472
+ values.shift();
15473
+ if (yes || wait || follow || stdin)
15474
+ throw new InvalidCommandError();
15475
+ const options2 = parseOptions(values, [
15476
+ "--project",
15477
+ "--handle",
15478
+ "--if-match",
15479
+ "--idempotency-key"
15480
+ ]);
15481
+ return {
15482
+ kind: "project-handle-set",
15483
+ projectId: options2["--project"],
15484
+ handle: options2["--handle"],
15485
+ ifMatch: options2["--if-match"],
15486
+ idempotencyKey: options2["--idempotency-key"],
15487
+ credentialStore
15488
+ };
15489
+ }
15447
15490
  if (subcommand === "handle" && values.shift() === "check") {
15448
15491
  if (yes || wait || follow || stdin)
15449
15492
  throw new InvalidCommandError();
@@ -16083,32 +16126,82 @@ var parseProductCliCommand = (argv) => {
16083
16126
  }
16084
16127
  throw new InvalidCommandError();
16085
16128
  }
16086
- if (first === "mail" && values[0] === "domain" && values[1] === "set") {
16129
+ if (first === "mail") {
16087
16130
  if (yes || wait || follow || stdin)
16088
16131
  throw new InvalidCommandError();
16089
- values.splice(0, 2);
16090
- const options = parseOptions(values, ["--project", "--domain", "--idempotency-key"]);
16091
- if (!/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/u.test(options["--domain"])) {
16092
- throw new InvalidCommandError();
16093
- }
16094
- return {
16095
- kind: "mail-domain-set",
16096
- projectId: options["--project"],
16097
- domain: options["--domain"],
16098
- idempotencyKey: options["--idempotency-key"],
16099
- credentialStore
16132
+ const area = values.shift();
16133
+ const sub = area === "webhook" || area === "messages" || area === "domain" ? values.shift() : void 0;
16134
+ const options = parseOptionalOptions(values, [
16135
+ "--project",
16136
+ "--environment",
16137
+ "--domain",
16138
+ "--sending",
16139
+ "--receiving",
16140
+ "--url",
16141
+ "--idempotency-key",
16142
+ "--message",
16143
+ "--after"
16144
+ ]);
16145
+ const required = (key) => {
16146
+ const value = options[key];
16147
+ if (!value)
16148
+ throw new InvalidCommandError();
16149
+ return value;
16100
16150
  };
16101
- }
16102
- if (first === "mail" && values[0] === "domain" && values[1] === "status") {
16103
- if (yes || wait || follow || stdin)
16151
+ const scope = { projectId: required("--project"), environmentId: required("--environment") };
16152
+ let request, label;
16153
+ if (area === "setup" || area === "domain" && sub === "set") {
16154
+ const sending = required("--sending"), receiving = required("--receiving");
16155
+ if (!["true", "false"].includes(sending) || !["true", "false"].includes(receiving))
16156
+ throw new InvalidCommandError();
16157
+ request = {
16158
+ ...scope,
16159
+ action: "configure",
16160
+ domain: required("--domain"),
16161
+ sending: sending === "true",
16162
+ receiving: receiving === "true",
16163
+ idempotencyKey: required("--idempotency-key")
16164
+ };
16165
+ label = area === "domain" ? "mail domain set" : "mail setup";
16166
+ } else if (area === "status" || area === "domain" && sub === "status") {
16167
+ request = { ...scope, action: "status" };
16168
+ label = area === "domain" ? "mail domain status" : "mail status";
16169
+ } else if (area === "webhook" && sub === "set") {
16170
+ request = {
16171
+ ...scope,
16172
+ action: "webhook_set",
16173
+ url: required("--url"),
16174
+ idempotencyKey: required("--idempotency-key")
16175
+ };
16176
+ label = "mail webhook set";
16177
+ } else if (area === "webhook" && (sub === "verify" || sub === "disable")) {
16178
+ request = {
16179
+ ...scope,
16180
+ action: sub === "verify" ? "webhook_verify" : "webhook_disable",
16181
+ idempotencyKey: required("--idempotency-key")
16182
+ };
16183
+ label = sub === "verify" ? "mail webhook verify" : "mail webhook disable";
16184
+ } else if (area === "messages" && sub === "list") {
16185
+ request = {
16186
+ ...scope,
16187
+ action: "messages_list",
16188
+ ...options["--after"] ? { after: options["--after"] } : {}
16189
+ };
16190
+ label = "mail messages list";
16191
+ } else if (area === "messages" && sub === "get") {
16192
+ request = { ...scope, action: "message_get", messageId: required("--message") };
16193
+ label = "mail messages get";
16194
+ } else if (area === "messages" && sub === "retry") {
16195
+ request = {
16196
+ ...scope,
16197
+ action: "message_retry",
16198
+ messageId: required("--message"),
16199
+ idempotencyKey: required("--idempotency-key")
16200
+ };
16201
+ label = "mail messages retry";
16202
+ } else
16104
16203
  throw new InvalidCommandError();
16105
- values.splice(0, 2);
16106
- const options = parseOptions(values, ["--project"]);
16107
- return {
16108
- kind: "mail-domain-status",
16109
- projectId: options["--project"],
16110
- credentialStore
16111
- };
16204
+ return { kind: "managed-mail", request, label, credentialStore };
16112
16205
  }
16113
16206
  throw new InvalidCommandError();
16114
16207
  };
@@ -16299,12 +16392,12 @@ function classifyFrameworkVersion(framework, version2) {
16299
16392
  return VERIFIED_VERSIONS[framework].has(version2) ? versionAdmission("verified", "verified_fixture") : versionAdmission("experimental", "inside_admitted_window");
16300
16393
  }
16301
16394
  function parseVersionSpec(version2) {
16302
- const exact3 = EXACT_VERSION.exec(version2);
16303
- const match = exact3 ?? (/^[~^](.*)$/u.exec(version2)?.[1] ? EXACT_VERSION.exec(version2.slice(1)) : null);
16395
+ const exact4 = EXACT_VERSION.exec(version2);
16396
+ const match = exact4 ?? (/^[~^](.*)$/u.exec(version2)?.[1] ? EXACT_VERSION.exec(version2.slice(1)) : null);
16304
16397
  if (match === null)
16305
16398
  return null;
16306
16399
  const tuple = [Number(match[1]), Number(match[2]), Number(match[3])];
16307
- return tuple.every(Number.isSafeInteger) ? Object.freeze({ exact: exact3 !== null, version: tuple }) : null;
16400
+ return tuple.every(Number.isSafeInteger) ? Object.freeze({ exact: exact4 !== null, version: tuple }) : null;
16308
16401
  }
16309
16402
  function insideAdmittedWindow(framework, version2) {
16310
16403
  switch (framework) {
@@ -16328,8 +16421,8 @@ function versionAdmission(classification, reason) {
16328
16421
  }
16329
16422
  var FRAMEWORK_CONVERSION_DETAILS = Object.freeze({
16330
16423
  database_binding_private: Object.freeze({
16331
- render: (path) => `"${path}" reads a managed database connection string. Hyperdrive, DATABASE_URL and postgres:// URLs never reach a customer Worker; call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database". Commit the change, then plan again.`,
16332
- pattern: /^"([^"]+)" reads a managed database connection string\. Hyperdrive, DATABASE_URL and postgres:\/\/ URLs never reach a customer Worker; call the database with createPrivateDatabaseClient from "@ohmyhost\/customer-runtime\/database"\. Commit the change, then plan again\.$/u
16424
+ render: (path) => `"${path}" reads a managed database connection string. HYPERDRIVE is retired; DATABASE_URL and postgres:// URLs never reach a customer Worker. Call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database". Commit the change, then plan again.`,
16425
+ pattern: /^"([^"]+)" reads a managed database connection string\. HYPERDRIVE is retired; DATABASE_URL and postgres:\/\/ URLs never reach a customer Worker\. Call the database with createPrivateDatabaseClient from "@ohmyhost\/customer-runtime\/database"\. Commit the change, then plan again\.$/u
16333
16426
  }),
16334
16427
  database_driver_unsupported: Object.freeze({
16335
16428
  render: (path) => `"${path}" imports a PostgreSQL socket driver. Outbound connect() is disabled for customer Workers, so it can never open a connection; call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database". Commit the change, then plan again.`,
@@ -16751,6 +16844,26 @@ var PROBLEM_POLICY = {
16751
16844
  retryable: true,
16752
16845
  action: "Retry project creation with the same idempotency key."
16753
16846
  },
16847
+ project_handle_taken: {
16848
+ status: 409,
16849
+ retryable: false,
16850
+ action: "Run 'ohmyhost project handle check' for a free address, then rename to one of the alternatives it returns."
16851
+ },
16852
+ project_handle_invalid: {
16853
+ status: 409,
16854
+ retryable: false,
16855
+ action: "Choose one to five lowercase words of letters and digits, three to fifty-nine characters, avoiding reserved words."
16856
+ },
16857
+ project_handle_unchanged: {
16858
+ status: 409,
16859
+ retryable: false,
16860
+ action: "The project already answers on this address; no rename is needed."
16861
+ },
16862
+ project_rename_blocked: {
16863
+ status: 409,
16864
+ retryable: true,
16865
+ action: "Wait for the running operation to finish, read the project again, then rename with the new ETag."
16866
+ },
16754
16867
  project_identity_unavailable: {
16755
16868
  status: 503,
16756
16869
  retryable: true,
@@ -16816,6 +16929,11 @@ var PROBLEM_POLICY = {
16816
16929
  retryable: false,
16817
16930
  action: "Run 'ohmyhost init', apply the matching ohmyhost framework skill, then plan the new commit."
16818
16931
  },
16932
+ repository_configuration_missing: {
16933
+ status: 409,
16934
+ retryable: false,
16935
+ action: "Place ohmyhost.yaml at the Git repository root and set applicationRoot to the application directory (for example website). Commit and push the change, then plan the new commit."
16936
+ },
16819
16937
  migration_filename_noncanonical: {
16820
16938
  status: 409,
16821
16939
  retryable: false,
@@ -16909,7 +17027,7 @@ var parsePaidDomain = (value) => {
16909
17027
  ]);
16910
17028
  const status = input["status"];
16911
17029
  const hostname = input["hostname"];
16912
- const records = input["validation_records"];
17030
+ const records2 = input["validation_records"];
16913
17031
  if (![
16914
17032
  "not_configured",
16915
17033
  "pending",
@@ -16922,7 +17040,7 @@ var parsePaidDomain = (value) => {
16922
17040
  "paid_plan_required",
16923
17041
  "insufficient_organization_credits",
16924
17042
  "project_budget_exceeded"
16925
- ].includes(input["suspension_reason"]) || status === "suspended" !== (input["suspension_reason"] !== null) || status === "suspended" && input["url"] !== null || input["environment"] !== "prod" || !isSaasCnameTarget(input["cname_target"]) || hostname !== null && !isPaidHostname(hostname) || input["custom_hostname_status"] !== null && typeof input["custom_hostname_status"] !== "string" || input["ssl_status"] !== null && typeof input["ssl_status"] !== "string" || !Array.isArray(records) || records.length > 16 || !records.every(isPaidValidationRecord) || input["url"] !== null && input["url"] !== `https://${String(hostname)}`) {
17043
+ ].includes(input["suspension_reason"]) || status === "suspended" !== (input["suspension_reason"] !== null) || status === "suspended" && input["url"] !== null || input["environment"] !== "prod" || !isSaasCnameTarget(input["cname_target"]) || hostname !== null && !isPaidHostname(hostname) || input["custom_hostname_status"] !== null && typeof input["custom_hostname_status"] !== "string" || input["ssl_status"] !== null && typeof input["ssl_status"] !== "string" || !Array.isArray(records2) || records2.length > 16 || !records2.every(isPaidValidationRecord) || input["url"] !== null && input["url"] !== `https://${String(hostname)}`) {
16926
17044
  throw new ResponseContractError();
16927
17045
  }
16928
17046
  return input;
@@ -17074,7 +17192,7 @@ var parseDevAccessTicket = (value) => {
17074
17192
  ]);
17075
17193
  const origin = input["origin"];
17076
17194
  const redeemUrl = input["redeem_url"];
17077
- if (!isUlid(input["ticket_id"]) || !isUlid(input["project_id"]) || !isUlid(input["environment_id"]) || typeof origin !== "string" || !/^https:\/\/dev-[a-z]+-[a-z]+-[a-z]+\.(?:dev\.)?check\.omh\.st$/u.test(origin) || typeof redeemUrl !== "string" || !/^https:\/\/dev-[a-z]+-[a-z]+-[a-z]+\.(?:dev\.)?check\.omh\.st\/\.ohmyhost\/dev-access\/redeem\?stage=dev&ticket=[A-Za-z0-9_-]{43}$/u.test(redeemUrl) || new URL(redeemUrl).origin !== origin || !isIsoInstant(input["expires_at"])) {
17195
+ if (!isUlid(input["ticket_id"]) || !isUlid(input["project_id"]) || !isUlid(input["environment_id"]) || typeof origin !== "string" || !/^https:\/\/dev-[a-z0-9]+(?:-[a-z0-9]+){0,4}\.(?:dev\.)?check\.omh\.st$/u.test(origin) || typeof redeemUrl !== "string" || !/^https:\/\/dev-[a-z0-9]+(?:-[a-z0-9]+){0,4}\.(?:dev\.)?check\.omh\.st\/\.ohmyhost\/dev-access\/redeem\?stage=dev&ticket=[A-Za-z0-9_-]{43}$/u.test(redeemUrl) || new URL(redeemUrl).origin !== origin || !isIsoInstant(input["expires_at"])) {
17078
17196
  throw new ResponseContractError();
17079
17197
  }
17080
17198
  return input;
@@ -17197,7 +17315,7 @@ var parseProject = (value) => {
17197
17315
  "region",
17198
17316
  "created_at"
17199
17317
  ]);
17200
- if (!isUlid(input["id"]) || !isUlid(input["organization_id"]) || !boundedString(input["name"], 1, 128) || input["name"] !== input["name"].trim() || !boundedString(input["handle"], 5, 59) || !/^[a-z]+-[a-z]+-[a-z]+$/u.test(input["handle"]) || input["data_mode"] !== "shared" && input["data_mode"] !== "isolated" || input["region"] !== "us" && input["region"] !== "eu" || !isIsoInstant(input["created_at"])) {
17318
+ if (!isUlid(input["id"]) || !isUlid(input["organization_id"]) || !boundedString(input["name"], 1, 128) || input["name"] !== input["name"].trim() || !boundedString(input["handle"], 3, 59) || !/^[a-z0-9]+(?:-[a-z0-9]+){0,4}$/u.test(input["handle"]) || input["data_mode"] !== "shared" && input["data_mode"] !== "isolated" || input["region"] !== "us" && input["region"] !== "eu" || !isIsoInstant(input["created_at"])) {
17201
17319
  throw new ResponseContractError();
17202
17320
  }
17203
17321
  return input;
@@ -17215,6 +17333,7 @@ var parseProjectPage = (value) => {
17215
17333
  var parseProjectStatus = (value) => {
17216
17334
  const input = exactRecord2(value, [
17217
17335
  "project_id",
17336
+ "etag",
17218
17337
  "handle",
17219
17338
  "region",
17220
17339
  "lifecycle",
@@ -17228,7 +17347,7 @@ var parseProjectStatus = (value) => {
17228
17347
  "cleanup_state"
17229
17348
  ]);
17230
17349
  const handle = input["handle"];
17231
- if (!isUlid(input["project_id"]) || !boundedString(handle, 5, 59) || !/^[a-z]+-[a-z]+-[a-z]+$/u.test(handle) || input["region"] !== "us" && input["region"] !== "eu" || input["lifecycle"] !== "active" && input["lifecycle"] !== "deleting" && input["lifecycle"] !== "deleted" || input["dev_url"] !== null && ![`https://dev-${handle}.dev.check.omh.st`, `https://dev-${handle}.check.omh.st`].includes(String(input["dev_url"])) || input["prod_url"] !== null && ![`https://${handle}.dev.check.omh.st`, `https://${handle}.check.omh.st`].includes(String(input["prod_url"])) || input["cleanup_state"] !== "not_started" && input["cleanup_state"] !== "pending" && input["cleanup_state"] !== "completed" && input["cleanup_state"] !== "reconciliation_required") {
17350
+ if (!isUlid(input["project_id"]) || typeof input["etag"] !== "string" || !/^"sha256-[a-f0-9]{64}"$/u.test(input["etag"]) || !boundedString(handle, 3, 59) || !/^[a-z0-9]+(?:-[a-z0-9]+){0,4}$/u.test(handle) || input["region"] !== "us" && input["region"] !== "eu" || input["lifecycle"] !== "active" && input["lifecycle"] !== "deleting" && input["lifecycle"] !== "deleted" || input["dev_url"] !== null && ![`https://dev-${handle}.dev.check.omh.st`, `https://dev-${handle}.check.omh.st`].includes(String(input["dev_url"])) || input["prod_url"] !== null && ![`https://${handle}.dev.check.omh.st`, `https://${handle}.check.omh.st`].includes(String(input["prod_url"])) || input["cleanup_state"] !== "not_started" && input["cleanup_state"] !== "pending" && input["cleanup_state"] !== "completed" && input["cleanup_state"] !== "reconciliation_required") {
17232
17351
  throw new ResponseContractError();
17233
17352
  }
17234
17353
  if (input["source"] !== null)
@@ -17248,10 +17367,10 @@ var parseProjectStatus = (value) => {
17248
17367
  const ids = /* @__PURE__ */ new Set(), names = /* @__PURE__ */ new Set();
17249
17368
  for (const raw of environments) {
17250
17369
  const environment = exactRecord2(raw, ["id", "name"]);
17251
- const id2 = environment["id"], name = environment["name"];
17252
- if (!isUlid(id2) || name !== "dev" && name !== "prod" || ids.has(id2) || names.has(name))
17370
+ const id3 = environment["id"], name = environment["name"];
17371
+ if (!isUlid(id3) || name !== "dev" && name !== "prod" || ids.has(id3) || names.has(name))
17253
17372
  throw new ResponseContractError();
17254
- ids.add(id2);
17373
+ ids.add(id3);
17255
17374
  names.add(name);
17256
17375
  }
17257
17376
  }
@@ -17395,45 +17514,6 @@ var parseEnvironmentSecretDeletion = (value) => {
17395
17514
  function validDelivery(input) {
17396
17515
  return Number.isSafeInteger(input["desired_generation"]) && Number(input["desired_generation"]) >= 0 && Number.isSafeInteger(input["applied_generation"]) && Number(input["applied_generation"]) >= 0 && Number(input["applied_generation"]) <= Number(input["desired_generation"]) && ["not_deployed", "pending", "ready", "failed"].includes(String(input["delivery_state"])) && (input["runtime_provider"] === null || input["runtime_provider"] === "wfp") && Number.isSafeInteger(input["applied_secret_count"]) && Number(input["applied_secret_count"]) >= 0 && Number(input["applied_secret_count"]) <= 100 && (input["last_error"] === null || typeof input["last_error"] === "string" && /^[A-Z][A-Z0-9_]{0,63}$/u.test(input["last_error"]));
17397
17516
  }
17398
- var parseProjectMailDomain = (value) => {
17399
- const input = exactRecord2(value, [
17400
- "domain",
17401
- "status",
17402
- "configured_at",
17403
- "name_servers",
17404
- "change_id",
17405
- "observed_at",
17406
- "verification_issue",
17407
- "next_check_after_seconds"
17408
- ]);
17409
- if (typeof input["domain"] !== "string" || !/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/u.test(input["domain"]) || !isIsoInstant(input["configured_at"])) {
17410
- throw new ResponseContractError();
17411
- }
17412
- if (input["status"] === "configured") {
17413
- if (input["name_servers"] !== void 0 || input["change_id"] !== void 0 || input["observed_at"] !== void 0 || input["verification_issue"] !== void 0 || input["next_check_after_seconds"] !== void 0) {
17414
- throw new ResponseContractError();
17415
- }
17416
- return input;
17417
- }
17418
- if (!["delegation_required", "ready", "verification_pending", "verification_failed"].includes(String(input["status"])) || !Array.isArray(input["name_servers"]) || input["name_servers"].length !== 4 || new Set(input["name_servers"]).size !== 4 || input["name_servers"].some((nameServer) => typeof nameServer !== "string" || !/^ns-[0-9]{1,4}\.awsdns-[0-9]{1,2}\.(?:com|net|org|co\.uk)$/u.test(nameServer)) || typeof input["change_id"] !== "string" || !/^C[A-Z0-9]{8,31}$/u.test(input["change_id"])) {
17419
- throw new ResponseContractError();
17420
- }
17421
- if (input["observed_at"] !== void 0) {
17422
- if (![
17423
- null,
17424
- "identity_missing",
17425
- "identity_verification_failed",
17426
- "dkim_verification_failed",
17427
- "dkim_records_changed",
17428
- "tenant_association_missing"
17429
- ].includes(input["verification_issue"]))
17430
- throw new ResponseContractError();
17431
- if (!isIsoInstant(input["observed_at"]) || input["next_check_after_seconds"] !== (input["status"] === "ready" ? null : 3600))
17432
- throw new ResponseContractError();
17433
- } else if (input["next_check_after_seconds"] !== void 0 || input["verification_issue"] !== void 0 || ["verification_pending", "verification_failed"].includes(String(input["status"])))
17434
- throw new ResponseContractError();
17435
- return input;
17436
- };
17437
17517
  var parseDeploymentPlan = (value) => {
17438
17518
  const input = exactRecord2(value, [
17439
17519
  "id",
@@ -17538,13 +17618,14 @@ var parseSafeProblem = (value) => {
17538
17618
  if (typeof code !== "string" || !(code in PROBLEM_POLICY))
17539
17619
  throw new ResponseContractError();
17540
17620
  const policy = PROBLEM_POLICY[code];
17541
- if (input["status"] !== policy.status || !boundedString(input["type"], 1, 512) || !isHttpsUrl(input["type"]) || !boundedString(input["title"], 1, 160) || !boundedString(input["request_id"], 1, 128) || typeof input["retryable"] !== "boolean" || !boundedString(input["suggested_action"], 1, 500) || input["detail"] !== void 0 && !boundedString(input["detail"], 1, 2e3) || input["instance"] !== void 0 && !boundedString(input["instance"], 1, 512)) {
17621
+ if (input["status"] !== policy.status || !boundedString(input["type"], 1, 512) || !isHttpsUrl(input["type"]) || !boundedString(input["title"], 1, 160) || !boundedString(input["request_id"], 1, 128) || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(input["request_id"]) || typeof input["retryable"] !== "boolean" || !boundedString(input["suggested_action"], 1, 500) || input["detail"] !== void 0 && !boundedString(input["detail"], 1, 2e3) || input["instance"] !== void 0 && !boundedString(input["instance"], 1, 512)) {
17542
17622
  throw new ResponseContractError();
17543
17623
  }
17544
17624
  const retryAfter = input["retry_after_seconds"];
17545
17625
  if (retryAfter !== void 0 && (code !== "rate_limited" || typeof retryAfter !== "number" || !Number.isSafeInteger(retryAfter) || retryAfter < 1 || retryAfter > 86400))
17546
17626
  throw new ResponseContractError();
17547
17627
  return {
17628
+ requestId: input["request_id"],
17548
17629
  code,
17549
17630
  retryable: policy.retryable,
17550
17631
  suggestedAction: (code === "framework_conversion_required" ? parseFrameworkConversionDetail(input["detail"]) ?? policy.action : policy.action) + (retryAfter === void 0 ? "" : ` Retry after ${String(retryAfter)} seconds.`),
@@ -17563,15 +17644,15 @@ var parseOperation = (value) => {
17563
17644
  "reconciliation",
17564
17645
  "progress"
17565
17646
  ]);
17566
- const id2 = input["id"];
17647
+ const id3 = input["id"];
17567
17648
  const state = input["state"];
17568
17649
  const createdAt = input["created_at"];
17569
17650
  const updatedAt = input["updated_at"];
17570
17651
  const result = input["result"];
17571
17652
  const blockingOperationId = input["blocking_operation_id"];
17572
- if (blockingOperationId !== void 0 && (state !== "queued" || !isUlid(blockingOperationId) || blockingOperationId === id2))
17653
+ if (blockingOperationId !== void 0 && (state !== "queued" || !isUlid(blockingOperationId) || blockingOperationId === id3))
17573
17654
  throw new ResponseContractError();
17574
- if (!isUlid(id2) || !isOperationState(state) || !isIsoInstant(createdAt) || !isIsoInstant(updatedAt) || result !== void 0 && !isRecord(result)) {
17655
+ if (!isUlid(id3) || !isOperationState(state) || !isIsoInstant(createdAt) || !isIsoInstant(updatedAt) || result !== void 0 && !isRecord(result)) {
17575
17656
  throw new ResponseContractError();
17576
17657
  }
17577
17658
  let progress;
@@ -17611,7 +17692,7 @@ var parseOperation = (value) => {
17611
17692
  throw new ResponseContractError();
17612
17693
  }
17613
17694
  return {
17614
- id: id2,
17695
+ id: id3,
17615
17696
  state,
17616
17697
  created_at: createdAt,
17617
17698
  updated_at: updatedAt,
@@ -17818,7 +17899,7 @@ function exact2(v, keys) {
17818
17899
  // apps/product-cli/package.json
17819
17900
  var package_default = {
17820
17901
  name: "@ohmyhost/product-cli",
17821
- version: "0.1.11",
17902
+ version: "0.1.14",
17822
17903
  private: true,
17823
17904
  ohmyhost: {
17824
17905
  deployment: "production",
@@ -18182,6 +18263,7 @@ var HELP_USAGE = Object.freeze({
18182
18263
  "project status": "ohmyhost project status --project ULID --json",
18183
18264
  "project dev-access create": "ohmyhost project dev-access create --project ULID --json",
18184
18265
  "project handle check": "ohmyhost project handle check --handle HANDLE --json (is this address free? answers with a reason and free alternatives; the address becomes HANDLE.check.omh.st)",
18266
+ "project handle set": "ohmyhost project handle set --project ULID --handle HANDLE --if-match ETAG --idempotency-key KEY --json (moves the project to a free address; the old one stops working and anyone may claim it)",
18185
18267
  "database compute set": "ohmyhost database compute set --project ULID --environment dev|prod --profile standard|performance --idempotency-key KEY --yes [--wait] --json\n standard: Free 0.25 CU/1 GB/60s idle, Paid 0.5 CU/2 GB/60s idle. performance: Paid 1 CU/4 GB/300s idle, 2.5x database compute credits per equal active minute; longer idle time also consumes credits.",
18186
18268
  "database compute get": "ohmyhost database compute get --project ULID [--environment dev|prod] --json",
18187
18269
  "database write": "ohmyhost database write --project ULID --environment dev|prod --statement-file PATH --idempotency-key KEY [--parameters-json JSON] --yes --json",
@@ -18214,8 +18296,16 @@ var HELP_USAGE = Object.freeze({
18214
18296
  "function runs": "ohmyhost function runs --project ULID --environment ENVIRONMENT_ULID [--limit 1-100] --json",
18215
18297
  "secret set": `printf '%s' "$SECRET_VALUE" | ohmyhost secret set NAME --project ULID --environment ENVIRONMENT_ULID --idempotency-key KEY --stdin [--wait] --json`,
18216
18298
  "secret delete": "ohmyhost secret delete NAME --project ULID --environment ENVIRONMENT_ULID --idempotency-key KEY [--wait] --json",
18217
- "mail domain set": "ohmyhost mail domain set --project ULID --domain DOMAIN --idempotency-key KEY --json",
18218
- "mail domain status": "ohmyhost mail domain status --project ULID --json"
18299
+ "mail setup": "ohmyhost mail setup --project ULID --environment ULID --domain DOMAIN --sending true --receiving false --idempotency-key KEY --json",
18300
+ "mail status": "ohmyhost mail status --project ULID --environment ULID --json",
18301
+ "mail webhook set": "ohmyhost mail webhook set --project ULID --environment ULID --url HTTPS_URL --idempotency-key KEY --json",
18302
+ "mail webhook verify": "ohmyhost mail webhook verify --project ULID --environment ULID --idempotency-key KEY --json",
18303
+ "mail webhook disable": "ohmyhost mail webhook disable --project ULID --environment ULID --idempotency-key KEY --json",
18304
+ "mail messages list": "ohmyhost mail messages list --project ULID --environment ULID [--after ULID] --json",
18305
+ "mail messages get": "ohmyhost mail messages get --project ULID --environment ULID --message ULID --json",
18306
+ "mail messages retry": "ohmyhost mail messages retry --project ULID --environment ULID --message ULID --idempotency-key KEY --json",
18307
+ "mail domain set": "ohmyhost mail domain set --project ULID --environment ULID --domain DOMAIN --sending true --receiving false --idempotency-key KEY --json",
18308
+ "mail domain status": "ohmyhost mail domain status --project ULID --environment ULID --json"
18219
18309
  });
18220
18310
  var HELP_COMMANDS = Object.freeze(Object.entries(HELP_USAGE).map(([command, usage]) => Object.freeze({ command, usage })));
18221
18311
  var cliMetadataResult = (kind, topic) => kind === "help" ? success("help", {
@@ -18458,6 +18548,8 @@ var ProductCli = class {
18458
18548
  return await this.listProjects(command, signal);
18459
18549
  if (command.kind === "project-handle-check")
18460
18550
  return await this.checkProjectHandle(command, signal);
18551
+ if (command.kind === "project-handle-set")
18552
+ return await this.changeProjectHandle(command, signal);
18461
18553
  if (command.kind === "database-compute-set") {
18462
18554
  const api = await this.authenticatedApi(command.credentialStore, signal);
18463
18555
  let operation = parseOperation(await api.changeDatabaseCompute(command));
@@ -18591,10 +18683,12 @@ var ProductCli = class {
18591
18683
  return await this.listFunctionRuns(command, signal);
18592
18684
  if (command.kind === "secret-set")
18593
18685
  return await this.putEnvironmentSecret(command, signal);
18594
- if (command.kind === "mail-domain-set")
18595
- return await this.configureMailDomain(command, signal);
18596
- if (command.kind === "mail-domain-status")
18597
- return await this.getMailDomain(command, signal);
18686
+ if (command.kind === "managed-mail") {
18687
+ const api = await this.authenticatedApi(command.credentialStore, signal);
18688
+ if (!api.managedMail)
18689
+ throw new Error("Mail unavailable");
18690
+ return success(command.label, { mail: await api.managedMail(command.request) });
18691
+ }
18598
18692
  return await this.deleteEnvironmentSecret(command, signal);
18599
18693
  } catch (error) {
18600
18694
  if (error instanceof UserTokenFileError)
@@ -18797,6 +18891,16 @@ var ProductCli = class {
18797
18891
  }));
18798
18892
  return success("project list", { status: "succeeded", projects });
18799
18893
  }
18894
+ async changeProjectHandle(command, signal) {
18895
+ const api = await this.authenticatedApi(command.credentialStore, signal);
18896
+ const operation = parseOperation(await api.changeProjectHandle({
18897
+ projectId: command.projectId,
18898
+ handle: command.handle,
18899
+ ifMatch: command.ifMatch,
18900
+ idempotencyKey: command.idempotencyKey
18901
+ }));
18902
+ return success("project handle set", { status: "accepted", operation });
18903
+ }
18800
18904
  async checkProjectHandle(command, signal) {
18801
18905
  const api = await this.authenticatedApi(command.credentialStore, signal);
18802
18906
  const handle = await api.checkProjectHandle({ handle: command.handle });
@@ -18918,26 +19022,26 @@ var ProductCli = class {
18918
19022
  }
18919
19023
  async applyPaidDomain(command, signal) {
18920
19024
  const api = await this.authenticatedApi(command.credentialStore, signal);
18921
- const domain = parsePaidDomain(await api.applyPaidDomain({
19025
+ const domain2 = parsePaidDomain(await api.applyPaidDomain({
18922
19026
  projectId: command.projectId,
18923
19027
  hostname: command.hostname,
18924
19028
  idempotencyKey: command.idempotencyKey
18925
19029
  }));
18926
- return success("domain paid apply", { status: domain.status, domain });
19030
+ return success("domain paid apply", { status: domain2.status, domain: domain2 });
18927
19031
  }
18928
19032
  async getPaidDomain(command, signal) {
18929
19033
  const api = await this.authenticatedApi(command.credentialStore, signal);
18930
- const domain = parsePaidDomain(await api.getPaidDomain(command.projectId));
18931
- return success("domain paid status", { status: domain.status, domain });
19034
+ const domain2 = parsePaidDomain(await api.getPaidDomain(command.projectId));
19035
+ return success("domain paid status", { status: domain2.status, domain: domain2 });
18932
19036
  }
18933
19037
  async deletePaidDomain(command, signal) {
18934
19038
  const api = await this.authenticatedApi(command.credentialStore, signal);
18935
- const domain = parsePaidDomain(await api.deletePaidDomain({
19039
+ const domain2 = parsePaidDomain(await api.deletePaidDomain({
18936
19040
  projectId: command.projectId,
18937
19041
  hostname: command.hostname,
18938
19042
  idempotencyKey: command.idempotencyKey
18939
19043
  }));
18940
- return success("domain paid delete", { status: domain.status, domain });
19044
+ return success("domain paid delete", { status: domain2.status, domain: domain2 });
18941
19045
  }
18942
19046
  async linkSource(command, signal) {
18943
19047
  const api = await this.authenticatedApi(command.credentialStore, signal);
@@ -19157,20 +19261,6 @@ var ProductCli = class {
19157
19261
  }
19158
19262
  throw new ProductCliFailure(8, "secret_delivery_wait_timeout", true, "Run 'ohmyhost secret list --json' to inspect delivery metadata.");
19159
19263
  }
19160
- async configureMailDomain(command, signal) {
19161
- const api = await this.authenticatedApi(command.credentialStore, signal);
19162
- const mailDomain = parseProjectMailDomain(await api.configureMailDomain({
19163
- projectId: command.projectId,
19164
- domain: command.domain,
19165
- idempotencyKey: command.idempotencyKey
19166
- }));
19167
- return success("mail domain set", { status: mailDomain.status, mail_domain: mailDomain });
19168
- }
19169
- async getMailDomain(command, signal) {
19170
- const api = await this.authenticatedApi(command.credentialStore, signal);
19171
- const mailDomain = parseProjectMailDomain(await api.getMailDomain(command.projectId));
19172
- return success("mail domain status", { status: mailDomain.status, mail_domain: mailDomain });
19173
- }
19174
19264
  async waitForOperation(api, initial, signal) {
19175
19265
  let operation = initial;
19176
19266
  for (let attempt = 0; attempt < 120 && (operation.state === "queued" || operation.state === "running") && operation.reconciliation?.state !== "required"; attempt += 1) {
@@ -19306,7 +19396,7 @@ var classifyFailure = (command, error, signal) => {
19306
19396
  if (looksLikeProblem(error)) {
19307
19397
  try {
19308
19398
  const problem = parseSafeProblem(error);
19309
- return failure(command, 7, problem.code, problem.retryable, problem.suggestedAction, void 0, problem.retryAfterSeconds);
19399
+ return failure(command, 7, problem.code, problem.retryable, problem.suggestedAction, void 0, problem.retryAfterSeconds, problem.requestId);
19310
19400
  } catch {
19311
19401
  return failure(command, 7, "response_contract_invalid", false, "Retry only after the client or server contract is repaired.");
19312
19402
  }
@@ -19326,7 +19416,7 @@ var success = (command, body) => ({
19326
19416
  `,
19327
19417
  stderr: ""
19328
19418
  });
19329
- var failure = (command, exitCode, code, retryable, suggestedAction, operation, retryAfterSeconds) => {
19419
+ var failure = (command, exitCode, code, retryable, suggestedAction, operation, retryAfterSeconds, requestId) => {
19330
19420
  const document = {
19331
19421
  version: 1,
19332
19422
  command,
@@ -19337,6 +19427,7 @@ var failure = (command, exitCode, code, retryable, suggestedAction, operation, r
19337
19427
  retryable,
19338
19428
  suggested_action: suggestedAction,
19339
19429
  ...retryAfterSeconds === void 0 ? {} : { retry_after_seconds: retryAfterSeconds },
19430
+ ...requestId === void 0 ? {} : { request_id: requestId },
19340
19431
  ...operation?.error === void 0 ? {} : { message: operation.error.message }
19341
19432
  }
19342
19433
  };
@@ -19408,6 +19499,8 @@ var parsedCommandName = (command) => {
19408
19499
  return "project dev-access create";
19409
19500
  if (command.kind === "project-handle-check")
19410
19501
  return "project handle check";
19502
+ if (command.kind === "project-handle-set")
19503
+ return "project handle set";
19411
19504
  if (command.kind === "database-write")
19412
19505
  return "database write";
19413
19506
  if (command.kind === "database-query")
@@ -19456,10 +19549,8 @@ var parsedCommandName = (command) => {
19456
19549
  return "secret set";
19457
19550
  if (command.kind === "secret-delete")
19458
19551
  return "secret delete";
19459
- if (command.kind === "mail-domain-set")
19460
- return "mail domain set";
19461
- if (command.kind === "mail-domain-status")
19462
- return "mail domain status";
19552
+ if (command.kind === "managed-mail")
19553
+ return command.label;
19463
19554
  return command.kind;
19464
19555
  };
19465
19556
  var boundedSignal = (parent, timeoutMs) => AbortSignal.any([parent, AbortSignal.timeout(timeoutMs)]);
@@ -19562,17 +19653,6 @@ var diagnosticDescriptor = (error, signal) => {
19562
19653
  return { category: "internal", subsystem: "runtime", errorKind: "unexpected" };
19563
19654
  };
19564
19655
 
19565
- // packages/contracts/dist/feedback.js
19566
- var identifier = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
19567
- function parseFeedbackReceipt(value) {
19568
- if (typeof value !== "object" || value === null || Array.isArray(value))
19569
- throw new TypeError("Feedback was not acknowledged");
19570
- const v = value;
19571
- if (Object.keys(v).sort().join(",") !== "id,organization_id,submitted_at" || typeof v["id"] !== "string" || !identifier.test(v["id"]) || typeof v["organization_id"] !== "string" || !identifier.test(v["organization_id"]) || typeof v["submitted_at"] !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u.test(v["submitted_at"]) || !Number.isFinite(Date.parse(v["submitted_at"])) || new Date(v["submitted_at"]).toISOString() !== v["submitted_at"])
19572
- throw new TypeError("Feedback was not acknowledged");
19573
- return v;
19574
- }
19575
-
19576
19656
  // packages/sdk-ts/dist/generated/core/bodySerializer.gen.js
19577
19657
  var jsonBodySerializer = {
19578
19658
  bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value)
@@ -20155,27 +20235,27 @@ var Interceptors = class {
20155
20235
  clear() {
20156
20236
  this.fns = [];
20157
20237
  }
20158
- eject(id2) {
20159
- const index = this.getInterceptorIndex(id2);
20238
+ eject(id3) {
20239
+ const index = this.getInterceptorIndex(id3);
20160
20240
  if (this.fns[index]) {
20161
20241
  this.fns[index] = null;
20162
20242
  }
20163
20243
  }
20164
- exists(id2) {
20165
- const index = this.getInterceptorIndex(id2);
20244
+ exists(id3) {
20245
+ const index = this.getInterceptorIndex(id3);
20166
20246
  return Boolean(this.fns[index]);
20167
20247
  }
20168
- getInterceptorIndex(id2) {
20169
- if (typeof id2 === "number") {
20170
- return this.fns[id2] ? id2 : -1;
20248
+ getInterceptorIndex(id3) {
20249
+ if (typeof id3 === "number") {
20250
+ return this.fns[id3] ? id3 : -1;
20171
20251
  }
20172
- return this.fns.indexOf(id2);
20252
+ return this.fns.indexOf(id3);
20173
20253
  }
20174
- update(id2, fn) {
20175
- const index = this.getInterceptorIndex(id2);
20254
+ update(id3, fn) {
20255
+ const index = this.getInterceptorIndex(id3);
20176
20256
  if (this.fns[index]) {
20177
20257
  this.fns[index] = fn;
20178
- return id2;
20258
+ return id3;
20179
20259
  }
20180
20260
  return false;
20181
20261
  }
@@ -21106,6 +21186,31 @@ var getCloudflareDnsAuthorizationStatus = (parameters, options) => {
21106
21186
  ...params
21107
21187
  });
21108
21188
  };
21189
+ var changeProjectHandle = (parameters, options) => {
21190
+ const params = buildClientParams([parameters], [
21191
+ {
21192
+ args: [
21193
+ { in: "headers", key: "X-Request-Id" },
21194
+ { in: "headers", key: "Idempotency-Key" },
21195
+ { in: "headers", key: "If-Match" },
21196
+ { in: "path", key: "project_id" },
21197
+ { in: "body", key: "handle" }
21198
+ ]
21199
+ }
21200
+ ]);
21201
+ return (options?.client ?? client).put({
21202
+ responseStyle: "data",
21203
+ security: [{ scheme: "bearer", type: "http" }],
21204
+ url: "/v1/projects/{project_id}/handle",
21205
+ ...options,
21206
+ ...params,
21207
+ headers: {
21208
+ "Content-Type": "application/json",
21209
+ ...options?.headers,
21210
+ ...params.headers
21211
+ }
21212
+ });
21213
+ };
21109
21214
  var configureProjectDomains = (parameters, options) => {
21110
21215
  const params = buildClientParams([parameters], [
21111
21216
  {
@@ -21212,47 +21317,6 @@ var applyPaidProjectDomain = (parameters, options) => {
21212
21317
  }
21213
21318
  });
21214
21319
  };
21215
- var getProjectMailDomain = (parameters, options) => {
21216
- const params = buildClientParams([parameters], [
21217
- {
21218
- args: [
21219
- { in: "headers", key: "X-Request-Id" },
21220
- { in: "path", key: "project_id" }
21221
- ]
21222
- }
21223
- ]);
21224
- return (options?.client ?? client).get({
21225
- responseStyle: "data",
21226
- security: [{ scheme: "bearer", type: "http" }],
21227
- url: "/v1/projects/{project_id}/mail-domain",
21228
- ...options,
21229
- ...params
21230
- });
21231
- };
21232
- var configureProjectMailDomain = (parameters, options) => {
21233
- const params = buildClientParams([parameters], [
21234
- {
21235
- args: [
21236
- { in: "headers", key: "X-Request-Id" },
21237
- { in: "headers", key: "Idempotency-Key" },
21238
- { in: "path", key: "project_id" },
21239
- { key: "configureProjectMailDomainRequest", map: "body" }
21240
- ]
21241
- }
21242
- ]);
21243
- return (options?.client ?? client).put({
21244
- responseStyle: "data",
21245
- security: [{ scheme: "bearer", type: "http" }],
21246
- url: "/v1/projects/{project_id}/mail-domain",
21247
- ...options,
21248
- ...params,
21249
- headers: {
21250
- "Content-Type": "application/json",
21251
- ...options?.headers,
21252
- ...params.headers
21253
- }
21254
- });
21255
- };
21256
21320
  var planDeployment = (parameters, options) => {
21257
21321
  const params = buildClientParams([parameters], [
21258
21322
  {
@@ -21719,6 +21783,384 @@ var streamOperationEvents = (parameters, options) => {
21719
21783
  ...params
21720
21784
  });
21721
21785
  };
21786
+ var getManagedMailDomain = (parameters, options) => {
21787
+ const params = buildClientParams([parameters], [
21788
+ {
21789
+ args: [
21790
+ { in: "headers", key: "X-Request-Id" },
21791
+ { in: "path", key: "project_id" },
21792
+ { in: "path", key: "environment_id" }
21793
+ ]
21794
+ }
21795
+ ]);
21796
+ return (options?.client ?? client).get({
21797
+ responseStyle: "data",
21798
+ security: [{ scheme: "bearer", type: "http" }],
21799
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail-domain",
21800
+ ...options,
21801
+ ...params
21802
+ });
21803
+ };
21804
+ var configureManagedMailDomain = (parameters, options) => {
21805
+ const params = buildClientParams([parameters], [
21806
+ {
21807
+ args: [
21808
+ { in: "headers", key: "X-Request-Id" },
21809
+ { in: "headers", key: "Idempotency-Key" },
21810
+ { in: "path", key: "project_id" },
21811
+ { in: "path", key: "environment_id" },
21812
+ { key: "managedMailDomainRequest", map: "body" }
21813
+ ]
21814
+ }
21815
+ ]);
21816
+ return (options?.client ?? client).put({
21817
+ responseStyle: "data",
21818
+ security: [{ scheme: "bearer", type: "http" }],
21819
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail-domain",
21820
+ ...options,
21821
+ ...params,
21822
+ headers: {
21823
+ "Content-Type": "application/json",
21824
+ ...options?.headers,
21825
+ ...params.headers
21826
+ }
21827
+ });
21828
+ };
21829
+ var disableManagedMailReceiving = (parameters, options) => {
21830
+ const params = buildClientParams([parameters], [
21831
+ {
21832
+ args: [
21833
+ { in: "headers", key: "X-Request-Id" },
21834
+ { in: "headers", key: "Idempotency-Key" },
21835
+ { in: "path", key: "project_id" },
21836
+ { in: "path", key: "environment_id" }
21837
+ ]
21838
+ }
21839
+ ]);
21840
+ return (options?.client ?? client).delete({
21841
+ responseStyle: "data",
21842
+ security: [{ scheme: "bearer", type: "http" }],
21843
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail-webhook",
21844
+ ...options,
21845
+ ...params
21846
+ });
21847
+ };
21848
+ var prepareManagedMailWebhook = (parameters, options) => {
21849
+ const params = buildClientParams([parameters], [
21850
+ {
21851
+ args: [
21852
+ { in: "headers", key: "X-Request-Id" },
21853
+ { in: "headers", key: "Idempotency-Key" },
21854
+ { in: "path", key: "project_id" },
21855
+ { in: "path", key: "environment_id" },
21856
+ { key: "managedMailWebhookRequest", map: "body" }
21857
+ ]
21858
+ }
21859
+ ]);
21860
+ return (options?.client ?? client).put({
21861
+ responseStyle: "data",
21862
+ security: [{ scheme: "bearer", type: "http" }],
21863
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail-webhook",
21864
+ ...options,
21865
+ ...params,
21866
+ headers: {
21867
+ "Content-Type": "application/json",
21868
+ ...options?.headers,
21869
+ ...params.headers
21870
+ }
21871
+ });
21872
+ };
21873
+ var verifyManagedMailWebhook = (parameters, options) => {
21874
+ const params = buildClientParams([parameters], [
21875
+ {
21876
+ args: [
21877
+ { in: "headers", key: "X-Request-Id" },
21878
+ { in: "headers", key: "Idempotency-Key" },
21879
+ { in: "path", key: "project_id" },
21880
+ { in: "path", key: "environment_id" }
21881
+ ]
21882
+ }
21883
+ ]);
21884
+ return (options?.client ?? client).post({
21885
+ responseStyle: "data",
21886
+ security: [{ scheme: "bearer", type: "http" }],
21887
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail-webhook/verify",
21888
+ ...options,
21889
+ ...params
21890
+ });
21891
+ };
21892
+ var listManagedMailMessages = (parameters, options) => {
21893
+ const params = buildClientParams([parameters], [
21894
+ {
21895
+ args: [
21896
+ { in: "headers", key: "X-Request-Id" },
21897
+ { in: "path", key: "project_id" },
21898
+ { in: "path", key: "environment_id" },
21899
+ { in: "query", key: "after" }
21900
+ ]
21901
+ }
21902
+ ]);
21903
+ return (options?.client ?? client).get({
21904
+ responseStyle: "data",
21905
+ security: [{ scheme: "bearer", type: "http" }],
21906
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail/messages",
21907
+ ...options,
21908
+ ...params
21909
+ });
21910
+ };
21911
+ var getManagedMailMessage = (parameters, options) => {
21912
+ const params = buildClientParams([parameters], [
21913
+ {
21914
+ args: [
21915
+ { in: "headers", key: "X-Request-Id" },
21916
+ { in: "path", key: "project_id" },
21917
+ { in: "path", key: "environment_id" },
21918
+ { in: "path", key: "message_id" }
21919
+ ]
21920
+ }
21921
+ ]);
21922
+ return (options?.client ?? client).get({
21923
+ responseStyle: "data",
21924
+ security: [{ scheme: "bearer", type: "http" }],
21925
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail/messages/{message_id}",
21926
+ ...options,
21927
+ ...params
21928
+ });
21929
+ };
21930
+ var retryManagedMailMessage = (parameters, options) => {
21931
+ const params = buildClientParams([parameters], [
21932
+ {
21933
+ args: [
21934
+ { in: "headers", key: "X-Request-Id" },
21935
+ { in: "headers", key: "Idempotency-Key" },
21936
+ { in: "path", key: "project_id" },
21937
+ { in: "path", key: "environment_id" },
21938
+ { in: "path", key: "message_id" }
21939
+ ]
21940
+ }
21941
+ ]);
21942
+ return (options?.client ?? client).post({
21943
+ responseStyle: "data",
21944
+ security: [{ scheme: "bearer", type: "http" }],
21945
+ url: "/v1/projects/{project_id}/environments/{environment_id}/mail/messages/{message_id}/retry",
21946
+ ...options,
21947
+ ...params
21948
+ });
21949
+ };
21950
+
21951
+ // packages/sdk-ts/dist/managed-mail-response.js
21952
+ var ULID = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
21953
+ function assertManagedMailResponse(value, input) {
21954
+ const r = object2(value);
21955
+ if (input.action === "configure" || input.action === "status" || input.action === "webhook_verify") {
21956
+ exact3(r, [
21957
+ "domain_id",
21958
+ "domain",
21959
+ "environment_id",
21960
+ "sending",
21961
+ "receiving",
21962
+ "status",
21963
+ "configured_at",
21964
+ "observed_at",
21965
+ "dns_records",
21966
+ "webhook",
21967
+ "next_check_after_seconds"
21968
+ ], ["dns"]);
21969
+ id2(r["domain_id"]);
21970
+ domain(r["domain"]);
21971
+ if (r["environment_id"] !== input.environmentId)
21972
+ invalid3();
21973
+ for (const key of ["sending", "receiving"])
21974
+ if (!["disabled", "pending", "ready", "failed"].includes(String(r[key])))
21975
+ invalid3();
21976
+ if (!["ready", "verification_pending"].includes(String(r["status"])))
21977
+ invalid3();
21978
+ time(r["configured_at"]);
21979
+ if (r["observed_at"] !== null)
21980
+ time(r["observed_at"]);
21981
+ records(r["dns_records"]);
21982
+ if (r["next_check_after_seconds"] !== null && r["next_check_after_seconds"] !== 60)
21983
+ invalid3();
21984
+ if (r["webhook"] !== null) {
21985
+ const hook = object2(r["webhook"]);
21986
+ exact3(hook, ["url", "verified"]);
21987
+ https(hook["url"]);
21988
+ if (typeof hook["verified"] !== "boolean")
21989
+ invalid3();
21990
+ }
21991
+ if (r["dns"] !== void 0) {
21992
+ const dns = object2(r["dns"]);
21993
+ exact3(dns, ["status", "records"]);
21994
+ if (!["configured", "action_required", "conflict"].includes(String(dns["status"])))
21995
+ invalid3();
21996
+ records(dns["records"]);
21997
+ }
21998
+ return;
21999
+ }
22000
+ if (input.action === "webhook_set") {
22001
+ exact3(r, ["url", "signing_secret", "status"]);
22002
+ 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"]))
22003
+ invalid3();
22004
+ return;
22005
+ }
22006
+ if (input.action === "webhook_disable") {
22007
+ exact3(r, ["status"]);
22008
+ if (r["status"] !== "disabled")
22009
+ invalid3();
22010
+ return;
22011
+ }
22012
+ if (input.action === "messages_list") {
22013
+ exact3(r, ["items"]);
22014
+ if (!Array.isArray(r["items"]) || r["items"].length > 50)
22015
+ invalid3();
22016
+ for (const value2 of r["items"]) {
22017
+ const item = object2(value2);
22018
+ exact3(item, ["message_id", "received_at", "state", "attempts"]);
22019
+ id2(item["message_id"]);
22020
+ time(item["received_at"]);
22021
+ if (!["pending", "delivering", "delivered", "delivery_failed", "expired"].includes(String(item["state"])) || !Number.isInteger(item["attempts"]) || Number(item["attempts"]) < 0 || Number(item["attempts"]) > 4)
22022
+ invalid3();
22023
+ }
22024
+ return;
22025
+ }
22026
+ if (input.action === "message_retry") {
22027
+ exact3(r, ["attempted"], ["delivered"]);
22028
+ if (typeof r["attempted"] !== "boolean" || r["delivered"] !== void 0 && typeof r["delivered"] !== "boolean")
22029
+ invalid3();
22030
+ return;
22031
+ }
22032
+ if (input.action !== "message_get")
22033
+ invalid3();
22034
+ if (r["status"] === "expired") {
22035
+ exact3(r, ["status"]);
22036
+ return;
22037
+ }
22038
+ exact3(r, [
22039
+ "id",
22040
+ "domain",
22041
+ "received_at",
22042
+ "expires_at",
22043
+ "from",
22044
+ "to",
22045
+ "subject",
22046
+ "text",
22047
+ "html",
22048
+ "message_id",
22049
+ "attachments"
22050
+ ]);
22051
+ if (r["id"] !== input.messageId)
22052
+ invalid3();
22053
+ domain(r["domain"]);
22054
+ time(r["received_at"]);
22055
+ time(r["expires_at"]);
22056
+ if (Date.parse(String(r["expires_at"])) - Date.parse(String(r["received_at"])) !== 72 * 36e5)
22057
+ invalid3();
22058
+ for (const key of ["from", "subject", "message_id"])
22059
+ if (typeof r[key] !== "string")
22060
+ invalid3();
22061
+ for (const key of ["text", "html"])
22062
+ if (r[key] !== null && typeof r[key] !== "string")
22063
+ invalid3();
22064
+ if (!Array.isArray(r["to"]) || r["to"].some((v) => typeof v !== "string" || v.slice(v.lastIndexOf("@") + 1).toLowerCase() !== r["domain"]))
22065
+ invalid3();
22066
+ if (!Array.isArray(r["attachments"]))
22067
+ invalid3();
22068
+ for (const value2 of r["attachments"]) {
22069
+ const a = object2(value2);
22070
+ exact3(a, ["id", "filename", "content_type", "download_path"]);
22071
+ 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"]}`)
22072
+ invalid3();
22073
+ }
22074
+ }
22075
+ function object2(v) {
22076
+ if (typeof v !== "object" || v === null || Array.isArray(v))
22077
+ invalid3();
22078
+ return v;
22079
+ }
22080
+ function exact3(v, required, optional = []) {
22081
+ if (required.some((k) => !(k in v)) || Object.keys(v).some((k) => !required.includes(k) && !optional.includes(k)))
22082
+ invalid3();
22083
+ }
22084
+ function id2(v) {
22085
+ if (typeof v !== "string" || !ULID.test(v))
22086
+ invalid3();
22087
+ }
22088
+ function domain(v) {
22089
+ if (typeof v !== "string" || !/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/u.test(v))
22090
+ invalid3();
22091
+ }
22092
+ function time(v) {
22093
+ if (typeof v !== "string" || !Number.isFinite(Date.parse(v)) || new Date(v).toISOString() !== v)
22094
+ invalid3();
22095
+ }
22096
+ function https(v) {
22097
+ if (typeof v !== "string" || !v.startsWith("https://"))
22098
+ invalid3();
22099
+ }
22100
+ function records(v) {
22101
+ if (!Array.isArray(v))
22102
+ invalid3();
22103
+ for (const value of v) {
22104
+ const r = object2(value);
22105
+ exact3(r, ["type", "name", "value", "purpose", "status"], ["priority"]);
22106
+ 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))
22107
+ invalid3();
22108
+ }
22109
+ }
22110
+ function invalid3() {
22111
+ throw new TypeError("Mail response contract invalid");
22112
+ }
22113
+
22114
+ // packages/sdk-ts/dist/managed-mail.js
22115
+ function requestManagedMail(client2, input) {
22116
+ const scope = { project_id: input.projectId, environment_id: input.environmentId };
22117
+ switch (input.action) {
22118
+ case "configure":
22119
+ return configureManagedMailDomain({
22120
+ ...scope,
22121
+ "Idempotency-Key": input.idempotencyKey,
22122
+ managedMailDomainRequest: {
22123
+ domain: input.domain,
22124
+ sending: input.sending,
22125
+ receiving: input.receiving
22126
+ }
22127
+ }, { client: client2 });
22128
+ case "status":
22129
+ return getManagedMailDomain(scope, { client: client2 });
22130
+ case "webhook_set":
22131
+ return prepareManagedMailWebhook({
22132
+ ...scope,
22133
+ "Idempotency-Key": input.idempotencyKey,
22134
+ managedMailWebhookRequest: { url: input.url }
22135
+ }, { client: client2 });
22136
+ case "webhook_verify":
22137
+ return verifyManagedMailWebhook({ ...scope, "Idempotency-Key": input.idempotencyKey }, { client: client2 });
22138
+ case "webhook_disable":
22139
+ return disableManagedMailReceiving({ ...scope, "Idempotency-Key": input.idempotencyKey }, { client: client2 });
22140
+ case "messages_list":
22141
+ return listManagedMailMessages({ ...scope, ...input.after ? { after: input.after } : {} }, { client: client2 });
22142
+ case "message_get":
22143
+ return getManagedMailMessage({ ...scope, message_id: input.messageId }, { client: client2 });
22144
+ case "message_retry":
22145
+ return retryManagedMailMessage({ ...scope, message_id: input.messageId, "Idempotency-Key": input.idempotencyKey }, { client: client2 });
22146
+ }
22147
+ }
22148
+ async function executeManagedMail(client2, input) {
22149
+ const result = await requestManagedMail(client2, input);
22150
+ assertManagedMailResponse(result, input);
22151
+ return result;
22152
+ }
22153
+
22154
+ // packages/contracts/dist/feedback.js
22155
+ var identifier = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u;
22156
+ function parseFeedbackReceipt(value) {
22157
+ if (typeof value !== "object" || value === null || Array.isArray(value))
22158
+ throw new TypeError("Feedback was not acknowledged");
22159
+ const v = value;
22160
+ if (Object.keys(v).sort().join(",") !== "id,organization_id,submitted_at" || typeof v["id"] !== "string" || !identifier.test(v["id"]) || typeof v["organization_id"] !== "string" || !identifier.test(v["organization_id"]) || typeof v["submitted_at"] !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u.test(v["submitted_at"]) || !Number.isFinite(Date.parse(v["submitted_at"])) || new Date(v["submitted_at"]).toISOString() !== v["submitted_at"])
22161
+ throw new TypeError("Feedback was not acknowledged");
22162
+ return v;
22163
+ }
21722
22164
 
21723
22165
  // apps/product-cli/dist/product-api.js
21724
22166
  var GeneratedSdkProductApi = class {
@@ -21852,6 +22294,14 @@ var GeneratedSdkProductApi = class {
21852
22294
  async listProjects(input) {
21853
22295
  return listProjects(input, { client: this.#client });
21854
22296
  }
22297
+ async changeProjectHandle(input) {
22298
+ return changeProjectHandle({
22299
+ project_id: input.projectId,
22300
+ "Idempotency-Key": input.idempotencyKey,
22301
+ "If-Match": input.ifMatch,
22302
+ handle: input.handle
22303
+ }, { client: this.#client });
22304
+ }
21855
22305
  async checkProjectHandle(input) {
21856
22306
  return getProjectHandleAvailability({ handle: input.handle }, { client: this.#client });
21857
22307
  }
@@ -22080,15 +22530,8 @@ var GeneratedSdkProductApi = class {
22080
22530
  secret_name: input.name
22081
22531
  }, { client: this.#client });
22082
22532
  }
22083
- async configureMailDomain(input) {
22084
- return configureProjectMailDomain({
22085
- "Idempotency-Key": input.idempotencyKey,
22086
- project_id: input.projectId,
22087
- configureProjectMailDomainRequest: { domain: input.domain }
22088
- }, { client: this.#client });
22089
- }
22090
- async getMailDomain(projectId) {
22091
- return getProjectMailDomain({ project_id: projectId }, { client: this.#client });
22533
+ managedMail(input) {
22534
+ return executeManagedMail(this.#client, input);
22092
22535
  }
22093
22536
  };
22094
22537
 
@@ -22116,7 +22559,7 @@ var OwnerOnlyProjectLinkStore = class {
22116
22559
  // apps/product-cli/dist/repository-init.js
22117
22560
  import { createHash } from "node:crypto";
22118
22561
  import { lstat as lstat2, open as open3, readFile, readdir, stat } from "node:fs/promises";
22119
- import { posix, resolve as resolve2 } from "node:path";
22562
+ import { dirname as dirname2, posix, resolve as resolve2 } from "node:path";
22120
22563
 
22121
22564
  // packages/contracts/dist/application-root.js
22122
22565
  var APPLICATION_ROOT_PATTERN = /^(?:\.|[A-Za-z0-9][A-Za-z0-9._-]*(?:\/[A-Za-z0-9][A-Za-z0-9._-]*)*)$/u;
@@ -23132,7 +23575,7 @@ async function databaseContractBlockers(config, applicationDirectory, files) {
23132
23575
  if (DATABASE_PRIVATE_BINDING_PATTERN.test(source)) {
23133
23576
  blockers.push({
23134
23577
  code: "database_binding_private",
23135
- message: `${path} reaches for a managed database connection string. Hyperdrive, DATABASE_URL and postgres:// URLs are platform-private and never reach a customer Worker. Call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database".`
23578
+ message: `${path} reaches for a managed database connection string. HYPERDRIVE is retired; DATABASE_URL and postgres:// URLs never reach a customer Worker. Call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database".`
23136
23579
  });
23137
23580
  }
23138
23581
  if (DATABASE_SOCKET_DRIVER_PATTERN.test(source)) {
@@ -23155,8 +23598,8 @@ function migrationFilenameBlockers(files, configuredPath, provider) {
23155
23598
  return [];
23156
23599
  const root = configuredPath ?? "postgres/migrations";
23157
23600
  const prefix = `${root}/`;
23158
- const invalid3 = files.filter((path) => path.startsWith(prefix)).map((path) => path.slice(prefix.length)).some((path) => !/^(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*\d{14}_[a-z0-9][a-z0-9_-]*\.sql$/u.test(path));
23159
- return invalid3 ? [
23601
+ const invalid4 = files.filter((path) => path.startsWith(prefix)).map((path) => path.slice(prefix.length)).some((path) => !/^(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*\d{14}_[a-z0-9][a-z0-9_-]*\.sql$/u.test(path));
23602
+ return invalid4 ? [
23160
23603
  {
23161
23604
  code: "migration_filename_noncanonical",
23162
23605
  message: "Rename every PostgreSQL migration to YYYYMMDDHHMMSS_name.sql before initialization."
@@ -23363,6 +23806,24 @@ async function assertRepositoryRoot(root) {
23363
23806
  if (!information.isDirectory()) {
23364
23807
  throw new RepositoryInitError("repository_not_directory", "Repository path is not a directory");
23365
23808
  }
23809
+ for (let ancestor = root; ; ancestor = dirname2(ancestor)) {
23810
+ let marker;
23811
+ try {
23812
+ marker = await lstat2(resolve2(ancestor, ".git"));
23813
+ } catch (error) {
23814
+ if (error.code !== "ENOENT") {
23815
+ throw new RepositoryInitError("repository_unreadable", "Could not determine the Git repository root");
23816
+ }
23817
+ }
23818
+ if (marker !== void 0) {
23819
+ if (ancestor !== root) {
23820
+ throw new RepositoryInitError("repository_root_required", "Run ohmyhost init from the Git repository root and select the application directory with --root; ohmyhost.yaml must be at the repository root.");
23821
+ }
23822
+ return;
23823
+ }
23824
+ if (dirname2(ancestor) === ancestor)
23825
+ return;
23826
+ }
23366
23827
  }
23367
23828
  async function collectRepositoryFiles(root) {
23368
23829
  const files = [];
@@ -24340,7 +24801,7 @@ var runOfflineInit = async (command, io, diagnostics) => {
24340
24801
  });
24341
24802
  const code = error instanceof RepositoryInitBlockedError ? "repository_init_blocked" : error instanceof RepositoryInitConflictError ? "repository_configuration_exists" : known ? error.code : "internal_error";
24342
24803
  const exitCode = error instanceof RepositoryInitBlockedError ? 9 : known ? 2 : 1;
24343
- const result = errorDocument("init", exitCode, code, false, error instanceof RepositoryInitConflictError ? "Keep the existing ohmyhost.yaml or remove it explicitly before retrying." : error instanceof RepositoryInitError && error.code === "project_name_invalid" ? "Pass a lowercase deployment slug with '--project', then rerun init." : "Run 'ohmyhost init --dry-run --json' and resolve every reported blocker.");
24804
+ const result = errorDocument("init", exitCode, code, false, error instanceof RepositoryInitConflictError ? "Keep the existing ohmyhost.yaml or remove it explicitly before retrying." : error instanceof RepositoryInitError && error.code === "repository_root_required" ? "Run ohmyhost init from the Git repository root with --root set to the application directory (for example --root website); commit the root ohmyhost.yaml before planning." : error instanceof RepositoryInitError && error.code === "project_name_invalid" ? "Pass a lowercase deployment slug with '--project', then rerun init." : "Run 'ohmyhost init --dry-run --json' and resolve every reported blocker.");
24344
24805
  io.writeStdout(result.stdout);
24345
24806
  return result.exitCode;
24346
24807
  }