@pmate/cli 0.24.30 → 0.24.32

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
@@ -936,6 +936,7 @@ type ServiceCommandArgs = {
936
936
  history: boolean;
937
937
  search?: string;
938
938
  follow: boolean;
939
+ env?: string;
939
940
  } | {
940
941
  type: Command.Service;
941
942
  action: "deploy-logs" | "deploy-history";
package/dist/index.js CHANGED
@@ -18362,7 +18362,7 @@ var ServiceRuntimeRunner = class {
18362
18362
  await this.deployNode(service, options);
18363
18363
  return;
18364
18364
  case "node-job":
18365
- await this.deployScriptManaged(service);
18365
+ await this.deployScriptManaged(service, options);
18366
18366
  return;
18367
18367
  case "vite":
18368
18368
  await this.deployVite(service, options);
@@ -18375,7 +18375,7 @@ var ServiceRuntimeRunner = class {
18375
18375
  return;
18376
18376
  case "rust":
18377
18377
  case "python":
18378
- await this.deployScriptManaged(service);
18378
+ await this.deployScriptManaged(service, options);
18379
18379
  return;
18380
18380
  case "fc":
18381
18381
  await this.deployFc(service, options);
@@ -18389,12 +18389,12 @@ var ServiceRuntimeRunner = class {
18389
18389
  throw new Error(`Unsupported service type for deploy: ${this.getType(service)}`);
18390
18390
  }
18391
18391
  }
18392
- async stop(service) {
18392
+ async stop(service, options = {}) {
18393
18393
  switch (this.getType(service)) {
18394
18394
  case "node-job":
18395
18395
  case "rust":
18396
18396
  case "python":
18397
- await this.stopScriptManaged(service);
18397
+ await this.stopScriptManaged(service, options);
18398
18398
  return;
18399
18399
  case "node":
18400
18400
  throw new Error("service stop is only supported for script-managed python/rust services for now");
@@ -18820,7 +18820,7 @@ var ServiceRuntimeRunner = class {
18820
18820
  `echo "[pmate] Synced env to $env_local"`
18821
18821
  ].join(" && ");
18822
18822
  }
18823
- async deployScriptManaged(service) {
18823
+ async deployScriptManaged(service, options = {}) {
18824
18824
  const network = this.getNetwork(service);
18825
18825
  const runner = this.getRunner(service);
18826
18826
  const server = network.server?.trim();
@@ -18839,6 +18839,8 @@ var ServiceRuntimeRunner = class {
18839
18839
  const repoUrl = this.getRepoUrl(repository);
18840
18840
  const gitUrl = this.withToken(repoUrl);
18841
18841
  const scriptPath = script.startsWith("/") || script.startsWith("./") ? script : `./${script}`;
18842
+ const envName = options.envName ?? "prod";
18843
+ const envSyncCommand = await this.buildScriptEnvSyncCommand(service.id, envName);
18842
18844
  const command = [
18843
18845
  `cd "$HOME"`,
18844
18846
  `[ -d "${repoDir}/.git" ] || git clone "${gitUrl}" "${repoDir}"`,
@@ -18847,11 +18849,12 @@ var ServiceRuntimeRunner = class {
18847
18849
  `if [ -f ~/.bashrc ]; then . ~/.bashrc; fi`,
18848
18850
  `if [ -n "$(git status --porcelain)" ]; then git reset --hard HEAD; git clean -fd; fi`,
18849
18851
  `git pull`,
18850
- `"${scriptPath}" restart`
18852
+ ...envSyncCommand ? [envSyncCommand] : [],
18853
+ `"${scriptPath}" restart --env ${shellQuote2(envName)}`
18851
18854
  ].join(" && ");
18852
18855
  await this.runRemoteCommand(server, command);
18853
18856
  }
18854
- async stopScriptManaged(service) {
18857
+ async stopScriptManaged(service, options = {}) {
18855
18858
  const network = this.getNetwork(service);
18856
18859
  const runner = this.getRunner(service);
18857
18860
  const server = network.server?.trim();
@@ -18868,15 +18871,51 @@ var ServiceRuntimeRunner = class {
18868
18871
  }
18869
18872
  const repoDir = this.getRepoDirName(repository);
18870
18873
  const scriptPath = script.startsWith("/") || script.startsWith("./") ? script : `./${script}`;
18874
+ const envName = options.envName ?? "prod";
18875
+ const envSyncCommand = await this.buildScriptEnvSyncCommand(service.id, envName);
18871
18876
  const command = [
18872
18877
  `cd "$HOME"`,
18873
18878
  `cd "${repoDir}"`,
18874
18879
  `if [ -f ~/.profile ]; then . ~/.profile; fi`,
18875
18880
  `if [ -f ~/.bashrc ]; then . ~/.bashrc; fi`,
18876
- `"${scriptPath}" stop`
18881
+ ...envSyncCommand ? [envSyncCommand] : [],
18882
+ `"${scriptPath}" stop --env ${shellQuote2(envName)}`
18877
18883
  ].join(" && ");
18878
18884
  await this.runRemoteCommand(server, command);
18879
18885
  }
18886
+ async buildScriptEnvSyncCommand(serviceId, envName) {
18887
+ if (!this.envProvider) {
18888
+ return void 0;
18889
+ }
18890
+ let pulled;
18891
+ try {
18892
+ pulled = await this.envProvider(serviceId, { stage: this.envNameToStage(envName), format: "dotenv" });
18893
+ } catch (error) {
18894
+ if (error instanceof ServiceEnvNotFoundError) {
18895
+ ui.warn(`No env found for ${serviceId}; skipping PMate env file sync.`);
18896
+ return void 0;
18897
+ }
18898
+ throw error;
18899
+ }
18900
+ const serviceRef = parseServiceRef(serviceId);
18901
+ const envFile = `.pmate/services/${serviceRef.namespace}/${serviceRef.name}/${envName}.env`;
18902
+ const content = [
18903
+ `PMATE_SERVICE_ID=${serviceId}`,
18904
+ `PMATE_SERVICE_NAMESPACE=${serviceRef.namespace}`,
18905
+ `PMATE_SERVICE_NAME=${serviceRef.name}`,
18906
+ `PMATE_SERVICE_ENV=${envName}`,
18907
+ pulled?.content?.trimEnd() ?? "",
18908
+ ""
18909
+ ].join("\n");
18910
+ const encodedContent = Buffer.from(content, "utf8").toString("base64");
18911
+ return [
18912
+ `env_file="$HOME/${envFile}"`,
18913
+ `mkdir -p "$(dirname "$env_file")"`,
18914
+ `printf '%s' ${shellQuote2(encodedContent)} | base64 --decode > "$env_file"`,
18915
+ `chmod 600 "$env_file"`,
18916
+ `echo "[pmate] Synced env to $env_file"`
18917
+ ].join(" && ");
18918
+ }
18880
18919
  async initStaticLike(service) {
18881
18920
  const site = this.getSite(service);
18882
18921
  const bucketName = site.bucket?.trim();
@@ -19705,6 +19744,13 @@ var ServiceRuntimeRunner = class {
19705
19744
  function shellQuote2(value) {
19706
19745
  return `'${value.replace(/'/g, `'\\''`)}'`;
19707
19746
  }
19747
+ function parseServiceRef(serviceId) {
19748
+ const [namespace, name, extra] = serviceId.split(":");
19749
+ if (!namespace || !name || extra !== void 0) {
19750
+ throw new Error(`Invalid service id: ${serviceId}`);
19751
+ }
19752
+ return { namespace, name };
19753
+ }
19708
19754
 
19709
19755
  // src/commands/ServiceCommandHandler.ts
19710
19756
  init_namespacedRef();
@@ -19851,7 +19897,7 @@ var ServiceCommandHandler = class {
19851
19897
  case "stop": {
19852
19898
  const record = await registry.getService(args.namespace, args.name);
19853
19899
  const service = args.env ? await this.materializeServiceEnv(registry, record, args.env) : record;
19854
- await runtime.stop(service);
19900
+ await runtime.stop(service, { envName: args.env });
19855
19901
  return;
19856
19902
  }
19857
19903
  case "init": {
@@ -19862,11 +19908,13 @@ var ServiceCommandHandler = class {
19862
19908
  }
19863
19909
  case "log": {
19864
19910
  const record = await registry.getService(args.namespace, args.name);
19865
- await runtime.log(record, {
19911
+ const service = args.env ? await this.materializeServiceEnv(registry, record, args.env) : record;
19912
+ await runtime.log(service, {
19866
19913
  page: args.page,
19867
19914
  history: args.history,
19868
19915
  search: args.search,
19869
- follow: args.follow
19916
+ follow: args.follow,
19917
+ envName: args.env
19870
19918
  });
19871
19919
  return;
19872
19920
  }
@@ -20506,50 +20554,48 @@ var ServiceCommandHandler = class {
20506
20554
  const site = this.getStaticSiteConfig(service);
20507
20555
  const bucketName = site.bucket?.trim();
20508
20556
  const domainName = site.domain?.trim();
20509
- if (!bucketName) {
20510
- throw new Error(`Missing site.bucket for ${service.id}`);
20511
- }
20512
- if (!domainName) {
20513
- throw new Error(`Missing site.domain for ${service.id}`);
20514
- }
20515
- const subdomain = site.subdomain?.trim();
20516
- const rr = subdomain || "@";
20517
- const cdnDomain = subdomain ? `${subdomain}.${domainName}` : domainName;
20518
- const cname = await AliyunService.getCdnCname(cdnDomain);
20519
- if (cname) {
20520
- this.logDeletedRecords(
20521
- `Removed CNAME record for ${cdnDomain}`,
20522
- await AliyunService.deleteDomainRecords({
20523
- domainName,
20524
- rr,
20525
- type: "CNAME",
20526
- value: cname
20527
- })
20528
- );
20529
- } else {
20530
- ui.warn(`No CDN CNAME found for ${cdnDomain}; deleting matching CNAME records by host.`);
20531
- this.logDeletedRecords(
20532
- `Removed CNAME record for ${cdnDomain}`,
20533
- await AliyunService.deleteDomainRecords({
20534
- domainName,
20535
- rr,
20536
- type: "CNAME"
20537
- })
20538
- );
20557
+ if (domainName) {
20558
+ const subdomain = site.subdomain?.trim();
20559
+ const rr = subdomain || "@";
20560
+ const cdnDomain = subdomain ? `${subdomain}.${domainName}` : domainName;
20561
+ const cname = await AliyunService.getCdnCname(cdnDomain);
20562
+ if (cname) {
20563
+ this.logDeletedRecords(
20564
+ `Removed CNAME record for ${cdnDomain}`,
20565
+ await AliyunService.deleteDomainRecords({
20566
+ domainName,
20567
+ rr,
20568
+ type: "CNAME",
20569
+ value: cname
20570
+ })
20571
+ );
20572
+ } else {
20573
+ ui.warn(`No CDN CNAME found for ${cdnDomain}; deleting matching CNAME records by host.`);
20574
+ this.logDeletedRecords(
20575
+ `Removed CNAME record for ${cdnDomain}`,
20576
+ await AliyunService.deleteDomainRecords({
20577
+ domainName,
20578
+ rr,
20579
+ type: "CNAME"
20580
+ })
20581
+ );
20582
+ }
20583
+ if (!subdomain) {
20584
+ this.logDeletedRecords(
20585
+ `Removed CNAME record for www.${domainName}`,
20586
+ await AliyunService.deleteDomainRecords({
20587
+ domainName,
20588
+ rr: "www",
20589
+ type: "CNAME",
20590
+ value: domainName
20591
+ })
20592
+ );
20593
+ }
20594
+ await AliyunService.deleteCdnDomain(cdnDomain);
20539
20595
  }
20540
- if (!subdomain) {
20541
- this.logDeletedRecords(
20542
- `Removed CNAME record for www.${domainName}`,
20543
- await AliyunService.deleteDomainRecords({
20544
- domainName,
20545
- rr: "www",
20546
- type: "CNAME",
20547
- value: domainName
20548
- })
20549
- );
20596
+ if (bucketName) {
20597
+ await AliyunService.deleteBucketAndContents(bucketName);
20550
20598
  }
20551
- await AliyunService.deleteCdnDomain(cdnDomain);
20552
- await AliyunService.deleteBucketAndContents(bucketName);
20553
20599
  }
20554
20600
  async deleteServerResources(service) {
20555
20601
  const network = this.getNetworkConfig(service);
@@ -23065,7 +23111,7 @@ function parseServiceArgs(tokens) {
23065
23111
  cwd = requireValue6(rest, token);
23066
23112
  break;
23067
23113
  case "--env":
23068
- if (action !== "deploy" && action !== "init" && action !== "stop" && action !== "deploy-logs" && action !== "deploy-history") {
23114
+ if (action !== "deploy" && action !== "init" && action !== "stop" && action !== "log" && action !== "deploy-logs" && action !== "deploy-history") {
23069
23115
  throw new Error(`Unknown service ${action} option: ${token}`);
23070
23116
  }
23071
23117
  env = requireValue6(rest, token);
@@ -23094,7 +23140,7 @@ function parseServiceArgs(tokens) {
23094
23140
  const namespace = parsedRef.namespace;
23095
23141
  const name = parsedRef.objectId;
23096
23142
  if (action === "log") {
23097
- return { type: "service" /* Service */, action, namespace, name, baseUrl, json, page, history, search, follow };
23143
+ return { type: "service" /* Service */, action, namespace, name, baseUrl, json, page, history, search, follow, env };
23098
23144
  }
23099
23145
  if (action === "deploy-logs" || action === "deploy-history") {
23100
23146
  return { type: "service" /* Service */, action, namespace, name, env, page, baseUrl, json };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.24.30",
3
+ "version": "0.24.32",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {