sealos-cli 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.cjs CHANGED
@@ -5542,6 +5542,40 @@ function normalizeDatabaseType(type) {
5542
5542
  return resolved;
5543
5543
  }
5544
5544
  __name(normalizeDatabaseType, "normalizeDatabaseType");
5545
+ function getDatabaseConnectScheme(type) {
5546
+ const databaseType = normalizeDatabaseType(type);
5547
+ const schemes = {
5548
+ postgresql: "postgresql",
5549
+ mongodb: "mongodb",
5550
+ "apecloud-mysql": "mysql",
5551
+ mysql: "mysql",
5552
+ redis: "redis",
5553
+ kafka: "kafka",
5554
+ qdrant: "qdrant",
5555
+ nebula: "nebula",
5556
+ weaviate: "weaviate",
5557
+ milvus: "milvus",
5558
+ pulsar: "pulsar",
5559
+ clickhouse: "clickhouse"
5560
+ };
5561
+ return schemes[databaseType];
5562
+ }
5563
+ __name(getDatabaseConnectScheme, "getDatabaseConnectScheme");
5564
+ function buildConsolePublicConnection(options) {
5565
+ if (!options.domain || !options.nodePort) return null;
5566
+ const scheme = getDatabaseConnectScheme(options.dbType);
5567
+ const port = String(options.nodePort);
5568
+ if (scheme === "kafka" || scheme === "milvus") {
5569
+ return `${options.domain}:${port}`;
5570
+ }
5571
+ if (!options.username || !options.password) return null;
5572
+ let connection = `${scheme}://${options.username}:${options.password}@${options.domain}:${port}`;
5573
+ if (scheme === "mongodb" || scheme === "postgresql") {
5574
+ connection += "/?directConnection=true";
5575
+ }
5576
+ return connection;
5577
+ }
5578
+ __name(buildConsolePublicConnection, "buildConsolePublicConnection");
5545
5579
  function normalizeLogDbType(type) {
5546
5580
  const normalized = normalizeDatabaseType(type);
5547
5581
  if (!SUPPORTED_LOG_DB_TYPES.includes(normalized)) {
@@ -5710,6 +5744,86 @@ function printConnectionDetail(connection) {
5710
5744
  outputTable(rows);
5711
5745
  }
5712
5746
  __name(printConnectionDetail, "printConnectionDetail");
5747
+ function buildPublicAccessResult(action, name, connection) {
5748
+ return {
5749
+ success: true,
5750
+ action,
5751
+ resource: "database",
5752
+ name,
5753
+ status: action === "enable-public" ? "enabled" : "disabled",
5754
+ publicConnection: connection?.publicConnection ?? null,
5755
+ connection: connection ?? null
5756
+ };
5757
+ }
5758
+ __name(buildPublicAccessResult, "buildPublicAccessResult");
5759
+ function getDatabaseProviderHost() {
5760
+ const override = process.env.SEALOS_DATABASE_HOST?.trim();
5761
+ if (override) {
5762
+ return override.replace(/\/+$/, "");
5763
+ }
5764
+ let authRegion;
5765
+ try {
5766
+ authRegion = loadAuth().region;
5767
+ } catch {
5768
+ authRegion = void 0;
5769
+ }
5770
+ return resolveDbproviderHost(process.env.SEALOS_REGION || authRegion || DEFAULT_SEALOS_REGION);
5771
+ }
5772
+ __name(getDatabaseProviderHost, "getDatabaseProviderHost");
5773
+ async function getLegacyApiData(path, headers) {
5774
+ const url = new URL(path, getDatabaseProviderHost());
5775
+ const response = await fetch(url, {
5776
+ headers: {
5777
+ Authorization: headers.Authorization
5778
+ }
5779
+ });
5780
+ const body = await response.json();
5781
+ if (!response.ok || body.code !== 200) {
5782
+ throw new Error(body.message || `Request failed: ${url.pathname}`);
5783
+ }
5784
+ return body.data;
5785
+ }
5786
+ __name(getLegacyApiData, "getLegacyApiData");
5787
+ async function fetchConsoleConnectionDetails(name, dbType, fallbackConnection, headers) {
5788
+ const [secret, service, config] = await Promise.all([
5789
+ getLegacyApiData(`/api/getSecretByName?dbName=${encodeURIComponent(name)}&dbType=${encodeURIComponent(dbType)}&mock=false`, headers),
5790
+ getLegacyApiData(`/api/getServiceByName?name=${encodeURIComponent(`${name}-export`)}`, headers).catch(() => null),
5791
+ getLegacyApiData("/api/platform/getClientAppConfig", headers).catch(() => null)
5792
+ ]);
5793
+ const nodePort = service?.spec?.ports?.find((port) => port.nodePort)?.nodePort;
5794
+ const publicConnection = buildConsolePublicConnection({
5795
+ dbType,
5796
+ username: secret.username,
5797
+ password: secret.password,
5798
+ domain: config?.domain,
5799
+ nodePort
5800
+ }) ?? fallbackConnection?.publicConnection ?? null;
5801
+ return {
5802
+ privateConnection: {
5803
+ endpoint: `${secret.host}:${secret.port}`,
5804
+ host: secret.host,
5805
+ port: secret.port,
5806
+ username: secret.username,
5807
+ password: secret.password,
5808
+ connectionString: secret.connection
5809
+ },
5810
+ publicConnection
5811
+ };
5812
+ }
5813
+ __name(fetchConsoleConnectionDetails, "fetchConsoleConnectionDetails");
5814
+ async function loadDatabaseConnectionDetails(name, headers) {
5815
+ const client = createDatabaseClient();
5816
+ const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
5817
+ headers,
5818
+ params: {
5819
+ path: { databaseName: name }
5820
+ }
5821
+ });
5822
+ if (error2) throw mapApiError(response.status, error2);
5823
+ if (!data.type) return data.connection ?? null;
5824
+ return await fetchConsoleConnectionDetails(name, data.type, data.connection, headers);
5825
+ }
5826
+ __name(loadDatabaseConnectionDetails, "loadDatabaseConnectionDetails");
5713
5827
  function createDatabaseCommand() {
5714
5828
  const dbCmd = new import_commander7.Command("database").alias("db").description("Manage databases");
5715
5829
  dbCmd.command("list").description("List databases").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading databases..." }, async (ctx, options) => {
@@ -5839,20 +5953,13 @@ function createDatabaseCommand() {
5839
5953
  printDatabaseDetail(data);
5840
5954
  }));
5841
5955
  dbCmd.command("connection <name>").description("Show database connection details").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading connection details..." }, async (ctx, name, options) => {
5842
- const client = createDatabaseClient();
5843
- const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
5844
- headers: ctx.auth,
5845
- params: {
5846
- path: { databaseName: name }
5847
- }
5848
- });
5849
- if (error2) throw mapApiError(response.status, error2);
5956
+ const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
5850
5957
  ctx.spinner.stop();
5851
5958
  if (options.output === "json") {
5852
- outputJson(data.connection ?? null);
5959
+ outputJson(connection);
5853
5960
  return;
5854
5961
  }
5855
- printConnectionDetail(data.connection);
5962
+ printConnectionDetail(connection);
5856
5963
  }));
5857
5964
  dbCmd.command("update <name>").description("Update database resources").option("--cpu <cpu>", "CPU cores per replica").option("--memory <memory>", "Memory in GB per replica").option("--storage <storage>", "Storage in GB per replica").option("--replicas <replicas>", "Replica count").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({
5858
5965
  spinnerText: "Updating database..."
@@ -6089,7 +6196,7 @@ function createDatabaseCommand() {
6089
6196
  }
6090
6197
  ctx.spinner.succeed(`Restore requested from backup "${options.from}"`);
6091
6198
  }));
6092
- dbCmd.command("enable-public <name>").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
6199
+ dbCmd.command("enable-public <name>").alias("expose").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
6093
6200
  const client = createDatabaseClient();
6094
6201
  const { error: error2, response } = await client.POST("/databases/{databaseName}/enable-public", {
6095
6202
  headers: ctx.auth,
@@ -6098,20 +6205,16 @@ function createDatabaseCommand() {
6098
6205
  }
6099
6206
  });
6100
6207
  if (error2) throw mapApiError(response.status, error2);
6208
+ const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
6101
6209
  if (options.output === "json") {
6102
6210
  ctx.spinner.stop();
6103
- outputJson({
6104
- success: true,
6105
- action: "enable-public",
6106
- resource: "database",
6107
- name,
6108
- status: "enabled"
6109
- });
6211
+ outputJson(buildPublicAccessResult("enable-public", name, connection));
6110
6212
  return;
6111
6213
  }
6112
6214
  ctx.spinner.succeed(`Public access enabled for "${name}"`);
6215
+ printConnectionDetail(connection);
6113
6216
  }));
6114
- dbCmd.command("disable-public <name>").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
6217
+ dbCmd.command("disable-public <name>").alias("unexpose").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
6115
6218
  const client = createDatabaseClient();
6116
6219
  const { error: error2, response } = await client.POST("/databases/{databaseName}/disable-public", {
6117
6220
  headers: ctx.auth,
@@ -6122,13 +6225,7 @@ function createDatabaseCommand() {
6122
6225
  if (error2) throw mapApiError(response.status, error2);
6123
6226
  if (options.output === "json") {
6124
6227
  ctx.spinner.stop();
6125
- outputJson({
6126
- success: true,
6127
- action: "disable-public",
6128
- resource: "database",
6129
- name,
6130
- status: "disabled"
6131
- });
6228
+ outputJson(buildPublicAccessResult("disable-public", name));
6132
6229
  return;
6133
6230
  }
6134
6231
  ctx.spinner.succeed(`Public access disabled for "${name}"`);
@@ -6214,6 +6311,22 @@ page=${data.data.metadata.page} total=${data.data.metadata.total} hasMore=${Stri
6214
6311
  }
6215
6312
  outputTable(rows);
6216
6313
  }));
6314
+ dbCmd.command("* [args...]", { hidden: true }).option("-o, --output <format>", "Output format (json|table)", "json").allowUnknownOption().action(async (args, options) => {
6315
+ const [name, operation, ...rest] = args;
6316
+ const aliases = {
6317
+ connection: "connection",
6318
+ connect: "connection",
6319
+ "enable-public": "enable-public",
6320
+ expose: "expose",
6321
+ "disable-public": "disable-public",
6322
+ unexpose: "unexpose"
6323
+ };
6324
+ const command = operation ? aliases[operation] : void 0;
6325
+ if (!name || !command) {
6326
+ throw new Error('Unknown database command. Use "sealos-cli database --help" to list supported commands.');
6327
+ }
6328
+ await dbCmd.parseAsync([command, name, ...rest, "--output", options.output], { from: "user" });
6329
+ });
6217
6330
  return dbCmd;
6218
6331
  }
6219
6332
  __name(createDatabaseCommand, "createDatabaseCommand");
@@ -6260,17 +6373,15 @@ async function resolveYaml(options, spinner2) {
6260
6373
  }
6261
6374
  __name(resolveYaml, "resolveYaml");
6262
6375
  function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin.isTTY) {
6263
- const isRaw = !!(options.file || options.yaml || !stdinIsTTY);
6264
- if (template && isRaw) {
6265
- throw new Error("Cannot specify both a template name and --file/--yaml/stdin. Use one or the other.");
6376
+ const hasExplicitRawInput = !!(options.file || options.yaml);
6377
+ const isRaw = hasExplicitRawInput || !template && !stdinIsTTY;
6378
+ if (template && hasExplicitRawInput) {
6379
+ throw new Error("Cannot specify both a template name and --file/--yaml. Use one or the other.");
6266
6380
  }
6267
6381
  if (!template && !isRaw) {
6268
6382
  throw new Error("Provide a template name or use --file/--yaml/stdin to supply raw YAML.");
6269
6383
  }
6270
6384
  if (template) {
6271
- if (!options.name) {
6272
- throw new Error("--name is required when deploying from the template catalog.");
6273
- }
6274
6385
  if (options.dryRun) {
6275
6386
  throw new Error("--dry-run is only supported for raw template deploys (--file, --yaml, or stdin).");
6276
6387
  }
@@ -6281,7 +6392,7 @@ function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin
6281
6392
  __name(resolveTemplateDeployMode, "resolveTemplateDeployMode");
6282
6393
  function buildCatalogTemplateDeployBody(template, options) {
6283
6394
  const body = {
6284
- name: options.name,
6395
+ name: options.name ?? template,
6285
6396
  template
6286
6397
  };
6287
6398
  if (options.set.length > 0) {
@@ -6491,9 +6602,10 @@ function createTemplateCommand() {
6491
6602
  }
6492
6603
  ctx.spinner.succeed(`Instance "${instance}" deleted`);
6493
6604
  }));
6494
- tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (required when deploying from catalog)").option("--file <path>", "Path to template YAML file").option("--yaml <yaml>", "Template YAML string").option("--set <KEY=VALUE...>", "Set template arguments", (val, prev) => [...prev, val], []).option("--dry-run", "Validate raw template YAML without creating resources").option("-o, --output <format>", "Output format (json|table)", "json").addHelpText("after", `
6605
+ tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (defaults to the catalog template name)").option("--file <path>", "Path to template YAML file").option("--yaml <yaml>", "Template YAML string").option("--set <KEY=VALUE...>", "Set template arguments", (val, prev) => [...prev, val], []).option("--dry-run", "Validate raw template YAML without creating resources").option("-o, --output <format>", "Output format (json|table)", "json").addHelpText("after", `
6495
6606
  Examples:
6496
6607
  Catalog:
6608
+ sealos-cli template deploy rybbit
6497
6609
  sealos-cli template deploy perplexica --name my-app --set OPENAI_API_KEY=xxx
6498
6610
 
6499
6611
  Raw:
@@ -6503,8 +6615,12 @@ kind: Template
6503
6615
  ...'
6504
6616
  cat template.yaml | sealos-cli template deploy --dry-run
6505
6617
  `).action(async (template, options) => {
6506
- const mode = resolveTemplateDeployMode(template, options);
6507
- await deployTemplate(template, options, mode);
6618
+ try {
6619
+ const mode = resolveTemplateDeployMode(template, options);
6620
+ await deployTemplate(template, options, mode);
6621
+ } catch (error2) {
6622
+ handleError(error2);
6623
+ }
6508
6624
  });
6509
6625
  return tplCmd;
6510
6626
  }
@@ -6513,7 +6629,7 @@ __name(createTemplateCommand, "createTemplateCommand");
6513
6629
  // package.json
6514
6630
  var package_default = {
6515
6631
  name: "sealos-cli",
6516
- version: "1.1.2",
6632
+ version: "1.1.3",
6517
6633
  description: "Official CLI tool for Sealos Cloud - Manage auth, workspaces, devboxes, databases, and templates",
6518
6634
  types: "dist/main.d.ts",
6519
6635
  type: "module",
package/dist/main.mjs CHANGED
@@ -5513,6 +5513,40 @@ function normalizeDatabaseType(type) {
5513
5513
  return resolved;
5514
5514
  }
5515
5515
  __name(normalizeDatabaseType, "normalizeDatabaseType");
5516
+ function getDatabaseConnectScheme(type) {
5517
+ const databaseType = normalizeDatabaseType(type);
5518
+ const schemes = {
5519
+ postgresql: "postgresql",
5520
+ mongodb: "mongodb",
5521
+ "apecloud-mysql": "mysql",
5522
+ mysql: "mysql",
5523
+ redis: "redis",
5524
+ kafka: "kafka",
5525
+ qdrant: "qdrant",
5526
+ nebula: "nebula",
5527
+ weaviate: "weaviate",
5528
+ milvus: "milvus",
5529
+ pulsar: "pulsar",
5530
+ clickhouse: "clickhouse"
5531
+ };
5532
+ return schemes[databaseType];
5533
+ }
5534
+ __name(getDatabaseConnectScheme, "getDatabaseConnectScheme");
5535
+ function buildConsolePublicConnection(options) {
5536
+ if (!options.domain || !options.nodePort) return null;
5537
+ const scheme = getDatabaseConnectScheme(options.dbType);
5538
+ const port = String(options.nodePort);
5539
+ if (scheme === "kafka" || scheme === "milvus") {
5540
+ return `${options.domain}:${port}`;
5541
+ }
5542
+ if (!options.username || !options.password) return null;
5543
+ let connection = `${scheme}://${options.username}:${options.password}@${options.domain}:${port}`;
5544
+ if (scheme === "mongodb" || scheme === "postgresql") {
5545
+ connection += "/?directConnection=true";
5546
+ }
5547
+ return connection;
5548
+ }
5549
+ __name(buildConsolePublicConnection, "buildConsolePublicConnection");
5516
5550
  function normalizeLogDbType(type) {
5517
5551
  const normalized = normalizeDatabaseType(type);
5518
5552
  if (!SUPPORTED_LOG_DB_TYPES.includes(normalized)) {
@@ -5681,6 +5715,86 @@ function printConnectionDetail(connection) {
5681
5715
  outputTable(rows);
5682
5716
  }
5683
5717
  __name(printConnectionDetail, "printConnectionDetail");
5718
+ function buildPublicAccessResult(action, name, connection) {
5719
+ return {
5720
+ success: true,
5721
+ action,
5722
+ resource: "database",
5723
+ name,
5724
+ status: action === "enable-public" ? "enabled" : "disabled",
5725
+ publicConnection: connection?.publicConnection ?? null,
5726
+ connection: connection ?? null
5727
+ };
5728
+ }
5729
+ __name(buildPublicAccessResult, "buildPublicAccessResult");
5730
+ function getDatabaseProviderHost() {
5731
+ const override = process.env.SEALOS_DATABASE_HOST?.trim();
5732
+ if (override) {
5733
+ return override.replace(/\/+$/, "");
5734
+ }
5735
+ let authRegion;
5736
+ try {
5737
+ authRegion = loadAuth().region;
5738
+ } catch {
5739
+ authRegion = void 0;
5740
+ }
5741
+ return resolveDbproviderHost(process.env.SEALOS_REGION || authRegion || DEFAULT_SEALOS_REGION);
5742
+ }
5743
+ __name(getDatabaseProviderHost, "getDatabaseProviderHost");
5744
+ async function getLegacyApiData(path, headers) {
5745
+ const url = new URL(path, getDatabaseProviderHost());
5746
+ const response = await fetch(url, {
5747
+ headers: {
5748
+ Authorization: headers.Authorization
5749
+ }
5750
+ });
5751
+ const body = await response.json();
5752
+ if (!response.ok || body.code !== 200) {
5753
+ throw new Error(body.message || `Request failed: ${url.pathname}`);
5754
+ }
5755
+ return body.data;
5756
+ }
5757
+ __name(getLegacyApiData, "getLegacyApiData");
5758
+ async function fetchConsoleConnectionDetails(name, dbType, fallbackConnection, headers) {
5759
+ const [secret, service, config] = await Promise.all([
5760
+ getLegacyApiData(`/api/getSecretByName?dbName=${encodeURIComponent(name)}&dbType=${encodeURIComponent(dbType)}&mock=false`, headers),
5761
+ getLegacyApiData(`/api/getServiceByName?name=${encodeURIComponent(`${name}-export`)}`, headers).catch(() => null),
5762
+ getLegacyApiData("/api/platform/getClientAppConfig", headers).catch(() => null)
5763
+ ]);
5764
+ const nodePort = service?.spec?.ports?.find((port) => port.nodePort)?.nodePort;
5765
+ const publicConnection = buildConsolePublicConnection({
5766
+ dbType,
5767
+ username: secret.username,
5768
+ password: secret.password,
5769
+ domain: config?.domain,
5770
+ nodePort
5771
+ }) ?? fallbackConnection?.publicConnection ?? null;
5772
+ return {
5773
+ privateConnection: {
5774
+ endpoint: `${secret.host}:${secret.port}`,
5775
+ host: secret.host,
5776
+ port: secret.port,
5777
+ username: secret.username,
5778
+ password: secret.password,
5779
+ connectionString: secret.connection
5780
+ },
5781
+ publicConnection
5782
+ };
5783
+ }
5784
+ __name(fetchConsoleConnectionDetails, "fetchConsoleConnectionDetails");
5785
+ async function loadDatabaseConnectionDetails(name, headers) {
5786
+ const client = createDatabaseClient();
5787
+ const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
5788
+ headers,
5789
+ params: {
5790
+ path: { databaseName: name }
5791
+ }
5792
+ });
5793
+ if (error2) throw mapApiError(response.status, error2);
5794
+ if (!data.type) return data.connection ?? null;
5795
+ return await fetchConsoleConnectionDetails(name, data.type, data.connection, headers);
5796
+ }
5797
+ __name(loadDatabaseConnectionDetails, "loadDatabaseConnectionDetails");
5684
5798
  function createDatabaseCommand() {
5685
5799
  const dbCmd = new Command7("database").alias("db").description("Manage databases");
5686
5800
  dbCmd.command("list").description("List databases").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading databases..." }, async (ctx, options) => {
@@ -5810,20 +5924,13 @@ function createDatabaseCommand() {
5810
5924
  printDatabaseDetail(data);
5811
5925
  }));
