@pmate/cli 0.24.26 → 0.24.28

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/index.d.ts CHANGED
@@ -913,6 +913,7 @@ type ServiceCommandArgs = {
913
913
  action: "deploy" | "stop";
914
914
  namespace: string;
915
915
  name: string;
916
+ env?: string;
916
917
  baseUrl?: string;
917
918
  json: boolean;
918
919
  } | {
@@ -920,6 +921,7 @@ type ServiceCommandArgs = {
920
921
  action: "init";
921
922
  namespace: string;
922
923
  name: string;
924
+ env: string;
923
925
  cwd?: string;
924
926
  baseUrl?: string;
925
927
  json: boolean;
@@ -943,6 +945,36 @@ type ServiceCommandArgs = {
943
945
  includeSecretValue: boolean;
944
946
  baseUrl?: string;
945
947
  json: boolean;
948
+ } | {
949
+ type: Command.Service;
950
+ action: "service-env-list";
951
+ appId: string;
952
+ baseUrl?: string;
953
+ json: boolean;
954
+ } | {
955
+ type: Command.Service;
956
+ action: "service-env-get";
957
+ appId: string;
958
+ envName: string;
959
+ baseUrl?: string;
960
+ json: boolean;
961
+ } | {
962
+ type: Command.Service;
963
+ action: "service-env-add";
964
+ appId: string;
965
+ envName: string;
966
+ baseUrl?: string;
967
+ json: boolean;
968
+ } | {
969
+ type: Command.Service;
970
+ action: "service-env-expose";
971
+ appId: string;
972
+ envName: string;
973
+ exposeType?: "https" | "websocket";
974
+ off: boolean;
975
+ domain?: string;
976
+ baseUrl?: string;
977
+ json: boolean;
946
978
  } | {
947
979
  type: Command.Service;
948
980
  action: "env-get";
package/dist/index.js CHANGED
@@ -18212,6 +18212,20 @@ var ServiceRegistryClient = class {
18212
18212
  }
18213
18213
  );
18214
18214
  }
18215
+ async getServiceEnv(serviceId, envName) {
18216
+ const payload = await this.request(
18217
+ "GET",
18218
+ `/services/by-id/${encodeURIComponent(serviceId)}/envs/${encodeURIComponent(envName)}`
18219
+ );
18220
+ return payload.item;
18221
+ }
18222
+ async appendDeployHistory(serviceId, input) {
18223
+ return this.requestWithBody(
18224
+ "POST",
18225
+ `/services/by-id/${encodeURIComponent(serviceId)}/deploy-history`,
18226
+ input
18227
+ );
18228
+ }
18215
18229
  async pullEnv(serviceId, options) {
18216
18230
  const pathname = `/services/by-id/${encodeURIComponent(serviceId)}/env/pull`;
18217
18231
  const response = await fetch(`${this.resolveBaseUrl()}${pathname}`, {
@@ -18327,6 +18341,12 @@ var ServiceRuntimeRunner = class {
18327
18341
  }
18328
18342
  async deploy(service, options = {}) {
18329
18343
  switch (this.getType(service)) {
18344
+ case "node-api":
18345
+ await this.deployNode(service, options);
18346
+ return;
18347
+ case "node-job":
18348
+ await this.deployScriptManaged(service);
18349
+ return;
18330
18350
  case "vite":
18331
18351
  await this.deployVite(service, options);
18332
18352
  return;
@@ -18334,14 +18354,14 @@ var ServiceRuntimeRunner = class {
18334
18354
  await this.deployStatic(service, options);
18335
18355
  return;
18336
18356
  case "node":
18337
- await this.deployNode(service);
18357
+ await this.deployNode(service, options);
18338
18358
  return;
18339
18359
  case "rust":
18340
18360
  case "python":
18341
18361
  await this.deployScriptManaged(service);
18342
18362
  return;
18343
18363
  case "fc":
18344
- await this.deployFc(service);
18364
+ await this.deployFc(service, options);
18345
18365
  return;
18346
18366
  case "ios":
18347
18367
  case "android":
@@ -18354,6 +18374,7 @@ var ServiceRuntimeRunner = class {
18354
18374
  }
18355
18375
  async stop(service) {
18356
18376
  switch (this.getType(service)) {
18377
+ case "node-job":
18357
18378
  case "rust":
18358
18379
  case "python":
18359
18380
  await this.stopScriptManaged(service);
@@ -18376,6 +18397,12 @@ var ServiceRuntimeRunner = class {
18376
18397
  case "static":
18377
18398
  await this.initStaticLike(service);
18378
18399
  return;
18400
+ case "node-api":
18401
+ await this.initServerApp(service, options, { ensurePackageJson: true });
18402
+ return;
18403
+ case "node-job":
18404
+ await this.initServerApp(service, options, { ensurePackageJson: false });
18405
+ return;
18379
18406
  case "node":
18380
18407
  await this.initServerApp(service, options, { ensurePackageJson: true });
18381
18408
  return;
@@ -18588,7 +18615,7 @@ var ServiceRuntimeRunner = class {
18588
18615
  }
18589
18616
  await AliyunService.uploadDirectory(srcDir, bucketName);
18590
18617
  }
18591
- async deployFc(service) {
18618
+ async deployFc(service, options = {}) {
18592
18619
  const fc = this.getFc(service);
18593
18620
  this.validateFcConfig(service, fc);
18594
18621
  const repoRoot = this.resolveRepoRoot(service);
@@ -18606,7 +18633,7 @@ var ServiceRuntimeRunner = class {
18606
18633
  await this.runCommand("pnpm", ["--filter", pkgName, "build"], repoRoot);
18607
18634
  const registry = new ServiceRegistryClient();
18608
18635
  const appId = `${service.namespace}:${service.name}`;
18609
- const stage = fc.deployStage ?? "prod";
18636
+ const stage = this.envNameToStage(options.envName ?? fc.deployStage ?? "prod");
18610
18637
  const requiredEnv = await this.syncFcRequiredEnv(service, registry, stage);
18611
18638
  const resolved = await registry.resolveEnv(appId, {
18612
18639
  stage,
@@ -18704,7 +18731,7 @@ var ServiceRuntimeRunner = class {
18704
18731
  url: this.buildFcUrl(fc)
18705
18732
  });
18706
18733
  }
18707
- async deployNode(service) {
18734
+ async deployNode(service, options = {}) {
18708
18735
  const network = this.getNetwork(service);
18709
18736
  const server = network.server?.trim();
18710
18737
  const repository = network.repository?.trim();
@@ -18731,7 +18758,7 @@ var ServiceRuntimeRunner = class {
18731
18758
  `pkg="${appDir}/package.json"`,
18732
18759
  `if [ -f "$pkg" ] && node -e 'const fs=require("node:fs"); const p=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); process.exit(p?.scripts?.build ? 0 : 1);' "$pkg"; then (cd "${appDir}" && pnpm run build); fi`
18733
18760
  ].join("; ");
18734
- const envSyncCommand = await this.buildNodeEnvSyncCommand(service.id, appDir);
18761
+ const envSyncCommand = await this.buildNodeEnvSyncCommand(service.id, appDir, options.envName);
18735
18762
  const command = [
18736
18763
  `cd "$HOME"`,
18737
18764
  `[ -d "${repoDir}/.git" ] || git clone "${gitUrl}" "${repoDir}"`,
@@ -18749,13 +18776,13 @@ var ServiceRuntimeRunner = class {
18749
18776
  ].join(" && ");
18750
18777
  await this.runRemoteCommand(server, command);
18751
18778
  }
18752
- async buildNodeEnvSyncCommand(serviceId, appDir) {
18779
+ async buildNodeEnvSyncCommand(serviceId, appDir, envName = "prod") {
18753
18780
  if (!this.envProvider) {
18754
18781
  return void 0;
18755
18782
  }
18756
18783
  let pulled;
18757
18784
  try {
18758
- pulled = await this.envProvider(serviceId, { stage: "prod", format: "dotenv" });
18785
+ pulled = await this.envProvider(serviceId, { stage: this.envNameToStage(envName), format: "dotenv" });
18759
18786
  } catch (error) {
18760
18787
  if (error instanceof ServiceEnvNotFoundError) {
18761
18788
  ui.warn(`No env found for ${serviceId}; skipping .env.local sync.`);
@@ -18977,6 +19004,12 @@ var ServiceRuntimeRunner = class {
18977
19004
  }
18978
19005
  return payload.data;
18979
19006
  }
19007
+ envNameToStage(envName) {
19008
+ if (envName === "dev" || envName === "preview" || envName === "prod") {
19009
+ return envName;
19010
+ }
19011
+ return "preview";
19012
+ }
18980
19013
  renderPage(page, options = {}) {
18981
19014
  ui.info("Page", {
18982
19015
  page: page.page,
@@ -19758,17 +19791,32 @@ var ServiceCommandHandler = class {
19758
19791
  }
19759
19792
  case "deploy": {
19760
19793
  const record = await registry.getService(args.namespace, args.name);
19761
- await runtime.deploy(record);
19794
+ const service = await this.materializeServiceEnv(registry, record, args.env);
19795
+ try {
19796
+ await runtime.deploy(service, { envName: args.env });
19797
+ await this.appendDeployHistory(registry, record.id, args.env, "success");
19798
+ } catch (error) {
19799
+ await this.appendDeployHistory(
19800
+ registry,
19801
+ record.id,
19802
+ args.env,
19803
+ "failed",
19804
+ error instanceof Error ? error.message : String(error)
19805
+ );
19806
+ throw error;
19807
+ }
19762
19808
  return;
19763
19809
  }
19764
19810
  case "stop": {
19765
19811
  const record = await registry.getService(args.namespace, args.name);
19766
- await runtime.stop(record);
19812
+ const service = args.env ? await this.materializeServiceEnv(registry, record, args.env) : record;
19813
+ await runtime.stop(service);
19767
19814
  return;
19768
19815
  }
19769
19816
  case "init": {
19770
19817
  const record = await registry.getService(args.namespace, args.name);
19771
- await runtime.init(record, { cwd: args.cwd });
19818
+ const service = await this.materializeServiceEnv(registry, record, args.env);
19819
+ await runtime.init(service, { cwd: args.cwd });
19772
19820
  return;
19773
19821
  }
19774
19822
  case "log": {
@@ -19901,7 +19949,183 @@ var ServiceCommandHandler = class {
19901
19949
  this.renderJson(payload, args.json);
19902
19950
  return;
19903
19951
  }
19952
+ case "service-env-list": {
19953
+ const payload = await this.request(
19954
+ baseUrl,
19955
+ "GET",
19956
+ this.buildServiceEnvBasePath(args.appId)
19957
+ );
19958
+ this.renderJson(payload, true);
19959
+ return;
19960
+ }
19961
+ case "service-env-get": {
19962
+ const payload = await this.request(
19963
+ baseUrl,
19964
+ "GET",
19965
+ `${this.buildServiceEnvBasePath(args.appId)}/${encodeURIComponent(args.envName)}`
19966
+ );
19967
+ this.renderJson(payload, true);
19968
+ return;
19969
+ }
19970
+ case "service-env-add": {
19971
+ const payload = await this.request(
19972
+ baseUrl,
19973
+ "PUT",
19974
+ `${this.buildServiceEnvBasePath(args.appId)}/${encodeURIComponent(args.envName)}`,
19975
+ {
19976
+ name: args.envName
19977
+ }
19978
+ );
19979
+ ui.success(`Updated service env ${args.envName} for ${args.appId}`);
19980
+ this.renderJson(payload, args.json);
19981
+ return;
19982
+ }
19983
+ case "service-env-expose": {
19984
+ const payload = await this.request(
19985
+ baseUrl,
19986
+ "POST",
19987
+ `${this.buildServiceEnvBasePath(args.appId)}/${encodeURIComponent(args.envName)}/expose`,
19988
+ {
19989
+ ...args.exposeType ? { type: args.exposeType } : {},
19990
+ ...args.domain ? { domain: args.domain } : {},
19991
+ ...args.off ? { off: true } : {}
19992
+ }
19993
+ );
19994
+ ui.success(
19995
+ args.off ? `Disabled network for ${args.appId} ${args.envName}` : `Updated network for ${args.appId} ${args.envName}`
19996
+ );
19997
+ this.renderJson(payload, args.json);
19998
+ return;
19999
+ }
20000
+ }
20001
+ }
20002
+ async materializeServiceEnv(registry, service, envName) {
20003
+ if (!envName || !this.isDefinitionStyleService(service)) {
20004
+ return service;
19904
20005
  }
20006
+ const env = await registry.getServiceEnv(service.id, envName);
20007
+ return this.buildRuntimeServiceRecord(service, env);
20008
+ }
20009
+ isDefinitionStyleService(service) {
20010
+ return "repository" in service || "type" in service && (service.type === "node-api" || service.type === "node-job") || !("site" in service) && !("network" in service) && !("fc" in service) && !("runtimeType" in service);
20011
+ }
20012
+ buildRuntimeServiceRecord(service, env) {
20013
+ if (!("type" in service)) {
20014
+ return service;
20015
+ }
20016
+ const repository = service.repository?.trim();
20017
+ const dir = service.dir?.trim();
20018
+ const runtime = env.runtime;
20019
+ if (!runtime) {
20020
+ throw new Error(`Missing runtime for ${service.id} env ${env.name}`);
20021
+ }
20022
+ if (!repository) {
20023
+ throw new Error(`Missing service.repository for ${service.id}`);
20024
+ }
20025
+ if (!dir) {
20026
+ throw new Error(`Missing service.dir for ${service.id}`);
20027
+ }
20028
+ if (runtime.type === "ali-oss") {
20029
+ const domainParts = splitPrimaryDomain(env.network?.domain);
20030
+ return {
20031
+ id: service.id,
20032
+ namespace: service.namespace,
20033
+ name: service.name,
20034
+ type: service.type === "static" ? "static" : "vite",
20035
+ site: {
20036
+ exposeType: "static-site",
20037
+ repository,
20038
+ dir,
20039
+ bucket: requireString(runtime.bucket, `runtime.bucket for ${service.id} ${env.name}`),
20040
+ domain: domainParts.domain,
20041
+ ...domainParts.subdomain ? { subdomain: domainParts.subdomain } : {}
20042
+ }
20043
+ };
20044
+ }
20045
+ if (runtime.type === "ssh-pm2") {
20046
+ return {
20047
+ id: service.id,
20048
+ namespace: service.namespace,
20049
+ name: runtime.appName?.trim() || service.name,
20050
+ type: service.type === "node-api" ? "node-api" : "node",
20051
+ network: {
20052
+ exposeType: env.network?.type === "websocket" ? "websocket" : env.network ? "rest" : "internal",
20053
+ repository,
20054
+ dir,
20055
+ server: requireString(runtime.server, `runtime.server for ${service.id} ${env.name}`),
20056
+ ...runtime.port !== void 0 ? { port: runtime.port } : {},
20057
+ ...splitPrimaryDomain(env.network?.domain)
20058
+ }
20059
+ };
20060
+ }
20061
+ if (runtime.type === "ssh-script") {
20062
+ return {
20063
+ id: service.id,
20064
+ namespace: service.namespace,
20065
+ name: service.name,
20066
+ type: service.type === "node-job" ? "node-job" : service.type === "rust" ? "rust" : "python",
20067
+ network: {
20068
+ exposeType: env.network?.type === "websocket" ? "websocket" : env.network ? "rest" : "internal",
20069
+ repository,
20070
+ dir: runtime.cwd?.trim() || dir,
20071
+ server: requireString(runtime.server, `runtime.server for ${service.id} ${env.name}`),
20072
+ ...runtime.port !== void 0 ? { port: runtime.port } : {},
20073
+ ...splitPrimaryDomain(env.network?.domain)
20074
+ },
20075
+ runner: {
20076
+ script: requireString(runtime.command, `runtime.command for ${service.id} ${env.name}`)
20077
+ }
20078
+ };
20079
+ }
20080
+ if (runtime.type === "fc") {
20081
+ const domainParts = splitPrimaryDomain(env.network?.domain);
20082
+ return {
20083
+ id: service.id,
20084
+ namespace: service.namespace,
20085
+ name: service.name,
20086
+ type: "fc",
20087
+ fc: {
20088
+ provider: runtime.provider ?? "aliyun",
20089
+ region: requireString(runtime.region, `runtime.region for ${service.id} ${env.name}`),
20090
+ repository,
20091
+ dir,
20092
+ functionName: requireString(runtime.functionName, `runtime.functionName for ${service.id} ${env.name}`),
20093
+ ...runtime.configFile ? { configFile: runtime.configFile } : {},
20094
+ ...runtime.qualifier ? { qualifier: runtime.qualifier } : {},
20095
+ ...domainParts.domain ? { domain: domainParts.domain } : {},
20096
+ ...domainParts.subdomain ? { subdomain: domainParts.subdomain } : {},
20097
+ deployStage: env.name === "prod" || env.name === "preview" || env.name === "dev" ? env.name : "preview"
20098
+ }
20099
+ };
20100
+ }
20101
+ throw new Error(`Unsupported runtime ${runtime.type} for ${service.id} env ${env.name}`);
20102
+ }
20103
+ async appendDeployHistory(registry, serviceId, environment, status, message) {
20104
+ let lastError;
20105
+ for (let attempt = 1; attempt <= 5; attempt += 1) {
20106
+ try {
20107
+ await registry.appendDeployHistory(serviceId, {
20108
+ environment,
20109
+ status,
20110
+ ...message ? { message } : {}
20111
+ });
20112
+ return;
20113
+ } catch (error2) {
20114
+ lastError = error2;
20115
+ if (attempt < 5 && shouldRetryDeployHistoryAppend(error2)) {
20116
+ await sleep3(attempt * 1e3);
20117
+ continue;
20118
+ }
20119
+ break;
20120
+ }
20121
+ }
20122
+ const error = lastError;
20123
+ ui.warn("Failed to append deploy history", {
20124
+ serviceId,
20125
+ environment,
20126
+ status,
20127
+ message: error instanceof Error ? error.message : String(error)
20128
+ });
19905
20129
  }
19906
20130
  resolveBaseUrl(baseUrl) {
19907
20131
  return (baseUrl || process.env.PMATE_APPS_API_BASE_URL || "https://apps-api.pmate.chat").replace(/\/+$/, "");
@@ -19943,6 +20167,9 @@ var ServiceCommandHandler = class {
19943
20167
  buildEnvBasePath(appId) {
19944
20168
  return `/services/by-id/${encodeURIComponent(appId)}/env`;
19945
20169
  }
20170
+ buildServiceEnvBasePath(appId) {
20171
+ return `/services/by-id/${encodeURIComponent(appId)}/envs`;
20172
+ }
19946
20173
  buildEnvPath(appId, query) {
19947
20174
  const params = new URLSearchParams();
19948
20175
  if (query.scope) {
@@ -20308,6 +20535,33 @@ var ServiceCommandHandler = class {
20308
20535
  ui.plain(JSON.stringify(value, null, 2));
20309
20536
  }
20310
20537
  };
20538
+ function requireString(value, field) {
20539
+ if (typeof value !== "string" || !value.trim()) {
20540
+ throw new Error(`Missing ${field}`);
20541
+ }
20542
+ return value.trim();
20543
+ }
20544
+ function splitPrimaryDomain(host) {
20545
+ const normalized = host?.trim();
20546
+ if (!normalized) {
20547
+ return { domain: "pmate.chat" };
20548
+ }
20549
+ const parts = normalized.split(".").filter(Boolean);
20550
+ if (parts.length <= 2) {
20551
+ return { domain: normalized };
20552
+ }
20553
+ return {
20554
+ subdomain: parts.slice(0, -2).join("."),
20555
+ domain: parts.slice(-2).join(".")
20556
+ };
20557
+ }
20558
+ function shouldRetryDeployHistoryAppend(error) {
20559
+ const message = error instanceof Error ? error.message : String(error);
20560
+ return message.includes("status 502") || message.includes("status 503") || message.includes("status 504") || message.includes("fetch failed") || message.includes("ECONNRESET") || message.includes("ETIMEDOUT");
20561
+ }
20562
+ function sleep3(ms) {
20563
+ return new Promise((resolve) => setTimeout(resolve, ms));
20564
+ }
20311
20565
 
20312
20566
  // src/commands/VercelCommandHandler.ts
20313
20567
  var import_node_child_process12 = require("child_process");
@@ -22556,10 +22810,14 @@ init_namespacedRef();
22556
22810
  function parseServiceArgs(tokens) {
22557
22811
  const rest = [...tokens];
22558
22812
  const rawAction = rest.shift();
22559
- if (rawAction && looksLikeNamespacedRef(rawAction) && rest[0] === "env") {
22813
+ if (rawAction && looksLikeNamespacedRef(rawAction) && rest[0] === "env-vars") {
22560
22814
  rest.shift();
22561
22815
  return parseServiceEnvArgs(rawAction, rest);
22562
22816
  }
22817
+ if (rawAction && looksLikeNamespacedRef(rawAction) && rest[0] === "env") {
22818
+ rest.shift();
22819
+ return parseServiceEnvDefinitionArgs(rawAction, rest);
22820
+ }
22563
22821
  const action = rawAction === "view" ? "view" : rawAction;
22564
22822
  if (!action) {
22565
22823
  throw new Error("Missing service action. Use: service list|get|view|create|update|rename|delete|deploy|stop|init|log");
@@ -22629,6 +22887,7 @@ function parseServiceArgs(tokens) {
22629
22887
  let history = false;
22630
22888
  let search;
22631
22889
  let follow = false;
22890
+ let env;
22632
22891
  while (rest.length > 0) {
22633
22892
  const token = rest.shift();
22634
22893
  switch (token) {
@@ -22641,6 +22900,12 @@ function parseServiceArgs(tokens) {
22641
22900
  }
22642
22901
  cwd = requireValue6(rest, token);
22643
22902
  break;
22903
+ case "--env":
22904
+ if (action !== "deploy" && action !== "init" && action !== "stop") {
22905
+ throw new Error(`Unknown service ${action} option: ${token}`);
22906
+ }
22907
+ env = requireValue6(rest, token);
22908
+ break;
22644
22909
  case "--page":
22645
22910
  page = Number.parseInt(requireValue6(rest, token), 10);
22646
22911
  break;
@@ -22668,10 +22933,16 @@ function parseServiceArgs(tokens) {
22668
22933
  return { type: "service" /* Service */, action, namespace, name, baseUrl, json, page, history, search, follow };
22669
22934
  }
22670
22935
  if (action === "deploy" || action === "stop") {
22671
- return { type: "service" /* Service */, action, namespace, name, baseUrl, json };
22936
+ if (action === "deploy" && !env) {
22937
+ throw new Error("Missing required option --env for service deploy");
22938
+ }
22939
+ return { type: "service" /* Service */, action, namespace, name, env, baseUrl, json };
22672
22940
  }
22673
22941
  if (action === "init") {
22674
- return { type: "service" /* Service */, action, namespace, name, cwd, baseUrl, json };
22942
+ if (!env) {
22943
+ throw new Error("Missing required option --env for service init");
22944
+ }
22945
+ return { type: "service" /* Service */, action, namespace, name, env, cwd, baseUrl, json };
22675
22946
  }
22676
22947
  return { type: "service" /* Service */, action, namespace, name, baseUrl, json };
22677
22948
  }
@@ -22839,6 +23110,106 @@ function parseBareRenameId3(value, entityName) {
22839
23110
  function looksLikeNamespacedRef(value) {
22840
23111
  return value.includes(":") && !value.startsWith("-");
22841
23112
  }
23113
+ function parseServiceEnvDefinitionArgs(appId, tokens) {
23114
+ const rest = [...tokens];
23115
+ const action = rest.shift();
23116
+ if (!action) {
23117
+ throw new Error("Usage: service <ns:service> env list|get|add|expose");
23118
+ }
23119
+ let baseUrl;
23120
+ let json = false;
23121
+ if (action === "list") {
23122
+ while (rest.length > 0) {
23123
+ const token = rest.shift();
23124
+ switch (token) {
23125
+ case "--base-url":
23126
+ baseUrl = requireValue6(rest, token);
23127
+ break;
23128
+ case "--json":
23129
+ json = true;
23130
+ break;
23131
+ default:
23132
+ throw new Error(`Unknown service env list option: ${token}`);
23133
+ }
23134
+ }
23135
+ return { type: "service" /* Service */, action: "service-env-list", appId, baseUrl, json };
23136
+ }
23137
+ if (action === "get" || action === "add") {
23138
+ const envName = rest.shift();
23139
+ if (!envName || envName.startsWith("-")) {
23140
+ throw new Error(`Usage: service <ns:service> env ${action} <env> [--base-url <url>] [--json]`);
23141
+ }
23142
+ while (rest.length > 0) {
23143
+ const token = rest.shift();
23144
+ switch (token) {
23145
+ case "--base-url":
23146
+ baseUrl = requireValue6(rest, token);
23147
+ break;
23148
+ case "--json":
23149
+ json = true;
23150
+ break;
23151
+ default:
23152
+ throw new Error(`Unknown service env ${action} option: ${token}`);
23153
+ }
23154
+ }
23155
+ return {
23156
+ type: "service" /* Service */,
23157
+ action: action === "get" ? "service-env-get" : "service-env-add",
23158
+ appId,
23159
+ envName,
23160
+ baseUrl,
23161
+ json
23162
+ };
23163
+ }
23164
+ if (action === "expose") {
23165
+ const envName = rest.shift();
23166
+ if (!envName || envName.startsWith("-")) {
23167
+ throw new Error("Usage: service <ns:service> env expose <env> [--type https|websocket] [--domain <domain>] [--off]");
23168
+ }
23169
+ let exposeType;
23170
+ let domain;
23171
+ let off = false;
23172
+ while (rest.length > 0) {
23173
+ const token = rest.shift();
23174
+ switch (token) {
23175
+ case "--type": {
23176
+ const value = requireValue6(rest, token);
23177
+ if (value !== "https" && value !== "websocket") {
23178
+ throw new Error("--type must be https or websocket");
23179
+ }
23180
+ exposeType = value;
23181
+ break;
23182
+ }
23183
+ case "--domain":
23184
+ domain = requireValue6(rest, token);
23185
+ break;
23186
+ case "--off":
23187
+ off = true;
23188
+ break;
23189
+ case "--base-url":
23190
+ baseUrl = requireValue6(rest, token);
23191
+ break;
23192
+ case "--json":
23193
+ json = true;
23194
+ break;
23195
+ default:
23196
+ throw new Error(`Unknown service env expose option: ${token}`);
23197
+ }
23198
+ }
23199
+ return {
23200
+ type: "service" /* Service */,
23201
+ action: "service-env-expose",
23202
+ appId,
23203
+ envName,
23204
+ exposeType,
23205
+ domain,
23206
+ off,
23207
+ baseUrl,
23208
+ json
23209
+ };
23210
+ }
23211
+ throw new Error(`Unknown service env action: ${action}`);
23212
+ }
22842
23213
  function parseServiceEnvArgs(appId, tokens) {
22843
23214
  const rest = [...tokens];
22844
23215
  const action = rest.shift();
@@ -22855,6 +23226,7 @@ function parseServiceEnvArgs(appId, tokens) {
22855
23226
  const token = rest.shift();
22856
23227
  switch (token) {
22857
23228
  case "--scope":
23229
+ case "--env":
22858
23230
  scope = requireValue6(rest, token);
22859
23231
  break;
22860
23232
  case "--include-secret-meta":
@@ -22886,6 +23258,7 @@ function parseServiceEnvArgs(appId, tokens) {
22886
23258
  const token = rest.shift();
22887
23259
  switch (token) {
22888
23260
  case "--scope":
23261
+ case "--env":
22889
23262
  scope = requireValue6(rest, token);
22890
23263
  break;
22891
23264
  case "--include-secret-value":
@@ -22901,9 +23274,7 @@ function parseServiceEnvArgs(appId, tokens) {
22901
23274
  throw new Error(`Unknown service env get option: ${token}`);
22902
23275
  }
22903
23276
  }
22904
- if (!scope) {
22905
- throw new Error("Usage: service <ns:app> env get <key> --scope <scope> [--include-secret-value]");
22906
- }
23277
+ scope = scope ?? "all";
22907
23278
  return { type: "service" /* Service */, action: "env-get", appId, key, scope, includeSecretValue, baseUrl, json };
22908
23279
  }
22909
23280
  if (action === "set") {
@@ -22922,6 +23293,7 @@ function parseServiceEnvArgs(appId, tokens) {
22922
23293
  const token = rest.shift();
22923
23294
  switch (token) {
22924
23295
  case "--scope":
23296
+ case "--env":
22925
23297
  scope = requireValue6(rest, token);
22926
23298
  break;
22927
23299
  case "--secret":
@@ -22940,9 +23312,7 @@ function parseServiceEnvArgs(appId, tokens) {
22940
23312
  throw new Error(`Unknown service env set option: ${token}`);
22941
23313
  }
22942
23314
  }
22943
- if (!scope) {
22944
- throw new Error("Usage: service <ns:app> env set <key> [value] --scope <scope> [--secret] [--prompt]");
22945
- }
23315
+ scope = scope ?? "all";
22946
23316
  if (!value && !secret && !prompt) {
22947
23317
  throw new Error("Missing env value. Pass a value or use --prompt.");
22948
23318
  }
@@ -22958,6 +23328,7 @@ function parseServiceEnvArgs(appId, tokens) {
22958
23328
  const token = rest.shift();
22959
23329
  switch (token) {
22960
23330
  case "--scope":
23331
+ case "--env":
22961
23332
  scope = requireValue6(rest, token);
22962
23333
  break;
22963
23334
  case "--base-url":
@@ -22970,9 +23341,7 @@ function parseServiceEnvArgs(appId, tokens) {
22970
23341
  throw new Error(`Unknown service env unset option: ${token}`);
22971
23342
  }
22972
23343
  }
22973
- if (!scope) {
22974
- throw new Error("Usage: service <ns:app> env unset <key> --scope <scope>");
22975
- }
23344
+ scope = scope ?? "all";
22976
23345
  return { type: "service" /* Service */, action: "env-unset", appId, key, scope, baseUrl, json };
22977
23346
  }
22978
23347
  if (action === "resolve") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.24.26",
3
+ "version": "0.24.28",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {