@popina/cli 5.1.2-20260911175301Z → 5.1.2

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/build/index.js CHANGED
@@ -10,7 +10,7 @@ import { Command as Command17 } from "@commander-js/extra-typings";
10
10
  import { $ as $24 } from "zx/core";
11
11
 
12
12
  // src/cmd/backup.ts
13
- import * as p9 from "@clack/prompts";
13
+ import * as p10 from "@clack/prompts";
14
14
  import { Command } from "@commander-js/extra-typings";
15
15
  import fse3 from "fs-extra";
16
16
  import color from "picocolors";
@@ -135,23 +135,58 @@ async function checkGCloud() {
135
135
  }
136
136
 
137
137
  // src/utils/gcloud/fetch-env.ts
138
+ import * as p5 from "@clack/prompts";
139
+ import { backOff } from "exponential-backoff";
140
+ import { $ as $8 } from "zx/core";
141
+
142
+ // src/utils/run-with-inherited-stdio.ts
138
143
  import { $ as $7 } from "zx/core";
144
+ var inheritedStdioShell = $7({ stdio: "inherit" });
145
+ async function runWithInheritedStdio(command, args) {
146
+ await inheritedStdioShell`${command} ${args}`;
147
+ }
139
148
 
140
149
  // src/utils/variables.ts
141
150
  var PRAGMA_REPO = "popina/pragma-web";
142
151
  var PROJECT_ID = "pragma-project";
143
152
 
144
153
  // src/utils/gcloud/fetch-env.ts
154
+ var MAX_ATTEMPTS = 3;
145
155
  async function fetchEnv(email3) {
146
- await $7`gcloud secrets versions access latest --secret=DEV_ENVIRONMENT_VARIABLES > .env --project=${PROJECT_ID}`.quiet();
147
- if (email3) {
148
- await $7`echo "\nINITIAL_SUPER_ADMIN_EMAIL=${email3}" >> .env`.quiet();
149
- }
156
+ await backOff(
157
+ async () => await $8({
158
+ input: process.stdin,
159
+ quiet: false
160
+ })`gcloud secrets versions access latest --secret=DEV_ENVIRONMENT_VARIABLES > .env --project=${PROJECT_ID}`,
161
+ {
162
+ numOfAttempts: MAX_ATTEMPTS,
163
+ retry: async (error51, attemptNumber) => {
164
+ const diagnostic = error51.stderr || error51.message;
165
+ const hasMissingCredentials = diagnostic.includes(
166
+ "You do not currently have an active account selected."
167
+ ) || diagnostic.includes("does not have any valid credentials");
168
+ const isTokenExpired = diagnostic.includes(
169
+ // cspell: disable-next-line
170
+ "There was a problem refreshing your current auth tokens: Reauthentication failed"
171
+ );
172
+ if (!hasMissingCredentials && !isTokenExpired || attemptNumber >= MAX_ATTEMPTS) {
173
+ return false;
174
+ }
175
+ p5.log.info(
176
+ `\u23F3 Auth tokens required/expired, manual authentication required`
177
+ );
178
+ await runWithInheritedStdio("gcloud", ["auth", "login", email3]);
179
+ p5.log.success("\u2705 Manual re-authentication succeeded");
180
+ return true;
181
+ }
182
+ }
183
+ );
184
+ await $8`echo "\nINITIAL_SUPER_ADMIN_EMAIL=${email3}" >> .env`.quiet();
150
185
  }
151
186
 
152
187
  // src/utils/gcloud/login-to-google.ts
153
- import * as p5 from "@clack/prompts";
154
- import { backOff } from "exponential-backoff";
188
+ import * as p6 from "@clack/prompts";
189
+ import { backOff as backOff2 } from "exponential-backoff";
155
190
 
156
191
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
157
192
  var external_exports = {};
@@ -3386,7 +3421,7 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
3386
3421
  defineLazy(inst._zod, "pattern", () => {
3387
3422
  if (def.options.every((o) => o._zod.pattern)) {
3388
3423
  const patterns = def.options.map((o) => o._zod.pattern);
3389
- return new RegExp(`^(${patterns.map((p22) => cleanRegex(p22.source)).join("|")})$`);
3424
+ return new RegExp(`^(${patterns.map((p23) => cleanRegex(p23.source)).join("|")})$`);
3390
3425
  }
3391
3426
  return void 0;
3392
3427
  });
@@ -10504,9 +10539,9 @@ var $ZodRegistry = class {
10504
10539
  return this;
10505
10540
  }
10506
10541
  get(schema) {
10507
- const p22 = schema._zod.parent;
10508
- if (p22) {
10509
- const pm = { ...this.get(p22) ?? {} };
10542
+ const p23 = schema._zod.parent;
10543
+ if (p23) {
10544
+ const pm = { ...this.get(p23) ?? {} };
10510
10545
  delete pm.id;
10511
10546
  const f = { ...pm, ...this._map.get(schema) };
10512
10547
  return Object.keys(f).length ? f : void 0;
@@ -14668,11 +14703,11 @@ function date4(params) {
14668
14703
  config(en_default());
14669
14704
 
14670
14705
  // src/utils/gcloud/login-to-google.ts
14671
- import { $ as $8 } from "zx/core";
14706
+ import { $ as $9 } from "zx/core";
14672
14707
  var EMAIL_REGEX = /[\w.+-]+@[\w.-]+\.[a-z]{2,}/i;
14673
14708
  async function loginGoogle() {
14674
- return await backOff(
14675
- async () => await $8({
14709
+ return await backOff2(
14710
+ async () => await $9({
14676
14711
  input: process.stdin,
14677
14712
  quiet: true
14678
14713
  })`gcloud config get-value account`.then((processOutput) => {
@@ -14684,7 +14719,7 @@ async function loginGoogle() {
14684
14719
  {
14685
14720
  retry: async (error51, attemptNumber) => {
14686
14721
  if (attemptNumber > 3) {
14687
- p5.log.error(
14722
+ p6.log.error(
14688
14723
  `\u{1F534} Couldn't manually re-authenticate (exceeded max 3 attempts): ${error51.message}`
14689
14724
  );
14690
14725
  process.exit(1);
@@ -14695,14 +14730,16 @@ async function loginGoogle() {
14695
14730
  "There was a problem refreshing your current auth tokens: Reauthentication failed"
14696
14731
  );
14697
14732
  if (!isNewAccount && !isTokenExpired) {
14698
- p5.log.error(`\u{1F534} gcloud get-value account failed: ${error51.message}`);
14733
+ p6.log.error(`\u{1F534} gcloud get-value account failed: ${error51.message}`);
14699
14734
  process.exit(1);
14700
14735
  }
14701
- p5.log.info(`\u23F3 Auth tokens expired, manual re-authentication required`);
14702
- await $8({ input: process.stdin, quiet: true })`gcloud auth login`.then(() => {
14703
- p5.log.success("\u2705 Manual re-authentication succeeded");
14736
+ p6.log.info(
14737
+ `\u23F3 Auth tokens required/expired, manual authentication required`
14738
+ );
14739
+ await $9({ input: process.stdin, quiet: true })`gcloud auth login`.then(() => {
14740
+ p6.log.success("\u2705 Manual re-authentication succeeded");
14704
14741
  }).catch((error52) => {
14705
- p5.log.error(`\u{1F534} Couldn't re-authenticate: ${error52.message}`);
14742
+ p6.log.error(`\u{1F534} Couldn't re-authenticate: ${error52.message}`);
14706
14743
  });
14707
14744
  return true;
14708
14745
  }
@@ -14711,12 +14748,12 @@ async function loginGoogle() {
14711
14748
  const [email3] = processOutput.lines();
14712
14749
  const parsedEmail = external_exports.email({ pattern: EMAIL_REGEX }).safeParse(email3);
14713
14750
  if (!parsedEmail.success) {
14714
- p5.log.error(
14751
+ p6.log.error(
14715
14752
  `\u{1F534} Couldn't parse user email (${email3}): ${external_exports.prettifyError(parsedEmail.error)}`
14716
14753
  );
14717
14754
  process.exit(1);
14718
14755
  }
14719
- p5.log.info(`\u2139\uFE0F Logged in as ${parsedEmail.data}`);
14756
+ p6.log.info(`\u2139\uFE0F Logged in as ${parsedEmail.data}`);
14720
14757
  return parsedEmail.data;
14721
14758
  });
14722
14759
  }
@@ -14765,7 +14802,7 @@ var removeEnvConfig = (envConfigCopyPath) => {
14765
14802
  };
14766
14803
 
14767
14804
  // package.json
14768
- var version2 = "5.1.2-20260911175301Z";
14805
+ var version2 = "5.1.2";
14769
14806
 
14770
14807
  // src/utils/get-package-info.ts
14771
14808
  async function getPackageInfo() {
@@ -14777,14 +14814,14 @@ async function getPackageInfo() {
14777
14814
  }
14778
14815
 
14779
14816
  // src/utils/gh/check-github-access.ts
14780
- import * as p7 from "@clack/prompts";
14781
- import { $ as $9 } from "zx/core";
14817
+ import * as p8 from "@clack/prompts";
14818
+ import { $ as $10 } from "zx/core";
14782
14819
 
14783
14820
  // src/utils/gh/login-to-github.ts
14784
- import * as p6 from "@clack/prompts";
14821
+ import * as p7 from "@clack/prompts";
14785
14822
  import { spawnSync } from "child_process";
14786
14823
  async function loginGH() {
14787
- p6.log.info("Logging in with GitHub CLI using device authentication...");
14824
+ p7.log.info("Logging in with GitHub CLI using device authentication...");
14788
14825
  const result = spawnSync("gh", ["auth", "login", "-p", "ssh"], {
14789
14826
  stdio: "inherit"
14790
14827
  });
@@ -14793,43 +14830,43 @@ async function loginGH() {
14793
14830
  "GitHub authentication did not complete. Run `gh auth login -p ssh`, then try popina init again."
14794
14831
  );
14795
14832
  }
14796
- p6.log.success("Authenticated with GitHub CLI.");
14833
+ p7.log.success("Authenticated with GitHub CLI.");
14797
14834
  }
14798
14835
 
14799
14836
  // src/utils/gh/check-github-access.ts
14800
14837
  async function checkGitHubAccess() {
14801
- const hasGH = await $9`command -v gh`.quiet().then(() => true).catch(() => false);
14838
+ const hasGH = await $10`command -v gh`.quiet().then(() => true).catch(() => false);
14802
14839
  if (!hasGH) {
14803
14840
  throw new Error(
14804
14841
  "GitHub CLI is required. Install it with `brew install gh`, then try again."
14805
14842
  );
14806
14843
  }
14807
- const isLoggedIn = await $9`gh auth status`.quiet().then(() => true).catch(() => false);
14844
+ const isLoggedIn = await $10`gh auth status`.quiet().then(() => true).catch(() => false);
14808
14845
  if (!isLoggedIn) {
14809
14846
  await loginGH();
14810
- p7.log.success("You are now logged in to GitHub.");
14847
+ p8.log.success("You are now logged in to GitHub.");
14811
14848
  }
14812
- const hasRepoAccess = await $9`gh repo view ${PRAGMA_REPO} --json nameWithOwner --jq '.nameWithOwner'`.quiet().then(({ stdout }) => stdout.trim() === PRAGMA_REPO).catch(() => false);
14849
+ const hasRepoAccess = await $10`gh repo view ${PRAGMA_REPO} --json nameWithOwner --jq '.nameWithOwner'`.quiet().then(({ stdout }) => stdout.trim() === PRAGMA_REPO).catch(() => false);
14813
14850
  if (!hasRepoAccess) {
14814
14851
  throw new Error(
14815
14852
  "Your GitHub account cannot access popina/pragma-web. Ask the Popina team to add you, then run popina init again."
14816
14853
  );
14817
14854
  }
14818
- p7.log.success("GitHub access to popina/pragma-web is ready.");
14855
+ p8.log.success("GitHub access to popina/pragma-web is ready.");
14819
14856
  }
14820
14857
 
14821
14858
  // src/utils/gh/clone-github-project.ts
14822
- import { $ as $11 } from "zx/core";
14859
+ import { $ as $12 } from "zx/core";
14823
14860
 
14824
14861
  // src/utils/gh/ensure-github-known-host.ts
14825
14862
  import { appendFile, mkdir, readFile } from "fs/promises";
14826
14863
  import { homedir } from "os";
14827
14864
  import { join as join2 } from "path";
14828
- import { $ as $10 } from "zx/core";
14865
+ import { $ as $11 } from "zx/core";
14829
14866
  var githubHost = "github.com";
14830
14867
  async function hasGitHubKnownHost(knownHostsPath) {
14831
14868
  try {
14832
- const { stdout } = await $10`ssh-keygen -F ${githubHost} -f ${knownHostsPath}`.quiet();
14869
+ const { stdout } = await $11`ssh-keygen -F ${githubHost} -f ${knownHostsPath}`.quiet();
14833
14870
  return stdout.trim().length > 0;
14834
14871
  } catch {
14835
14872
  return false;
@@ -14841,7 +14878,7 @@ function isMissingFileError(error51) {
14841
14878
  async function ensureGitHubKnownHost(sshDirectory = join2(homedir(), ".ssh")) {
14842
14879
  const knownHostsPath = join2(sshDirectory, "known_hosts");
14843
14880
  if (await hasGitHubKnownHost(knownHostsPath)) return;
14844
- const { stdout } = await $10`gh api meta --jq '.ssh_keys[]'`.quiet();
14881
+ const { stdout } = await $11`gh api meta --jq '.ssh_keys[]'`.quiet();
14845
14882
  const hostKeys = stdout.split(/\r?\n/).map((key) => key.trim()).filter(Boolean);
14846
14883
  if (hostKeys.length === 0 || hostKeys.some((key) => !/^[A-Za-z0-9@._+-]+ [A-Za-z0-9+/=]+$/.test(key))) {
14847
14884
  throw new Error("GitHub did not return valid SSH host keys. Try again.");
@@ -14869,24 +14906,24 @@ async function ensureGitHubKnownHost(sshDirectory = join2(homedir(), ".ssh")) {
14869
14906
  async function cloneProject(destination) {
14870
14907
  await ensureGitHubKnownHost();
14871
14908
  const sshCommand = "ssh -o BatchMode=yes -o StrictHostKeyChecking=yes -o ConnectTimeout=15";
14872
- await $11`GIT_TERMINAL_PROMPT=0 GIT_SSH_COMMAND=${sshCommand} gh repo clone ${PRAGMA_REPO} ${destination}`.quiet();
14909
+ await $12`GIT_TERMINAL_PROMPT=0 GIT_SSH_COMMAND=${sshCommand} gh repo clone ${PRAGMA_REPO} ${destination}`.quiet();
14873
14910
  }
14874
14911
 
14875
14912
  // src/utils/mise/check-mise.ts
14876
- import * as p8 from "@clack/prompts";
14877
- import { $ as $12 } from "zx/core";
14913
+ import * as p9 from "@clack/prompts";
14914
+ import { $ as $13 } from "zx/core";
14878
14915
  async function checkMise() {
14879
- const { stdout } = await $12`mise --version`.quiet().catch(() => {
14916
+ const { stdout } = await $13`mise --version`.quiet().catch(() => {
14880
14917
  throw new Error(
14881
14918
  "mise is not installed. Install it with `brew install mise`, then try again."
14882
14919
  );
14883
14920
  });
14884
14921
  const [version3] = stdout.trim().split(" ");
14885
- p8.log.success(`mise ${version3} is installed.`);
14922
+ p9.log.success(`mise ${version3} is installed.`);
14886
14923
  }
14887
14924
 
14888
14925
  // src/utils/mise/run-mise.ts
14889
- import { $ as $13 } from "zx/core";
14926
+ import { $ as $14 } from "zx/core";
14890
14927
  function getMiseSetupTasks(shouldSetupDatabase) {
14891
14928
  if (!shouldSetupDatabase) return ["setup:dependencies"];
14892
14929
  return [
@@ -14897,7 +14934,7 @@ function getMiseSetupTasks(shouldSetupDatabase) {
14897
14934
  ];
14898
14935
  }
14899
14936
  async function checkMiseSetupTasks() {
14900
- const { stdout } = await $13`mise tasks --json`.quiet();
14937
+ const { stdout } = await $14`mise tasks --json`.quiet();
14901
14938
  const tasks = JSON.parse(stdout);
14902
14939
  const taskNames = new Set(
14903
14940
  Array.isArray(tasks) ? tasks.flatMap((task) => {
@@ -14917,25 +14954,25 @@ async function checkMiseSetupTasks() {
14917
14954
  }
14918
14955
  }
14919
14956
  async function installMiseTools() {
14920
- await $13`mise install`.quiet();
14957
+ await $14`mise install`.quiet();
14921
14958
  await checkMiseSetupTasks();
14922
14959
  }
14923
14960
  async function runMiseTask(task) {
14924
- const { stdout } = await $13`mise run ${task}`.quiet();
14961
+ const { stdout } = await $14`mise run ${task}`.quiet();
14925
14962
  return stdout;
14926
14963
  }
14927
14964
 
14928
14965
  // src/cmd/backup.ts
14929
14966
  var backup = new Command().name("backup").description("Back up the database to a file").action(async () => {
14930
14967
  console.clear();
14931
- p9.intro(`${color.bgCyan(color.black(" Popina CLI - DB Backup "))}`);
14932
- p9.log.step("Creating database backup...");
14968
+ p10.intro(`${color.bgCyan(color.black(" Popina CLI - DB Backup "))}`);
14969
+ p10.log.step("Creating database backup...");
14933
14970
  const defaultBranchName = await getGitBranch();
14934
14971
  const defaultName = `${defaultBranchName}-${getTimestamp()}`;
14935
14972
  const backupDir = "./docker/database/backups";
14936
- const userInput = await p9.group(
14973
+ const userInput = await p10.group(
14937
14974
  {
14938
- backupName: () => p9.text({
14975
+ backupName: () => p10.text({
14939
14976
  message: "Enter a name for the backup:",
14940
14977
  defaultValue: defaultName,
14941
14978
  placeholder: `Default is branch name: ${defaultBranchName}`
@@ -14943,7 +14980,7 @@ var backup = new Command().name("backup").description("Back up the database to a
14943
14980
  },
14944
14981
  {
14945
14982
  onCancel: () => {
14946
- p9.cancel("Backup process was canceled.");
14983
+ p10.cancel("Backup process was canceled.");
14947
14984
  process.exit(0);
14948
14985
  }
14949
14986
  }
@@ -14951,12 +14988,12 @@ var backup = new Command().name("backup").description("Back up the database to a
14951
14988
  const backupFileName = `${sanitizeFilename(userInput.backupName)}.tar.gz`;
14952
14989
  const backupFilePath = `${backupDir}/${backupFileName}`;
14953
14990
  if (await fse3.exists(backupFilePath)) {
14954
- p9.log.warn(
14991
+ p10.log.warn(
14955
14992
  `A backup with the name '${backupFileName}' already exists. Please choose a different name.`
14956
14993
  );
14957
14994
  process.exit(0);
14958
14995
  }
14959
- const spinner10 = p9.spinner();
14996
+ const spinner10 = p10.spinner();
14960
14997
  const startTime = Date.now();
14961
14998
  spinner10.start(`\u{1F4E6} Creating backup`);
14962
14999
  await fse3.mkdir(backupDir, { recursive: true });
@@ -14966,26 +15003,17 @@ var backup = new Command().name("backup").description("Back up the database to a
14966
15003
  const elapsedTime = ((endTime - startTime) / 1e3).toFixed(2);
14967
15004
  const backupStats = await fse3.stat(backupFilePath);
14968
15005
  const backupSize = (backupStats.size / 1024 / 1024).toFixed(2);
14969
- p9.log.info(`Backup file: ${backupFileName}`);
14970
- p9.log.info(`Backup size: ${backupSize} MB`);
14971
- p9.log.info(`Backup location: ${backupDir}`);
14972
- p9.log.info(`Elapsed time: ${elapsedTime} seconds`);
14973
- p9.outro("\u2728 Database backup complete!");
15006
+ p10.log.info(`Backup file: ${backupFileName}`);
15007
+ p10.log.info(`Backup size: ${backupSize} MB`);
15008
+ p10.log.info(`Backup location: ${backupDir}`);
15009
+ p10.log.info(`Elapsed time: ${elapsedTime} seconds`);
15010
+ p10.outro("\u2728 Database backup complete!");
14974
15011
  });
14975
15012
 
14976
15013
  // src/cmd/demo.ts
14977
- import * as p10 from "@clack/prompts";
15014
+ import * as p11 from "@clack/prompts";
14978
15015
  import { Command as Command2 } from "@commander-js/extra-typings";
14979
15016
  import color2 from "picocolors";
14980
-
14981
- // src/utils/run-with-inherited-stdio.ts
14982
- import { $ as $14 } from "zx/core";
14983
- var inheritedStdioShell = $14({ stdio: "inherit" });
14984
- async function runWithInheritedStdio(command, args) {
14985
- await inheritedStdioShell`${command} ${args}`;
14986
- }
14987
-
14988
- // src/cmd/demo.ts
14989
15017
  function getDateDaysAgo(days) {
14990
15018
  const date5 = /* @__PURE__ */ new Date();
14991
15019
  date5.setUTCDate(date5.getUTCDate() - days);
@@ -15004,9 +15032,9 @@ function validateSeed(value) {
15004
15032
  }
15005
15033
  var demo = new Command2().name("demo").description("Install deterministic local discovery data").option("--location <location-id>", "Target a specific local location").action(async ({ location }) => {
15006
15034
  console.clear();
15007
- p10.intro(`${color2.bgCyan(color2.black(" Popina CLI - Demo data "))}`);
15035
+ p11.intro(`${color2.bgCyan(color2.black(" Popina CLI - Demo data "))}`);
15008
15036
  await checkRootProjectDirectory();
15009
- const mode = await p10.select({
15037
+ const mode = await p11.select({
15010
15038
  initialValue: "generate",
15011
15039
  message: "What should be prepared?",
15012
15040
  options: [
@@ -15027,8 +15055,8 @@ var demo = new Command2().name("demo").description("Install deterministic local
15027
15055
  }
15028
15056
  ]
15029
15057
  });
15030
- if (p10.isCancel(mode)) {
15031
- p10.cancel("Demo data setup canceled.");
15058
+ if (p11.isCancel(mode)) {
15059
+ p11.cancel("Demo data setup canceled.");
15032
15060
  return;
15033
15061
  }
15034
15062
  const locationArgument = location ? [`--location=${location}`] : [];
@@ -15043,15 +15071,15 @@ var demo = new Command2().name("demo").description("Install deterministic local
15043
15071
  "reset",
15044
15072
  ...locationArgument
15045
15073
  ]);
15046
- p10.outro("Generated sales removed.");
15074
+ p11.outro("Generated sales removed.");
15047
15075
  return;
15048
15076
  }
15049
- const shouldReplaceCatalog = await p10.confirm({
15077
+ const shouldReplaceCatalog = await p11.confirm({
15050
15078
  initialValue: true,
15051
15079
  message: "Replace this location catalog with the idempotent Comme un Vendredi preset?"
15052
15080
  });
15053
- if (p10.isCancel(shouldReplaceCatalog) || !shouldReplaceCatalog) {
15054
- p10.cancel("Demo data setup canceled; the catalog was not changed.");
15081
+ if (p11.isCancel(shouldReplaceCatalog) || !shouldReplaceCatalog) {
15082
+ p11.cancel("Demo data setup canceled; the catalog was not changed.");
15055
15083
  return;
15056
15084
  }
15057
15085
  if (mode === "catalog") {
@@ -15065,26 +15093,26 @@ var demo = new Command2().name("demo").description("Install deterministic local
15065
15093
  "catalog",
15066
15094
  ...locationArgument
15067
15095
  ]);
15068
- p10.outro("Comme un Vendredi is ready for discovery.");
15096
+ p11.outro("Comme un Vendredi is ready for discovery.");
15069
15097
  return;
15070
15098
  }
15071
- const settings = await p10.group(
15099
+ const settings = await p11.group(
15072
15100
  {
15073
- from: () => p10.text({
15101
+ from: () => p11.text({
15074
15102
  defaultValue: getDateDaysAgo(90),
15075
15103
  initialValue: getDateDaysAgo(90),
15076
15104
  message: "First business date",
15077
15105
  placeholder: getDateDaysAgo(90),
15078
15106
  validate: validateDate
15079
15107
  }),
15080
- to: () => p10.text({
15108
+ to: () => p11.text({
15081
15109
  defaultValue: getDateDaysAgo(1),
15082
15110
  initialValue: getDateDaysAgo(1),
15083
15111
  message: "Last business date",
15084
15112
  placeholder: getDateDaysAgo(1),
15085
15113
  validate: validateDate
15086
15114
  }),
15087
- activity: () => p10.select({
15115
+ activity: () => p11.select({
15088
15116
  initialValue: "typical",
15089
15117
  message: "Sales activity",
15090
15118
  options: [
@@ -15093,7 +15121,7 @@ var demo = new Command2().name("demo").description("Install deterministic local
15093
15121
  { label: "Busy", value: "busy" }
15094
15122
  ]
15095
15123
  }),
15096
- complexity: () => p10.select({
15124
+ complexity: () => p11.select({
15097
15125
  initialValue: "realistic",
15098
15126
  message: "Data complexity",
15099
15127
  options: [
@@ -15114,31 +15142,31 @@ var demo = new Command2().name("demo").description("Install deterministic local
15114
15142
  }
15115
15143
  ]
15116
15144
  }),
15117
- seed: () => p10.text({
15145
+ seed: () => p11.text({
15118
15146
  defaultValue: "comme-un-vendredi",
15119
15147
  initialValue: "comme-un-vendredi",
15120
15148
  message: "Deterministic seed",
15121
15149
  placeholder: "comme-un-vendredi",
15122
15150
  validate: validateSeed
15123
15151
  }),
15124
- liveOrders: () => p10.confirm({
15152
+ liveOrders: () => p11.confirm({
15125
15153
  initialValue: true,
15126
15154
  message: "Populate today's live orders?"
15127
15155
  })
15128
15156
  },
15129
15157
  {
15130
15158
  onCancel: () => {
15131
- p10.cancel("Demo data setup canceled.");
15159
+ p11.cancel("Demo data setup canceled.");
15132
15160
  process.exit(0);
15133
15161
  }
15134
15162
  }
15135
15163
  );
15136
15164
  if (settings.from > settings.to) {
15137
- p10.log.error("The first business date must not be after the last one.");
15165
+ p11.log.error("The first business date must not be after the last one.");
15138
15166
  process.exitCode = 1;
15139
15167
  return;
15140
15168
  }
15141
- p10.log.step(
15169
+ p11.log.step(
15142
15170
  "Generating restaurant-medium. Progress will be printed for every business day."
15143
15171
  );
15144
15172
  const startedAt = Date.now();
@@ -15160,11 +15188,11 @@ var demo = new Command2().name("demo").description("Install deterministic local
15160
15188
  ...locationArgument
15161
15189
  ]);
15162
15190
  const elapsedSeconds = Math.round((Date.now() - startedAt) / 1e3);
15163
- p10.outro(`Discovery data ready in ${elapsedSeconds}s.`);
15191
+ p11.outro(`Discovery data ready in ${elapsedSeconds}s.`);
15164
15192
  });
15165
15193
 
15166
15194
  // src/cmd/dev.ts
15167
- import * as p11 from "@clack/prompts";
15195
+ import * as p12 from "@clack/prompts";
15168
15196
  import { Command as Command3 } from "@commander-js/extra-typings";
15169
15197
  import clipboardy from "clipboardy";
15170
15198
  import color3 from "picocolors";
@@ -15531,16 +15559,16 @@ var dev = new Command3().name("dev").description(
15531
15559
  "Interactively select which apps and services to run in development mode"
15532
15560
  ).action(async () => {
15533
15561
  console.clear();
15534
- p11.intro(
15562
+ p12.intro(
15535
15563
  `${color3.bgCyan(color3.black(" Popina CLI - Dev command generator "))}
15536
15564
  `
15537
15565
  );
15538
- const s = p11.spinner();
15566
+ const s = p12.spinner();
15539
15567
  try {
15540
15568
  const services = await discoverServices();
15541
15569
  if (services.length === 0) {
15542
- p11.log.error("No services found with dev scripts");
15543
- p11.outro("Please check your apps directory");
15570
+ p12.log.error("No services found with dev scripts");
15571
+ p12.outro("Please check your apps directory");
15544
15572
  process.exit(1);
15545
15573
  }
15546
15574
  const sortedServices = groupServices(services);
@@ -15549,17 +15577,17 @@ var dev = new Command3().name("dev").description(
15549
15577
  label: `${service.displayName}`,
15550
15578
  hint: service.description || service.path
15551
15579
  }));
15552
- const selected = await p11.multiselect({
15580
+ const selected = await p12.multiselect({
15553
15581
  message: "Select services to start:",
15554
15582
  options,
15555
15583
  required: true
15556
15584
  });
15557
- if (p11.isCancel(selected)) {
15558
- p11.cancel("Operation cancelled");
15585
+ if (p12.isCancel(selected)) {
15586
+ p12.cancel("Operation cancelled");
15559
15587
  process.exit(0);
15560
15588
  }
15561
15589
  const selectedPackages = selected;
15562
- const logOrder = await p11.select({
15590
+ const logOrder = await p12.select({
15563
15591
  message: "Select log UI:",
15564
15592
  options: [
15565
15593
  {
@@ -15580,8 +15608,8 @@ var dev = new Command3().name("dev").description(
15580
15608
  ],
15581
15609
  initialValue: "tui"
15582
15610
  });
15583
- if (p11.isCancel(logOrder)) {
15584
- p11.cancel("Operation cancelled");
15611
+ if (p12.isCancel(logOrder)) {
15612
+ p12.cancel("Operation cancelled");
15585
15613
  process.exit(0);
15586
15614
  }
15587
15615
  const command = buildCommand(selectedPackages, logOrder);
@@ -15589,19 +15617,19 @@ var dev = new Command3().name("dev").description(
15589
15617
  await clipboardy.write(command);
15590
15618
  } catch {
15591
15619
  }
15592
- p11.log.message(
15620
+ p12.log.message(
15593
15621
  `
15594
15622
  ${color3.bold("Generated command:")}
15595
15623
  ${color3.cyan(command)}
15596
15624
  `
15597
15625
  );
15598
- p11.outro(`${color3.green("\u2713")} Command copied to clipboard`);
15626
+ p12.outro(`${color3.green("\u2713")} Command copied to clipboard`);
15599
15627
  } catch (err) {
15600
15628
  s.stop("Error occurred");
15601
- p11.log.error(
15629
+ p12.log.error(
15602
15630
  `Failed to discover services: ${err instanceof Error ? err.message : String(err)}`
15603
15631
  );
15604
- p11.outro(
15632
+ p12.outro(
15605
15633
  `Problems? ${color3.underline(color3.cyan("https://linear.new/team/web/new?labels=cli"))}`
15606
15634
  );
15607
15635
  process.exit(1);
@@ -15609,12 +15637,12 @@ ${color3.cyan(command)}
15609
15637
  });
15610
15638
 
15611
15639
  // src/cmd/env.ts
15612
- import * as p15 from "@clack/prompts";
15640
+ import * as p16 from "@clack/prompts";
15613
15641
  import { Command as Command7 } from "@commander-js/extra-typings";
15614
15642
  import color5 from "picocolors";
15615
15643
 
15616
15644
  // src/cmd/env-app.ts
15617
- import * as p12 from "@clack/prompts";
15645
+ import * as p13 from "@clack/prompts";
15618
15646
  import { Command as Command4 } from "@commander-js/extra-typings";
15619
15647
  import fse4 from "fs-extra";
15620
15648
  import glob2 from "tiny-glob";
@@ -15632,17 +15660,17 @@ var getPragmaDependencies = (packageJsonPath) => {
15632
15660
  }
15633
15661
  return [];
15634
15662
  } catch (error51) {
15635
- p12.log.error(`Error reading or parsing ${packageJsonPath}: ${error51}`);
15663
+ p13.log.error(`Error reading or parsing ${packageJsonPath}: ${error51}`);
15636
15664
  process.exit(1);
15637
15665
  }
15638
15666
  };
15639
15667
  var explorePackagesDependencies = (packages) => {
15640
15668
  const newPackages = [
15641
15669
  ...packages,
15642
- ...packages.map((p22) => {
15643
- const packageJsonPath = `${CURRENT_DIR}/packages/${p22}/package.json`;
15670
+ ...packages.map((p23) => {
15671
+ const packageJsonPath = `${CURRENT_DIR}/packages/${p23}/package.json`;
15644
15672
  return getPragmaDependencies(packageJsonPath);
15645
- }).flat().filter((p22) => !packages.includes(p22))
15673
+ }).flat().filter((p23) => !packages.includes(p23))
15646
15674
  ];
15647
15675
  return newPackages.length === packages.length ? newPackages : explorePackagesDependencies(newPackages);
15648
15676
  };
@@ -15690,13 +15718,13 @@ var getSingleAppOrPackageEnvList = async (appOrPackage) => {
15690
15718
  async function getAppEnvList(app) {
15691
15719
  const apps = getAppDirList();
15692
15720
  if (!app) {
15693
- app = await p12.select({
15721
+ app = await p13.select({
15694
15722
  message: "Select an app:",
15695
15723
  options: apps.map((app2) => ({ value: app2, label: app2 }))
15696
15724
  });
15697
15725
  }
15698
15726
  if (app && !apps.includes(app)) {
15699
- p12.log.error(`App ${app} does not exist in the code base.`);
15727
+ p13.log.error(`App ${app} does not exist in the code base.`);
15700
15728
  process.exit(1);
15701
15729
  }
15702
15730
  const packageJsonPath = `./apps/${app}/package.json`;
@@ -15704,7 +15732,7 @@ async function getAppEnvList(app) {
15704
15732
  const packageList = Array.from(
15705
15733
  new Set(explorePackagesDependencies(packagesLvl0))
15706
15734
  ).sort();
15707
- p12.log.info(`List of pragma dependencies:
15735
+ p13.log.info(`List of pragma dependencies:
15708
15736
  ${packageList.join(" \n")}`);
15709
15737
  const appAndPackagesToExplore = [app, ...packageList];
15710
15738
  let envKeysList = [];
@@ -15715,23 +15743,23 @@ ${packageList.join(" \n")}`);
15715
15743
  envList = Array.from(/* @__PURE__ */ new Set([...envList, ...currentEnvList]));
15716
15744
  }
15717
15745
  envKeysList = envKeysList.filter((curr, index, self) => self.indexOf(curr) === index).sort();
15718
- p12.log.info(
15746
+ p13.log.info(
15719
15747
  `List of env keys from @pragma/config/env:
15720
15748
  ${envKeysList.join(" \n")}`
15721
15749
  );
15722
15750
  envList = envList.filter((curr, index, self) => self.indexOf(curr) === index).sort();
15723
- p12.log.info(`Environment variables for ${app}:
15751
+ p13.log.info(`Environment variables for ${app}:
15724
15752
  ${envList.join("\n")}`);
15725
- p12.outro("\u2728 Done!");
15753
+ p13.outro("\u2728 Done!");
15726
15754
  }
15727
15755
 
15728
15756
  // src/cmd/env-diff.ts
15729
- import * as p13 from "@clack/prompts";
15757
+ import * as p14 from "@clack/prompts";
15730
15758
  import { Command as Command5 } from "@commander-js/extra-typings";
15731
15759
  import fse5 from "fs-extra";
15732
15760
  import glob3 from "tiny-glob";
15733
15761
  var envDiff = new Command5().command("diff").description("Diff relative commands").action(
15734
- async () => p13.select({
15762
+ async () => p14.select({
15735
15763
  message: "Select a microservice:",
15736
15764
  options: [...getAppDirList(), ...getPackagesDirList()].map(
15737
15765
  (microService) => ({
@@ -15774,7 +15802,7 @@ var getEnvFromCode = async (microServiceName) => {
15774
15802
  };
15775
15803
  var getEnvDiff = async (microServiceName) => {
15776
15804
  if (!microServiceName) {
15777
- microServiceName = await p13.select({
15805
+ microServiceName = await p14.select({
15778
15806
  message: "Select a microservice:",
15779
15807
  options: [...getAppDirList(), ...getPackagesDirList()].map(
15780
15808
  (microService) => ({
@@ -15785,7 +15813,7 @@ var getEnvDiff = async (microServiceName) => {
15785
15813
  });
15786
15814
  }
15787
15815
  const { envList: importedEnv } = await getSingleAppOrPackageEnvList(microServiceName);
15788
- p13.log.info(
15816
+ p14.log.info(
15789
15817
  `[ ${microServiceName} ] Imported env variables:
15790
15818
  ${importedEnv.join(
15791
15819
  "\n"
@@ -15793,7 +15821,7 @@ ${importedEnv.join(
15793
15821
  Total imported env var: ${importedEnv.length}`
15794
15822
  );
15795
15823
  const envUsed = await getEnvFromCode(microServiceName);
15796
- p13.log.info(
15824
+ p14.log.info(
15797
15825
  `[ ${microServiceName} ] Used env variables:
15798
15826
  ${envUsed.join(
15799
15827
  "\n"
@@ -15802,26 +15830,26 @@ Total used env var: ${envUsed.length}`
15802
15830
  );
15803
15831
  const unusedEnvList = importedEnv.filter((env2) => !envUsed.includes(env2));
15804
15832
  if (unusedEnvList.length > 0) {
15805
- p13.log.warning(
15833
+ p14.log.warning(
15806
15834
  `[ ${microServiceName} ] \u2757\uFE0F Unused env variables in the app:
15807
15835
  ${unusedEnvList.join(
15808
15836
  " \n"
15809
15837
  )}`
15810
15838
  );
15811
- p13.log.warning(`Total unused env var: ${unusedEnvList.length}`);
15839
+ p14.log.warning(`Total unused env var: ${unusedEnvList.length}`);
15812
15840
  } else {
15813
- p13.log.success(`[ ${microServiceName} ] \u2705 No unused env variables found!`);
15841
+ p14.log.success(`[ ${microServiceName} ] \u2705 No unused env variables found!`);
15814
15842
  }
15815
15843
  };
15816
15844
 
15817
15845
  // src/cmd/env-pull.ts
15818
- import * as p14 from "@clack/prompts";
15846
+ import * as p15 from "@clack/prompts";
15819
15847
  import { Command as Command6 } from "@commander-js/extra-typings";
15820
15848
  import color4 from "picocolors";
15821
15849
  var envPull = new Command6().name("pull").description("Fetch environment variables from Google Cloud Secret Manager").action(getEnvPull);
15822
15850
  async function getEnvPull() {
15823
- p14.intro(`${color4.bgCyan(color4.black(" Popina CLI - Env "))}`);
15824
- const spinner10 = p14.spinner();
15851
+ p15.intro(`${color4.bgCyan(color4.black(" Popina CLI - Env "))}`);
15852
+ const spinner10 = p15.spinner();
15825
15853
  spinner10.start("\u{1F4C1} Check if you are in the root of a Popina project.");
15826
15854
  await checkRootProjectDirectory();
15827
15855
  spinner10.stop("\u2705 You are in the root of a Popina project.");
@@ -15834,13 +15862,13 @@ async function getEnvPull() {
15834
15862
  spinner10.start("\u{1F511} Fetching secrets from Google Cloud Secret Manager ...");
15835
15863
  await fetchEnv(email3);
15836
15864
  spinner10.stop("\u2705 Secrets fetched from Google Cloud Secret Manager.");
15837
- p14.outro("\u2705 Environment variables are ready to use!");
15865
+ p15.outro("\u2705 Environment variables are ready to use!");
15838
15866
  }
15839
15867
 
15840
15868
  // src/cmd/env.ts
15841
15869
  var env = new Command7().name("env").description("Env relative commands").action(async () => {
15842
- p15.intro(`${color5.bgCyan(color5.black(" Popina CLI - Env "))}`);
15843
- await p15.select({
15870
+ p16.intro(`${color5.bgCyan(color5.black(" Popina CLI - Env "))}`);
15871
+ await p16.select({
15844
15872
  message: "Select an action:",
15845
15873
  options: [
15846
15874
  { label: "Pull", value: "pull", hint: "Pull env vars from google" },
@@ -15857,7 +15885,7 @@ var env = new Command7().name("env").description("Env relative commands").action
15857
15885
  ]
15858
15886
  }).then(async (action) => {
15859
15887
  const selectedAction = action;
15860
- p15.log.info(`You selected: ${selectedAction}`);
15888
+ p16.log.info(`You selected: ${selectedAction}`);
15861
15889
  switch (selectedAction) {
15862
15890
  case "pull":
15863
15891
  await getEnvPull();
@@ -15938,14 +15966,14 @@ var gen = new Command12().name("gen").alias("g").description("Generate a new com
15938
15966
  gen.addCommand(ui).addCommand(api);
15939
15967
 
15940
15968
  // src/cmd/init.ts
15941
- import * as p16 from "@clack/prompts";
15969
+ import * as p17 from "@clack/prompts";
15942
15970
  import { Command as Command13 } from "@commander-js/extra-typings";
15943
15971
  import { resolve } from "path";
15944
15972
  import color6 from "picocolors";
15945
15973
  import { cd } from "zx";
15946
15974
  var canceled = /* @__PURE__ */ Symbol("canceled");
15947
15975
  function cancelInitialization(message) {
15948
- p16.cancel(message);
15976
+ p17.cancel(message);
15949
15977
  throw canceled;
15950
15978
  }
15951
15979
  function getErrorMessage(error51) {
@@ -15958,7 +15986,7 @@ function quoteShellArgument(value) {
15958
15986
  return `'${value.replaceAll("'", `'\\''`)}'`;
15959
15987
  }
15960
15988
  async function runStep(message, successMessage, action) {
15961
- const spinner10 = p16.spinner({ indicator: "timer" });
15989
+ const spinner10 = p17.spinner({ indicator: "timer" });
15962
15990
  spinner10.start(message);
15963
15991
  try {
15964
15992
  const result = await action();
@@ -16011,12 +16039,12 @@ async function runProjectSetup(shouldSetupDatabase) {
16011
16039
  const readiness = output.match(
16012
16040
  /CockroachDB is ready after \d+ attempts?\./
16013
16041
  )?.[0];
16014
- p16.log.success(readiness ?? "CockroachDB is ready.");
16042
+ p17.log.success(readiness ?? "CockroachDB is ready.");
16015
16043
  }
16016
16044
  }
16017
16045
  }
16018
16046
  async function getProjectDirectory(workspacePath) {
16019
- p16.note(
16047
+ p17.note(
16020
16048
  `A workspace is the parent folder where you keep your code repositories.
16021
16049
  Current workspace: ${workspacePath}
16022
16050
 
@@ -16024,7 +16052,7 @@ We recommend keeping pragma-web here alongside your future repositories.`,
16024
16052
  "Your workspace"
16025
16053
  );
16026
16054
  while (true) {
16027
- const answer = await p16.text({
16055
+ const answer = await p17.text({
16028
16056
  message: "Project folder name",
16029
16057
  initialValue: "pragma-project",
16030
16058
  validate: (value) => {
@@ -16035,7 +16063,7 @@ We recommend keeping pragma-web here alongside your future repositories.`,
16035
16063
  }
16036
16064
  }
16037
16065
  });
16038
- if (p16.isCancel(answer)) {
16066
+ if (p17.isCancel(answer)) {
16039
16067
  cancelInitialization(
16040
16068
  "Project setup canceled. Run popina init when ready."
16041
16069
  );
@@ -16046,44 +16074,44 @@ We recommend keeping pragma-web here alongside your future repositories.`,
16046
16074
  return { name, path: projectPath, shouldClone: true };
16047
16075
  }
16048
16076
  if (!await dirAlreadyExist(projectPath)) {
16049
- p16.log.warn(
16077
+ p17.log.warn(
16050
16078
  `${projectPath} is a file. Move it or choose another folder name.`
16051
16079
  );
16052
16080
  continue;
16053
16081
  }
16054
16082
  if (!await isPopinaProjectDirectory(projectPath)) {
16055
- p16.log.warn(
16083
+ p17.log.warn(
16056
16084
  `${projectPath} is not a Popina repository. Choose another folder name.`
16057
16085
  );
16058
16086
  continue;
16059
16087
  }
16060
- const shouldResume = await p16.confirm({
16088
+ const shouldResume = await p17.confirm({
16061
16089
  message: `Resume setup in the existing ${name} repository?`,
16062
16090
  initialValue: true
16063
16091
  });
16064
- if (p16.isCancel(shouldResume)) {
16092
+ if (p17.isCancel(shouldResume)) {
16065
16093
  cancelInitialization(
16066
16094
  "Existing project left unchanged. Run popina init when ready."
16067
16095
  );
16068
16096
  }
16069
16097
  if (!shouldResume) {
16070
- p16.log.info(
16098
+ p17.log.info(
16071
16099
  "The existing project was left unchanged. Choose another name."
16072
16100
  );
16073
16101
  continue;
16074
16102
  }
16075
- p16.log.info(`Resuming the existing Popina checkout at ${projectPath}.`);
16103
+ p17.log.info(`Resuming the existing Popina checkout at ${projectPath}.`);
16076
16104
  return { name, path: projectPath, shouldClone: false };
16077
16105
  }
16078
16106
  }
16079
16107
  async function runInitialization() {
16080
16108
  const workspacePath = process.cwd();
16081
- p16.intro(color6.bgCyan(color6.black(" Popina CLI \xB7 Project setup ")));
16082
- p16.box(
16109
+ p17.intro(color6.bgCyan(color6.black(" Popina CLI \xB7 Project setup ")));
16110
+ p17.box(
16083
16111
  "This is the official @popina/cli setup wizard.\nIt will clone pragma-web, install the repository-pinned toolchain,\nfetch development secrets, and optionally prepare CockroachDB.",
16084
16112
  "What happens next"
16085
16113
  );
16086
- p16.log.info("Checking GitHub access and required tools...");
16114
+ p17.log.info("Checking GitHub access and required tools...");
16087
16115
  await checkGitHubAccess();
16088
16116
  await checkMise();
16089
16117
  const project = await getProjectDirectory(workspacePath);
@@ -16100,11 +16128,11 @@ async function runInitialization() {
16100
16128
  "Popina toolchain is ready.",
16101
16129
  installMiseTools
16102
16130
  );
16103
- const shouldFetchEnv = await p16.confirm({
16131
+ const shouldFetchEnv = await p17.confirm({
16104
16132
  message: "Fetch the shared development secrets?",
16105
16133
  initialValue: true
16106
16134
  });
16107
- if (p16.isCancel(shouldFetchEnv)) {
16135
+ if (p17.isCancel(shouldFetchEnv)) {
16108
16136
  cancelInitialization(
16109
16137
  "Secrets setup canceled. Your repository is preserved."
16110
16138
  );
@@ -16122,11 +16150,11 @@ async function runInitialization() {
16122
16150
  () => fetchEnv(email3)
16123
16151
  );
16124
16152
  }
16125
- const shouldSetupDatabase = await p16.confirm({
16153
+ const shouldSetupDatabase = await p17.confirm({
16126
16154
  message: "Start CockroachDB, apply its schema, and add development data?",
16127
16155
  initialValue: true
16128
16156
  });
16129
- if (p16.isCancel(shouldSetupDatabase)) {
16157
+ if (p17.isCancel(shouldSetupDatabase)) {
16130
16158
  cancelInitialization(
16131
16159
  "Database setup canceled. Your repository and completed setup are preserved."
16132
16160
  );
@@ -16141,12 +16169,12 @@ async function runInitialization() {
16141
16169
  "popina demo # optional discovery data",
16142
16170
  "popina dev"
16143
16171
  ].join("\n");
16144
- p16.note(nextSteps, "Next steps");
16145
- p16.note(
16172
+ p17.note(nextSteps, "Next steps");
16173
+ p17.note(
16146
16174
  "popina dev lets you choose services and copies the generated command.\nDeveloper guide: https://knowledge.popina.com/docs\nQuestions: ask in Slack #web.",
16147
16175
  "Need help?"
16148
16176
  );
16149
- p16.outro(
16177
+ p17.outro(
16150
16178
  `Problems? ${color6.underline(
16151
16179
  color6.cyan("https://linear.new/team/web/new?labels=cli")
16152
16180
  )}`
@@ -16162,8 +16190,8 @@ var init = new Command13().name("init").alias("i").description(
16162
16190
  process.exitCode = 130;
16163
16191
  return;
16164
16192
  }
16165
- p16.log.error(getErrorMessage(error51));
16166
- p16.outro(
16193
+ p17.log.error(getErrorMessage(error51));
16194
+ p17.outro(
16167
16195
  "Setup stopped. Fix the issue, then run popina init again to resume."
16168
16196
  );
16169
16197
  process.exitCode = 1;
@@ -16171,12 +16199,12 @@ var init = new Command13().name("init").alias("i").description(
16171
16199
  });
16172
16200
 
16173
16201
  // src/cmd/list.ts
16174
- import * as p18 from "@clack/prompts";
16202
+ import * as p19 from "@clack/prompts";
16175
16203
  import { Command as Command14 } from "@commander-js/extra-typings";
16176
16204
  import color8 from "picocolors";
16177
16205
 
16178
16206
  // src/template.ts
16179
- import * as p17 from "@clack/prompts";
16207
+ import * as p18 from "@clack/prompts";
16180
16208
  import color7 from "picocolors";
16181
16209
  var MARGIN = ` `;
16182
16210
  function printAppsList(apps) {
@@ -16187,7 +16215,7 @@ ${MARGIN}${description}
16187
16215
  ${MARGIN}${color7.underline(
16188
16216
  color7.blue(url2)
16189
16217
  )} - ${color7.italic(color7.blue(path2))}`;
16190
- return p17.log.message(`${apps.map(appRow).join("\n")}`);
16218
+ return p18.log.message(`${apps.map(appRow).join("\n")}`);
16191
16219
  }
16192
16220
 
16193
16221
  // src/cmd/list.ts
@@ -16200,23 +16228,23 @@ var cmdList = new Command14().name("list").description(
16200
16228
  const docList = getDocServices();
16201
16229
  const otherList = getOtherServices();
16202
16230
  const databaseList = getDatabaseTools();
16203
- p18.intro(`${color8.bgCyan(color8.black(` Popina CLI - list `))}`);
16204
- p18.log.message(`
16231
+ p19.intro(`${color8.bgCyan(color8.black(` Popina CLI - list `))}`);
16232
+ p19.log.message(`
16205
16233
  ${color8.bold("API Services:")}`);
16206
16234
  printAppsList(apiList);
16207
- p18.log.message(`
16235
+ p19.log.message(`
16208
16236
  ${color8.bold("Web Applications:")}`);
16209
16237
  printAppsList(appsList);
16210
- p18.log.message(`
16238
+ p19.log.message(`
16211
16239
  ${color8.bold("Documentations:")}`);
16212
16240
  printAppsList(docList);
16213
- p18.log.message(`
16241
+ p19.log.message(`
16214
16242
  ${color8.bold("Background services:")}`);
16215
16243
  printAppsList(otherList);
16216
- p18.log.message(`
16244
+ p19.log.message(`
16217
16245
  ${color8.bold("Database tools:")}`);
16218
16246
  printAppsList(databaseList);
16219
- p18.outro(
16247
+ p19.outro(
16220
16248
  `Problems? ${color8.underline(
16221
16249
  color8.cyan("https://linear.new/team/web/new?labels=cli")
16222
16250
  )}`
@@ -16296,24 +16324,24 @@ var localization = new Command15().name("localization").description("Review loca
16296
16324
  });
16297
16325
 
16298
16326
  // src/cmd/restore.ts
16299
- import * as p21 from "@clack/prompts";
16327
+ import * as p22 from "@clack/prompts";
16300
16328
  import { Argument, Command as Command16, Option } from "@commander-js/extra-typings";
16301
16329
  import fse8 from "fs-extra";
16302
16330
  import color9 from "picocolors";
16303
16331
  import { $ as $23 } from "zx/core";
16304
16332
 
16305
16333
  // src/cmd/restore-local.ts
16306
- import * as p19 from "@clack/prompts";
16334
+ import * as p20 from "@clack/prompts";
16307
16335
  import fse6 from "fs-extra";
16308
16336
  import { $ as $21 } from "zx/core";
16309
- var spinner6 = p19.spinner();
16337
+ var spinner6 = p20.spinner();
16310
16338
  async function restoreLocal() {
16311
16339
  const backupDir = "./docker/database/backups";
16312
16340
  const backups = await fse6.readdir(backupDir);
16313
16341
  const tarGzBackups = backups.filter((b) => b.endsWith(".tar.gz"));
16314
16342
  if (tarGzBackups.length === 0) {
16315
- p19.log.warn("No backup files found to restore.");
16316
- p19.log.warn(
16343
+ p20.log.warn("No backup files found to restore.");
16344
+ p20.log.warn(
16317
16345
  `Database backup files should be placed in the '${backupDir}' folder.`
16318
16346
  );
16319
16347
  process.exit(0);
@@ -16330,9 +16358,9 @@ async function restoreLocal() {
16330
16358
  };
16331
16359
  })
16332
16360
  );
16333
- const userChoices = await p19.group(
16361
+ const userChoices = await p20.group(
16334
16362
  {
16335
- selectedBackup: () => p19.select({
16363
+ selectedBackup: () => p20.select({
16336
16364
  message: "Select a backup to restore:",
16337
16365
  options: backupDetails,
16338
16366
  initialValue: backupDetails[0]?.value
@@ -16340,7 +16368,7 @@ async function restoreLocal() {
16340
16368
  },
16341
16369
  {
16342
16370
  onCancel: () => {
16343
- p19.cancel("Restore process was canceled.");
16371
+ p20.cancel("Restore process was canceled.");
16344
16372
  process.exit(0);
16345
16373
  }
16346
16374
  }
@@ -16362,38 +16390,38 @@ async function restoreLocal() {
16362
16390
  spinner6.stop(
16363
16391
  `\u{1F331} Database restored successfully from ${userChoices.selectedBackup}`
16364
16392
  );
16365
- p19.log.info(`Elapsed time: ${elapsedTime} seconds`);
16366
- p19.log.info(`Restore date: ${formatDate(/* @__PURE__ */ new Date())}`);
16367
- p19.log.info(`Restored DB size: ${restoreSize} MB`);
16368
- p19.log.info(`Branch name: ${branchName}`);
16393
+ p20.log.info(`Elapsed time: ${elapsedTime} seconds`);
16394
+ p20.log.info(`Restore date: ${formatDate(/* @__PURE__ */ new Date())}`);
16395
+ p20.log.info(`Restored DB size: ${restoreSize} MB`);
16396
+ p20.log.info(`Branch name: ${branchName}`);
16369
16397
  }
16370
16398
 
16371
16399
  // src/cmd/restore-remote.ts
16372
- import * as p20 from "@clack/prompts";
16400
+ import * as p21 from "@clack/prompts";
16373
16401
  import fse7 from "fs-extra";
16374
16402
  import { $ as $22 } from "zx/core";
16375
16403
  var STAGING_BACKUP_BUCKET = "staging";
16376
- var spinner8 = p20.spinner();
16404
+ var spinner8 = p21.spinner();
16377
16405
  async function restoreRemote() {
16378
16406
  await checkCockroach();
16379
16407
  await checkGCloud();
16380
16408
  const keyFilePath = await $22`gcloud auth application-default login 2>&1`.then((res) => {
16381
16409
  if (res.exitCode !== 0) {
16382
- p20.cancel(`\u274C Couldn't authenticate with gcloud, ${res.stdout}`);
16410
+ p21.cancel(`\u274C Couldn't authenticate with gcloud, ${res.stdout}`);
16383
16411
  process.exit(0);
16384
16412
  }
16385
- p20.log.success(`\u{1F513} Successfully authenticated with gcloud.`);
16413
+ p21.log.success(`\u{1F513} Successfully authenticated with gcloud.`);
16386
16414
  const parsedFilePath = external_exports.string().min(1).safeParse(res.stdout.match(/\[(?<filepath>.*)\]/)?.groups?.filepath);
16387
16415
  if (parsedFilePath.success) {
16388
16416
  return parsedFilePath.data;
16389
16417
  } else {
16390
- p20.cancel(
16418
+ p21.cancel(
16391
16419
  `\u274C Couldn't find the key's file path from the gcloud response, err: ${parsedFilePath.error}`
16392
16420
  );
16393
16421
  process.exit(0);
16394
16422
  }
16395
16423
  });
16396
- p20.log.success(`\u2705 Successfully parsed the backup file path: ${keyFilePath}`);
16424
+ p21.log.success(`\u2705 Successfully parsed the backup file path: ${keyFilePath}`);
16397
16425
  const base64Key = await fse7.readJson(keyFilePath, "utf-8").then((keyJson) => {
16398
16426
  const parsedKey = external_exports.object({
16399
16427
  account: external_exports.string(),
@@ -16405,7 +16433,7 @@ async function restoreRemote() {
16405
16433
  universe_domain: external_exports.string()
16406
16434
  }).safeParse(keyJson);
16407
16435
  if (!parsedKey.success) {
16408
- p20.log.error(
16436
+ p21.log.error(
16409
16437
  `\u274C Couldn't parse the key file: ${keyFilePath}: ${parsedKey.error}`
16410
16438
  );
16411
16439
  process.exit(0);
@@ -16413,31 +16441,31 @@ async function restoreRemote() {
16413
16441
  return btoa(JSON.stringify(parsedKey.data));
16414
16442
  }
16415
16443
  }).catch((err) => {
16416
- p20.log.error(`\u274C Couldn't read the key file: ${keyFilePath}: ${err}`);
16444
+ p21.log.error(`\u274C Couldn't read the key file: ${keyFilePath}: ${err}`);
16417
16445
  process.exit(0);
16418
16446
  });
16419
- p20.log.success(`\u2705 Successfully parsed the key file.`);
16447
+ p21.log.success(`\u2705 Successfully parsed the key file.`);
16420
16448
  spinner8.start(
16421
16449
  "\u{1F504} Restoring database from latest staging backup in GCP bucket."
16422
16450
  );
16423
16451
  spinner8.message(`\u{1F52B} Dropping the current "dev" database`);
16424
16452
  await $22`cockroach sql --url="postgresql://root@127.0.0.1:26257?sslmode=disable" -e "DROP DATABASE IF EXISTS dev;"`;
16425
- p20.log.success(`\u2705 Successfully reset the current database.`);
16453
+ p21.log.success(`\u2705 Successfully reset the current database.`);
16426
16454
  spinner8.message(`\u{1F6B0} Restoring`);
16427
16455
  const restoreFeedBack = await $22`cockroach sql --url="postgresql://root@localhost:26257?sslmode=disable" -e "RESTORE DATABASE \\"pragma\-api\\" FROM LATEST IN 'gs://pragma-cockroach-backup/${STAGING_BACKUP_BUCKET}?AUTH=specified&CREDENTIALS=${base64Key}' WITH new_db_name = 'dev';"`.then((res) => {
16428
16456
  if (res.stderr) {
16429
16457
  spinner8.stop("\u274C Failed to restore the database.");
16430
- p20.log.error(`\u274C Couldn't restore the database: ${res.stderr}`);
16458
+ p21.log.error(`\u274C Couldn't restore the database: ${res.stderr}`);
16431
16459
  process.exit(0);
16432
16460
  }
16433
16461
  return res.stdout;
16434
16462
  }).catch((err) => {
16435
16463
  spinner8.stop("\u274C Failed to restore the database.");
16436
- p20.log.error(`\u274C Couldn't restore the database: ${err}`);
16464
+ p21.log.error(`\u274C Couldn't restore the database: ${err}`);
16437
16465
  process.exit(0);
16438
16466
  });
16439
16467
  spinner8.stop("\u{1F331} Database restored successfully from GCP Bucket.");
16440
- p20.log.success(String(restoreFeedBack));
16468
+ p21.log.success(String(restoreFeedBack));
16441
16469
  }
16442
16470
 
16443
16471
  // src/cmd/restore.ts
@@ -16451,29 +16479,29 @@ var restore = new Command16().name("restore").description("Restore the database
16451
16479
  new Argument("[source]", "Source to restore the DB from").choices(["local", "remote"]).argParser((source) => sourceSchema.optional().parse(source))
16452
16480
  ).action(async (source, option) => {
16453
16481
  console.clear();
16454
- p21.intro(`${color9.bgCyan(color9.black(" Popina CLI - DB Restore "))}`);
16455
- p21.log.step("Restoring database from backup...");
16482
+ p22.intro(`${color9.bgCyan(color9.black(" Popina CLI - DB Restore "))}`);
16483
+ p22.log.step("Restoring database from backup...");
16456
16484
  await checkDocker();
16457
16485
  if (!await isContainerUp("pragma-project-cockroach-dev")) {
16458
- p21.log.error(
16486
+ p22.log.error(
16459
16487
  "Cockroach container is not running. Please start it and try again."
16460
16488
  );
16461
16489
  process.exit(1);
16462
16490
  }
16463
- const spinner10 = p21.spinner();
16491
+ const spinner10 = p22.spinner();
16464
16492
  if (option.skipArchive) {
16465
- p21.log.info("Skipping archiving of the current database");
16493
+ p22.log.info("Skipping archiving of the current database");
16466
16494
  } else {
16467
- await p21.confirm({
16495
+ await p22.confirm({
16468
16496
  message: "\u{1F4BE} Do you want to archive the current database before restoring?",
16469
16497
  initialValue: true
16470
16498
  }).then(async (archive) => {
16471
16499
  if (String(archive) === "Symbol(clack:cancel)") {
16472
- p21.log.info("Cancelled... \u{1F44B}.");
16500
+ p22.log.info("Cancelled... \u{1F44B}.");
16473
16501
  process.exit(0);
16474
16502
  }
16475
16503
  if (archive === false) {
16476
- p21.log.info("Current database will not be archived");
16504
+ p22.log.info("Current database will not be archived");
16477
16505
  } else {
16478
16506
  spinner10.start(`\u{1F4E6} Archiving current database...`);
16479
16507
  const timestamp = getTimestamp();
@@ -16491,7 +16519,7 @@ var restore = new Command16().name("restore").description("Restore the database
16491
16519
  case "remote":
16492
16520
  return await restoreRemote();
16493
16521
  case void 0:
16494
- await p21.select({
16522
+ await p22.select({
16495
16523
  message: "Choose the source to restore the database from:",
16496
16524
  options: [
16497
16525
  { label: "\u{1F4BD} Local backup", value: "local" },
@@ -16500,7 +16528,7 @@ var restore = new Command16().name("restore").description("Restore the database
16500
16528
  initialValue: "local"
16501
16529
  }).then(async (s) => {
16502
16530
  if (typeof s === "symbol" || String(s) === "Symbol(clack:cancel)") {
16503
- p21.log.info("Canceled... \u{1F44B}");
16531
+ p22.log.info("Canceled... \u{1F44B}");
16504
16532
  process.exit(0);
16505
16533
  } else {
16506
16534
  const parsedSource = sourceSchema.parse(s);
@@ -16512,7 +16540,7 @@ var restore = new Command16().name("restore").description("Restore the database
16512
16540
  }
16513
16541
  });
16514
16542
  }
16515
- p21.outro(
16543
+ p22.outro(
16516
16544
  `\u{1F9DA}\u2728${color9.bgCyan(color9.black(" Database restore complete! "))}\u2728\u{1F9DA}`
16517
16545
  );
16518
16546
  });