@popina/cli 5.1.2-20260910122156Z → 5.1.2-20260916115432Z

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