5812
5926
  dbCmd.command("connection <name>").description("Show database connection details").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading connection details..." }, async (ctx, name, options) => {
5813
- const client = createDatabaseClient();
5814
- const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
5815
- headers: ctx.auth,
5816
- params: {
5817
- path: { databaseName: name }
5818
- }
5819
- });
5820
- if (error2) throw mapApiError(response.status, error2);
5927
+ const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
5821
5928
  ctx.spinner.stop();
5822
5929
  if (options.output === "json") {
5823
- outputJson(data.connection ?? null);
5930
+ outputJson(connection);
5824
5931
  return;
5825
5932
  }
5826
- printConnectionDetail(data.connection);
5933
+ printConnectionDetail(connection);
5827
5934
  }));
5828
5935
  dbCmd.command("update <name>").description("Update database resources").option("--cpu <cpu>", "CPU cores per replica").option("--memory <memory>", "Memory in GB per replica").option("--storage <storage>", "Storage in GB per replica").option("--replicas <replicas>", "Replica count").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({
5829
5936
  spinnerText: "Updating database..."
@@ -6060,7 +6167,7 @@ function createDatabaseCommand() {
6060
6167
  }
6061
6168
  ctx.spinner.succeed(`Restore requested from backup "${options.from}"`);
6062
6169
  }));
6063
- dbCmd.command("enable-public <name>").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
6170
+ dbCmd.command("enable-public <name>").alias("expose").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
6064
6171
  const client = createDatabaseClient();
6065
6172
  const { error: error2, response } = await client.POST("/databases/{databaseName}/enable-public", {
6066
6173
  headers: ctx.auth,
@@ -6069,20 +6176,16 @@ function createDatabaseCommand() {
6069
6176
  }
6070
6177
  });
6071
6178
  if (error2) throw mapApiError(response.status, error2);
6179
+ const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
6072
6180
  if (options.output === "json") {
6073
6181
  ctx.spinner.stop();
6074
- outputJson({
6075
- success: true,
6076
- action: "enable-public",
6077
- resource: "database",
6078
- name,
6079
- status: "enabled"
6080
- });
6182
+ outputJson(buildPublicAccessResult("enable-public", name, connection));
6081
6183
  return;
6082
6184
  }
6083
6185
  ctx.spinner.succeed(`Public access enabled for "${name}"`);
6186
+ printConnectionDetail(connection);
6084
6187
  }));
6085
- dbCmd.command("disable-public <name>").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
6188
+ dbCmd.command("disable-public <name>").alias("unexpose").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
6086
6189
  const client = createDatabaseClient();
6087
6190
  const { error: error2, response } = await client.POST("/databases/{databaseName}/disable-public", {
6088
6191
  headers: ctx.auth,
@@ -6093,13 +6196,7 @@ function createDatabaseCommand() {
6093
6196
  if (error2) throw mapApiError(response.status, error2);
6094
6197
  if (options.output === "json") {
6095
6198
  ctx.spinner.stop();
6096
- outputJson({
6097
- success: true,
6098
- action: "disable-public",
6099
- resource: "database",
6100
- name,
6101
- status: "disabled"
6102
- });
6199
+ outputJson(buildPublicAccessResult("disable-public", name));
6103
6200
  return;
6104
6201
  }
6105
6202
  ctx.spinner.succeed(`Public access disabled for "${name}"`);
@@ -6185,6 +6282,22 @@ page=${data.data.metadata.page} total=${data.data.metadata.total} hasMore=${Stri
6185
6282
  }
6186
6283
  outputTable(rows);
6187
6284
  }));
6285
+ dbCmd.command("* [args...]", { hidden: true }).option("-o, --output <format>", "Output format (json|table)", "json").allowUnknownOption().action(async (args, options) => {
6286
+ const [name, operation, ...rest] = args;
6287
+ const aliases = {
6288
+ connection: "connection",
6289
+ connect: "connection",
6290
+ "enable-public": "enable-public",
6291
+ expose: "expose",
6292
+ "disable-public": "disable-public",
6293
+ unexpose: "unexpose"
6294
+ };
6295
+ const command = operation ? aliases[operation] : void 0;
6296
+ if (!name || !command) {
6297
+ throw new Error('Unknown database command. Use "sealos-cli database --help" to list supported commands.');
6298
+ }
6299
+ await dbCmd.parseAsync([command, name, ...rest, "--output", options.output], { from: "user" });
6300
+ });
6188
6301
  return dbCmd;
6189
6302
  }
