@amerged/ohmyhost-cli 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @amerged/ohmyhost-cli
2
2
 
3
- ohmyho.st cli client, version 0.1.24.
3
+ ohmyho.st cli client, version 0.1.26.
4
4
 
5
5
  ```sh
6
6
  npm install --global @amerged/ohmyhost-cli
@@ -57,7 +57,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
57
57
  SOFTWARE.
58
58
 
59
59
 
60
- ## fast-uri 3.1.6
60
+ ## fast-uri 3.1.7
61
61
 
62
62
  ### LICENSE
63
63
 
package/dist/bin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __ohmyhostCreateRequire } from "node:module"; const require = __ohmyhostCreateRequire(import.meta.url);
3
3
  import {
4
4
  runProductionCli
5
- } from "./chunk-QIJJFWW6.js";
5
+ } from "./chunk-YMVBC7UB.js";
6
6
  import "./chunk-7D2RFLWM.js";
7
7
 
8
8
  // apps/product-cli/dist/bin.js
@@ -3080,12 +3080,13 @@ var require_data = __commonJS({
3080
3080
  }
3081
3081
  });
3082
3082
 
3083
- // node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/utils.js
3083
+ // node_modules/.pnpm/fast-uri@3.1.7/node_modules/fast-uri/lib/utils.js
3084
3084
  var require_utils = __commonJS({
3085
- "node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/utils.js"(exports, module) {
3085
+ "node_modules/.pnpm/fast-uri@3.1.7/node_modules/fast-uri/lib/utils.js"(exports, module) {
3086
3086
  "use strict";
3087
3087
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3088
3088
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3089
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
3089
3090
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
3090
3091
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
3091
3092
  var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
@@ -3551,8 +3552,12 @@ var require_utils = __commonJS({
3551
3552
  uriTokens.push(host);
3552
3553
  }
3553
3554
  if (typeof component.port === "number" || typeof component.port === "string") {
3555
+ const port = String(component.port);
3556
+ if (!isPort(port)) {
3557
+ throw new TypeError("URI port is malformed.");
3558
+ }
3554
3559
  uriTokens.push(":");
3555
- uriTokens.push(String(component.port));
3560
+ uriTokens.push(port);
3556
3561
  }
3557
3562
  return uriTokens.length ? uriTokens.join("") : void 0;
3558
3563
  }
@@ -3577,9 +3582,9 @@ var require_utils = __commonJS({
3577
3582
  }
3578
3583
  });
3579
3584
 
3580
- // node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/schemes.js
3585
+ // node_modules/.pnpm/fast-uri@3.1.7/node_modules/fast-uri/lib/schemes.js
3581
3586
  var require_schemes = __commonJS({
3582
- "node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3587
+ "node_modules/.pnpm/fast-uri@3.1.7/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3583
3588
  "use strict";
3584
3589
  var { isUUID } = require_utils();
3585
3590
  var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
@@ -3788,9 +3793,9 @@ var require_schemes = __commonJS({
3788
3793
  }
3789
3794
  });
3790
3795
 
3791
- // node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/index.js
3796
+ // node_modules/.pnpm/fast-uri@3.1.7/node_modules/fast-uri/index.js
3792
3797
  var require_fast_uri = __commonJS({
3793
- "node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/index.js"(exports, module) {
3798
+ "node_modules/.pnpm/fast-uri@3.1.7/node_modules/fast-uri/index.js"(exports, module) {
3794
3799
  "use strict";
3795
3800
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3796
3801
  var { SCHEMES, getSchemeHandler } = require_schemes();
@@ -3995,12 +4000,15 @@ var require_fast_uri = __commonJS({
3995
4000
  }
3996
4001
  return false;
3997
4002
  }
4003
+ function isIPLiteral(host) {
4004
+ return host[0] === "[" && host[host.length - 1] === "]";
4005
+ }
3998
4006
  function hasMalformedComponentPercentEncoding(matches) {
3999
4007
  const host = matches[4];
4000
- return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4008
+ return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4001
4009
  }
4002
4010
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
4003
- if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4011
+ if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4004
4012
  try {
4005
4013
  parsed.host = new URL("http://" + parsed.host).hostname;
4006
4014
  } catch (e) {
@@ -4087,10 +4095,11 @@ var require_fast_uri = __commonJS({
4087
4095
  if (parsed.host) {
4088
4096
  const ipv4result = isIPv4(parsed.host);
4089
4097
  if (ipv4result === false) {
4090
- const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
4098
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
4099
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
4091
4100
  const ipv6result = normalizeIPv6(parsed.host);
4092
4101
  isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
4093
- malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
4102
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4094
4103
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4095
4104
  if (malformedIPLiteral) {
4096
4105
  parsed.error = parsed.error || "URI host is malformed.";
@@ -4113,7 +4122,9 @@ var require_fast_uri = __commonJS({
4113
4122
  parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
4114
4123
  }
4115
4124
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
4116
- malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4125
+ if (!malformedIPLiteral) {
4126
+ malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4127
+ }
4117
4128
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4118
4129
  if (uri.indexOf("%") !== -1) {
4119
4130
  if (parsed.host !== void 0 && !malformedIPLiteral) {
@@ -17008,9 +17019,6 @@ function isAdmittedFrameworkBuildScript(framework, script) {
17008
17019
  }
17009
17020
 
17010
17021
  // packages/contracts/dist/customer-auth-admission.js
17011
- function managedCustomerAuthMailMessage(path) {
17012
- return `"${path}" selects the managed Better Auth bridge, which sends verification and password-reset email through ohmyhost Mail. Set mail.enabled: true and set up a verified mail sender, or set auth.provider: none and keep the application-owned Better Auth configuration and sender. Commit and push the change, then plan the new commit.`;
17013
- }
17014
17022
  function managedCustomerAuthDatabaseMessage(path) {
17015
17023
  return `"${path}" selects the managed Better Auth bridge, which requires the managed PostgreSQL database. Set database.enabled: true with an admitted migrations path, or set auth.provider: none and keep the application-owned authentication configuration. Commit and push the change, then plan the new commit.`;
17016
17024
  }
@@ -17024,12 +17032,7 @@ function managedCustomerAuthAdmissionIssue(capabilities) {
17024
17032
  message: managedCustomerAuthDatabaseMessage("ohmyhost.yaml")
17025
17033
  });
17026
17034
  }
17027
- if (capabilities.mail?.enabled === true)
17028
- return null;
17029
- return Object.freeze({
17030
- code: "managed_auth_mail_required",
17031
- message: managedCustomerAuthMailMessage("ohmyhost.yaml")
17032
- });
17035
+ return null;
17033
17036
  }
17034
17037
 
17035
17038
  // packages/contracts/dist/framework-admission.js
@@ -17155,10 +17158,6 @@ var FRAMEWORK_CONVERSION_DETAILS = Object.freeze({
17155
17158
  render: managedCustomerAuthDatabaseMessage,
17156
17159
  pattern: /^"([^"]+)" selects the managed Better Auth bridge, which requires the managed PostgreSQL database\. Set database\.enabled: true with an admitted migrations path, or set auth\.provider: none and keep the application-owned authentication configuration\. Commit and push the change, then plan the new commit\.$/u
17157
17160
  }),
17158
- managed_auth_mail_required: Object.freeze({
17159
- render: managedCustomerAuthMailMessage,
17160
- pattern: /^"([^"]+)" selects the managed Better Auth bridge, which sends verification and password-reset email through ohmyhost Mail\. Set mail\.enabled: true and set up a verified mail sender, or set auth\.provider: none and keep the application-owned Better Auth configuration and sender\. Commit and push the change, then plan the new commit\.$/u
17161
- }),
17162
17161
  database_binding_private: Object.freeze({
17163
17162
  render: (path) => `"${path}" reads a database connection string (DATABASE_URL, HYPERDRIVE, connectionString or a postgres:// URL); none reaches a customer Worker. Call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database". ${PUSH_AND_PLAN}`,
17164
17163
  pattern: /^"([^"]+)" reads a database connection string \(DATABASE_URL, HYPERDRIVE, connectionString or a postgres:\/\/ URL\); none reaches a customer Worker\. Call the database with createPrivateDatabaseClient from "@ohmyhost\/customer-runtime\/database"\. Commit and push the change, then plan the new commit\.$/u
@@ -17205,7 +17204,7 @@ function parseFrameworkConversionDiagnostic(value) {
17205
17204
  const record5 = value;
17206
17205
  const path = record5["path"];
17207
17206
  const code = record5["code"];
17208
- if (Object.keys(record5).length !== 2 || !isFrameworkConversionDiagnosticCode(code) || typeof path !== "string" || path.length > 240 || (code === "managed_auth_mail_required" || code === "managed_auth_database_required" ? path !== "ohmyhost.yaml" : !/^[A-Za-z0-9_@()[\]./-]+\.(?:[cm]?[jt]sx?)$/u.test(path)) || path.split("/").some((segment) => segment === "" || segment === "." || segment === ".."))
17207
+ if (Object.keys(record5).length !== 2 || !isFrameworkConversionDiagnosticCode(code) || typeof path !== "string" || path.length > 240 || (code === "managed_auth_database_required" ? path !== "ohmyhost.yaml" : !/^[A-Za-z0-9_@()[\]./-]+\.(?:[cm]?[jt]sx?)$/u.test(path)) || path.split("/").some((segment) => segment === "" || segment === "." || segment === ".."))
17209
17208
  return null;
17210
17209
  return Object.freeze({ code, path });
17211
17210
  }
@@ -18948,7 +18947,7 @@ function exact2(v, keys) {
18948
18947
  // apps/product-cli/package.json
18949
18948
  var package_default = {
18950
18949
  name: "@ohmyhost/product-cli",
18951
- version: "0.1.24",
18950
+ version: "0.1.26",
18952
18951
  private: true,
18953
18952
  ohmyhost: {
18954
18953
  deployment: "production",
@@ -25239,7 +25238,8 @@ async function initializeRepository(input) {
25239
25238
  const project = projectName(input.project, packageJson);
25240
25239
  const repositoryAdmissionBlockers = repositoryBlockers(packageJson, framework, nextStandaloneOutput, tanStackRuntime, applicationFiles, packageManagerAdmission, frameworkConfigs, compatibility, existingConfiguration);
25241
25240
  const supabaseMigrationCount = applicationFiles.filter((path) => /^supabase\/migrations\/[^/]+\.sql$/u.test(path)).length;
25242
- const postgresMigrationCount = applicationFiles.filter((path) => /^postgres\/migrations\/[^/]+\.sql$/u.test(path)).length;
25241
+ const postgresMigrationRoot = existingConfiguration?.database?.migrations ?? "postgres/migrations";
25242
+ const postgresMigrationCount = applicationFiles.filter((path) => path.startsWith(`${postgresMigrationRoot}/`) && path.endsWith(".sql")).length;
25243
25243
  const edgeFunctionNames = new Set(applicationFiles.flatMap((path) => {
25244
25244
  const match = path.match(/^supabase\/functions\/([^/]+)\//u);
25245
25245
  return match?.[1] === void 0 || match[1].startsWith("_") ? [] : [match[1]];
@@ -25249,6 +25249,7 @@ async function initializeRepository(input) {
25249
25249
  const configuredDatabase = existingConfiguration?.database?.enabled === true;
25250
25250
  const databaseProvider = supabaseMigrationCount > 0 ? "supabase" : postgresMigrationCount > 0 || configuredDatabase ? "postgresql" : "none";
25251
25251
  const migrationCount = databaseProvider === "supabase" ? supabaseMigrationCount : postgresMigrationCount;
25252
+ const selectedDatabaseProvider = existingConfiguration === null ? databaseProvider : configuredDatabase ? "postgresql" : "none";
25252
25253
  const betterAuth = dependencies.has("better-auth") || existingConfiguration?.auth?.provider === "better-auth";
25253
25254
  const workos = [
25254
25255
  "@workos-inc/authkit-react",
@@ -25301,19 +25302,19 @@ async function initializeRepository(input) {
25301
25302
  });
25302
25303
  const configurationYaml = existingConfigurationYaml ?? generatedConfigurationYaml;
25303
25304
  const capabilities = Object.freeze({
25304
- database: databaseProvider !== "none",
25305
+ database: selectedDatabaseProvider !== "none",
25305
25306
  auth: targetBetterAuth,
25306
25307
  mail: targetMail,
25307
25308
  storage: targetStorage
25308
25309
  });
25309
25310
  const companion = companionRequired ? viteCompanionScaffold(applicationFiles, capabilities) : null;
25310
25311
  const companionSourcePresent = companion !== null && applicationFiles.includes(companion.sourceEntryPoint);
25311
- const migrationSqlAdmissionBlockers = await migrationSqlBlockers(applicationDirectory, applicationFiles, existingConfiguration?.database?.migrations, databaseProvider);
25312
+ const migrationSqlAdmissionBlockers = await migrationSqlBlockers(applicationDirectory, applicationFiles, existingConfiguration?.database?.migrations, selectedDatabaseProvider);
25312
25313
  const blockers = [
25313
25314
  ...repositoryAdmissionBlockers,
25314
25315
  ...await workerModuleBlockers(framework, applicationDirectory, applicationFiles),
25315
25316
  ...await cronBlockers(framework, existingConfiguration, applicationDirectory, applicationFiles),
25316
- ...migrationFilenameBlockers(applicationFiles, existingConfiguration?.database?.migrations, databaseProvider),
25317
+ ...selectedDatabaseProvider === "none" ? [] : migrationFilenameBlockers(applicationFiles, existingConfiguration?.database?.migrations, selectedDatabaseProvider),
25317
25318
  ...migrationSqlAdmissionBlockers,
25318
25319
  ...await storageClientBlockers(existingConfiguration, applicationDirectory, applicationFiles),
25319
25320
  ...await databaseContractBlockers(existingConfiguration, applicationDirectory, applicationFiles)
@@ -25882,9 +25883,9 @@ function repositoryBlockers(packageJson, framework, nextStandaloneOutput, tanSta
25882
25883
  });
25883
25884
  }
25884
25885
  const betterAuthVersion = dependencyVersion(packageJson, "better-auth");
25885
- const managedMailIssue = managedCustomerAuthAdmissionIssue(existingConfiguration);
25886
- if (managedMailIssue !== null)
25887
- blockers.push(managedMailIssue);
25886
+ const managedAuthIssue = managedCustomerAuthAdmissionIssue(existingConfiguration);
25887
+ if (managedAuthIssue !== null)
25888
+ blockers.push(managedAuthIssue);
25888
25889
  if (existingConfiguration?.auth?.provider === "better-auth" && betterAuthVersion !== null && betterAuthVersion !== SUPPORTED_BETTER_AUTH_VERSION) {
25889
25890
  blockers.push({
25890
25891
  code: "better_auth_version_unsupported",
package/dist/index.js CHANGED
@@ -86,7 +86,7 @@ import {
86
86
  selectWorkspace,
87
87
  verifiedUserId,
88
88
  workspaceOf
89
- } from "./chunk-QIJJFWW6.js";
89
+ } from "./chunk-YMVBC7UB.js";
90
90
  import {
91
91
  CredentialStoreIntegrityError,
92
92
  CredentialStoreUnavailableError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amerged/ohmyhost-cli",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ohmyhost/product-cli",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "private": true,
5
5
  "ohmyhost": {
6
6
  "deployment": "production",
@@ -102,7 +102,6 @@ export interface RepositoryInitBlocker {
102
102
  | "database_driver_unsupported"
103
103
  | "build_script_missing"
104
104
  | "better_auth_version_unsupported"
105
- | "managed_auth_mail_required"
106
105
  | "managed_auth_database_required"
107
106
  | "framework_ambiguous"
108
107
  | "framework_unsupported"
@@ -293,8 +292,10 @@ export async function initializeRepository(
293
292
  const supabaseMigrationCount = applicationFiles.filter((path) =>
294
293
  /^supabase\/migrations\/[^/]+\.sql$/u.test(path),
295
294
  ).length;
296
- const postgresMigrationCount = applicationFiles.filter((path) =>
297
- /^postgres\/migrations\/[^/]+\.sql$/u.test(path),
295
+ const postgresMigrationRoot =
296
+ existingConfiguration?.database?.migrations ?? "postgres/migrations";
297
+ const postgresMigrationCount = applicationFiles.filter(
298
+ (path) => path.startsWith(`${postgresMigrationRoot}/`) && path.endsWith(".sql"),
298
299
  ).length;
299
300
  const edgeFunctionNames = new Set(
300
301
  applicationFiles.flatMap((path) => {
@@ -315,6 +316,9 @@ export async function initializeRepository(
315
316
  : "none";
316
317
  const migrationCount =
317
318
  databaseProvider === "supabase" ? supabaseMigrationCount : postgresMigrationCount;
319
+ // Inventory remains evidence; an existing configuration selects the managed capabilities.
320
+ const selectedDatabaseProvider =
321
+ existingConfiguration === null ? databaseProvider : configuredDatabase ? "postgresql" : "none";
318
322
  const betterAuth =
319
323
  dependencies.has("better-auth") || existingConfiguration?.auth?.provider === "better-auth";
320
324
  const workos = [
@@ -390,7 +394,7 @@ export async function initializeRepository(
390
394
  });
391
395
  const configurationYaml = existingConfigurationYaml ?? generatedConfigurationYaml;
392
396
  const capabilities: RuntimeCapabilities = Object.freeze({
393
- database: databaseProvider !== "none",
397
+ database: selectedDatabaseProvider !== "none",
394
398
  auth: targetBetterAuth,
395
399
  mail: targetMail,
396
400
  storage: targetStorage,
@@ -404,7 +408,7 @@ export async function initializeRepository(
404
408
  applicationDirectory,
405
409
  applicationFiles,
406
410
  existingConfiguration?.database?.migrations,
407
- databaseProvider,
411
+ selectedDatabaseProvider,
408
412
  );
409
413
  const blockers = [
410
414
  ...repositoryAdmissionBlockers,
@@ -415,11 +419,13 @@ export async function initializeRepository(
415
419
  applicationDirectory,
416
420
  applicationFiles,
417
421
  )),
418
- ...migrationFilenameBlockers(
419
- applicationFiles,
420
- existingConfiguration?.database?.migrations,
421
- databaseProvider,
422
- ),
422
+ ...(selectedDatabaseProvider === "none"
423
+ ? []
424
+ : migrationFilenameBlockers(
425
+ applicationFiles,
426
+ existingConfiguration?.database?.migrations,
427
+ selectedDatabaseProvider,
428
+ )),
423
429
  ...migrationSqlAdmissionBlockers,
424
430
  ...(await storageClientBlockers(existingConfiguration, applicationDirectory, applicationFiles)),
425
431
  ...(await databaseContractBlockers(
@@ -1244,8 +1250,8 @@ function repositoryBlockers(
1244
1250
  });
1245
1251
  }
1246
1252
  const betterAuthVersion = dependencyVersion(packageJson, "better-auth");
1247
- const managedMailIssue = managedCustomerAuthAdmissionIssue(existingConfiguration);
1248
- if (managedMailIssue !== null) blockers.push(managedMailIssue);
1253
+ const managedAuthIssue = managedCustomerAuthAdmissionIssue(existingConfiguration);
1254
+ if (managedAuthIssue !== null) blockers.push(managedAuthIssue);
1249
1255
  if (
1250
1256
  existingConfiguration?.auth?.provider === "better-auth" &&
1251
1257
  betterAuthVersion !== null &&
@@ -4,19 +4,15 @@ export interface ManagedCustomerAuthCapabilities {
4
4
  readonly mail?: Readonly<{ enabled: boolean }>;
5
5
  }
6
6
 
7
- export function managedCustomerAuthMailMessage(path: string): string {
8
- return `"${path}" selects the managed Better Auth bridge, which sends verification and password-reset email through ohmyhost Mail. Set mail.enabled: true and set up a verified mail sender, or set auth.provider: none and keep the application-owned Better Auth configuration and sender. Commit and push the change, then plan the new commit.`;
9
- }
10
-
11
7
  export function managedCustomerAuthDatabaseMessage(path: string): string {
12
8
  return `"${path}" selects the managed Better Auth bridge, which requires the managed PostgreSQL database. Set database.enabled: true with an admitted migrations path, or set auth.provider: none and keep the application-owned authentication configuration. Commit and push the change, then plan the new commit.`;
13
9
  }
14
10
 
15
- /** Dependency inventory never selects the managed bridge; only the explicit auth capability does. */
11
+ /** Managed auth needs its real database; Mail remains an independent optional capability. */
16
12
  export function managedCustomerAuthAdmissionIssue(
17
13
  capabilities: ManagedCustomerAuthCapabilities | null | undefined,
18
14
  ): Readonly<{
19
- code: "managed_auth_database_required" | "managed_auth_mail_required";
15
+ code: "managed_auth_database_required";
20
16
  message: string;
21
17
  }> | null {
22
18
  if (capabilities?.auth?.provider !== "better-auth") {
@@ -28,9 +24,5 @@ export function managedCustomerAuthAdmissionIssue(
28
24
  message: managedCustomerAuthDatabaseMessage("ohmyhost.yaml"),
29
25
  });
30
26
  }
31
- if (capabilities.mail?.enabled === true) return null;
32
- return Object.freeze({
33
- code: "managed_auth_mail_required" as const,
34
- message: managedCustomerAuthMailMessage("ohmyhost.yaml"),
35
- });
27
+ return null;
36
28
  }
@@ -1,12 +1,6 @@
1
1
  import { PINNED_BUN_VERSION } from "./framework-build-script.mjs";
2
- import {
3
- managedCustomerAuthMailMessage,
4
- managedCustomerAuthDatabaseMessage,
5
- } from "./customer-auth-admission.js";
6
- export {
7
- managedCustomerAuthAdmissionIssue,
8
- managedCustomerAuthMailMessage,
9
- } from "./customer-auth-admission.js";
2
+ import { managedCustomerAuthDatabaseMessage } from "./customer-auth-admission.js";
3
+ export { managedCustomerAuthAdmissionIssue } from "./customer-auth-admission.js";
10
4
 
11
5
  export type PackageManagerName = "bun" | "npm" | "pnpm" | "yarn";
12
6
 
@@ -202,7 +196,6 @@ function versionAdmission(
202
196
 
203
197
  export type FrameworkConversionDiagnosticCode =
204
198
  | "managed_auth_database_required"
205
- | "managed_auth_mail_required"
206
199
  | "database_binding_private"
207
200
  | "database_driver_unsupported"
208
201
  | "source_syntax_invalid"
@@ -233,11 +226,6 @@ const FRAMEWORK_CONVERSION_DETAILS: Readonly<
233
226
  pattern:
234
227
  /^"([^"]+)" selects the managed Better Auth bridge, which requires the managed PostgreSQL database\. Set database\.enabled: true with an admitted migrations path, or set auth\.provider: none and keep the application-owned authentication configuration\. Commit and push the change, then plan the new commit\.$/u,
235
228
  }),
236
- managed_auth_mail_required: Object.freeze({
237
- render: managedCustomerAuthMailMessage,
238
- pattern:
239
- /^"([^"]+)" selects the managed Better Auth bridge, which sends verification and password-reset email through ohmyhost Mail\. Set mail\.enabled: true and set up a verified mail sender, or set auth\.provider: none and keep the application-owned Better Auth configuration and sender\. Commit and push the change, then plan the new commit\.$/u,
240
- }),
241
229
  database_binding_private: Object.freeze({
242
230
  render: (path: string) =>
243
231
  `"${path}" reads a database connection string (DATABASE_URL, HYPERDRIVE, connectionString or a postgres:// URL); none reaches a customer Worker. Call the database with createPrivateDatabaseClient from "@ohmyhost/customer-runtime/database". ${PUSH_AND_PLAN}`,
@@ -329,7 +317,7 @@ export function parseFrameworkConversionDiagnostic(
329
317
  !isFrameworkConversionDiagnosticCode(code) ||
330
318
  typeof path !== "string" ||
331
319
  path.length > 240 ||
332
- (code === "managed_auth_mail_required" || code === "managed_auth_database_required"
320
+ (code === "managed_auth_database_required"
333
321
  ? path !== "ohmyhost.yaml"
334
322
  : !/^[A-Za-z0-9_@()[\]./-]+\.(?:[cm]?[jt]sx?)$/u.test(path)) ||
335
323
  path.split("/").some((segment) => segment === "" || segment === "." || segment === "..")
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ohmyhost/sdk-ts",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -2749,7 +2749,7 @@ export const applyPaidProjectDomain = <ThrowOnError extends boolean = true>(
2749
2749
  /**
2750
2750
  * Plan a deployment
2751
2751
  *
2752
- * Resolves immutable inputs and estimates effects without provider mutation or billable work. The plan targets Dev unless `environment` is `prod`; a Prod plan builds straight into Prod, except that a project with shared data and a database only reaches Prod through promotion. Mail and the currently supported mail-backed Better Auth contract require a confirmed Paid service period; it is checked again before build reservation. An old sender configuration is not Paid authority.
2752
+ * Resolves immutable inputs and estimates effects without provider mutation or billable work. The plan targets Dev unless `environment` is `prod`; a Prod plan builds straight into Prod, except that a project with shared data and a database only reaches Prod through promotion. Managed mail requires a confirmed Paid service period; it is checked again before build reservation. Selecting the managed Better Auth bridge does not require managed mail or Paid access. An old sender configuration is not Paid authority.
2753
2753
  */
2754
2754
  export const planDeployment = <ThrowOnError extends boolean = true>(
2755
2755
  parameters: {