6190
6303
  __name(createDatabaseCommand, "createDatabaseCommand");
@@ -6231,17 +6344,15 @@ async function resolveYaml(options, spinner2) {
6231
6344
  }
6232
6345
  __name(resolveYaml, "resolveYaml");
6233
6346
  function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin.isTTY) {
6234
- const isRaw = !!(options.file || options.yaml || !stdinIsTTY);
6235
- if (template && isRaw) {
6236
- throw new Error("Cannot specify both a template name and --file/--yaml/stdin. Use one or the other.");
6347
+ const hasExplicitRawInput = !!(options.file || options.yaml);
6348
+ const isRaw = hasExplicitRawInput || !template && !stdinIsTTY;
6349
+ if (template && hasExplicitRawInput) {
6350
+ throw new Error("Cannot specify both a template name and --file/--yaml. Use one or the other.");
6237
6351
  }
6238
6352
  if (!template && !isRaw) {
6239
6353
  throw new Error("Provide a template name or use --file/--yaml/stdin to supply raw YAML.");
6240
6354
  }
6241
6355
  if (template) {
6242
- if (!options.name) {
6243
- throw new Error("--name is required when deploying from the template catalog.");
6244
- }
6245
6356
  if (options.dryRun) {
6246
6357
  throw new Error("--dry-run is only supported for raw template deploys (--file, --yaml, or stdin).");
6247
6358
  }
@@ -6252,7 +6363,7 @@ function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin
6252
6363
  __name(resolveTemplateDeployMode, "resolveTemplateDeployMode");
6253
6364
  function buildCatalogTemplateDeployBody(template, options) {
6254
6365
  const body = {
6255
- name: options.name,
6366
+ name: options.name ?? template,
6256
6367
  template
6257
6368
  };
6258
6369
  if (options.set.length > 0) {
@@ -6462,9 +6573,10 @@ function createTemplateCommand() {
6462
6573
  }
6463
6574
  ctx.spinner.succeed(`Instance "${instance}" deleted`);
6464
6575
  }));
6465
- tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (required when deploying from catalog)").option("--file <path>", "Path to template YAML file").option("--yaml <yaml>", "Template YAML string").option("--set <KEY=VALUE...>", "Set template arguments", (val, prev) => [...prev, val], []).option("--dry-run", "Validate raw template YAML without creating resources").option("-o, --output <format>", "Output format (json|table)", "json").addHelpText("after", `
6576
+ tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (defaults to the catalog template name)").option("--file <path>", "Path to template YAML file").option("--yaml <yaml>", "Template YAML string").option("--set <KEY=VALUE...>", "Set template arguments", (val, prev) => [...prev, val], []).option("--dry-run", "Validate raw template YAML without creating resources").option("-o, --output <format>", "Output format (json|table)", "json").addHelpText("after", `
6466
6577
  Examples:
6467
6578
  Catalog:
6579
+ sealos-cli template deploy rybbit
6468
6580
  sealos-cli template deploy perplexica --name my-app --set OPENAI_API_KEY=xxx
6469
6581
 
6470
6582
  Raw:
@@ -6474,8 +6586,12 @@ kind: Template
6474
6586
  ...'
6475
6587
  cat template.yaml | sealos-cli template deploy --dry-run
6476
6588
  `).action(async (template, options) => {
6477
- const mode = resolveTemplateDeployMode(template, options);
6478
- await deployTemplate(template, options, mode);
6589
+ try {
6590
+ const mode = resolveTemplateDeployMode(template, options);
6591
+ await deployTemplate(template, options, mode);
6592
+ } catch (error2) {
6593
+ handleError(error2);
6594
+ }
6479
6595
  });
6480
6596
  return tplCmd;
6481
6597
  }
@@ -6484,7 +6600,7 @@ __name(createTemplateCommand, "createTemplateCommand");
6484
6600
  // package.json
6485
6601
  var package_default = {
6486
6602
  name: "sealos-cli",
6487
- version: "1.1.2",
6603
+ version: "1.1.3",
6488
6604
  description: "Official CLI tool for Sealos Cloud - Manage auth, workspaces, devboxes, databases, and templates",
6489
6605
  types: "dist/main.d.ts",
6490
6606
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sealos-cli",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Official CLI tool for Sealos Cloud - Manage auth, workspaces, devboxes, databases, and templates",
5
5
  "types": "dist/main.d.ts",
6
6
  "type": "module",