nvii 2.0.1 → 2.0.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.
Files changed (2) hide show
  1. package/dist/index.js +302 -209
  2. package/package.json +6 -4
package/dist/index.js CHANGED
@@ -23916,6 +23916,74 @@ var {
23916
23916
  Help
23917
23917
  } = import_index.default;
23918
23918
 
23919
+ // package.json
23920
+ var package_default = {
23921
+ name: "nvii",
23922
+ version: "2.0.1",
23923
+ description: "Secure environment variable management CLI for modern development teams",
23924
+ keywords: [
23925
+ "environment",
23926
+ "variables",
23927
+ "env",
23928
+ "cli",
23929
+ "security",
23930
+ "encryption",
23931
+ "development"
23932
+ ],
23933
+ homepage: "https://nvii.dev",
23934
+ repository: {
23935
+ type: "git",
23936
+ url: "https://github.com/skaleway/nvii.git",
23937
+ directory: "packages/cli"
23938
+ },
23939
+ main: "./dist/index.js",
23940
+ bin: {
23941
+ nvii: "./dist/index.js"
23942
+ },
23943
+ types: "./dist/index.d.ts",
23944
+ module: "./dist/index.mjs",
23945
+ private: false,
23946
+ scripts: {
23947
+ build: "tsup",
23948
+ dev: "tsc && pnpm chmod && tsc -w",
23949
+ chmod: "chmod +x dist/index.js",
23950
+ "test:dev": "./dist/index.js --help",
23951
+ "start:dev": "ts-node src/index.ts || true",
23952
+ start: "node dist/index.js || true"
23953
+ },
23954
+ files: [
23955
+ "README.md",
23956
+ "LICENSE",
23957
+ "./dist"
23958
+ ],
23959
+ license: "ISC",
23960
+ devDependencies: {
23961
+ "@nvii/typescript-config": "workspace:*",
23962
+ "@swc/core": "^1.3.99",
23963
+ "@nvii/db": "workspace:*",
23964
+ "@nvii/env-helpers": "workspace:*",
23965
+ "@types/node": "^20.17.10",
23966
+ "@types/update-notifier": "^6.0.8",
23967
+ commander: "^11.1.0",
23968
+ concurrently: "^9.2.0",
23969
+ nodemon: "^3.1.10",
23970
+ "ts-node": "^10.9.2",
23971
+ "ts-node-dev": "^2.0.0",
23972
+ tsup: "^7.3.0",
23973
+ typescript: "^5.7.2"
23974
+ },
23975
+ dependencies: {
23976
+ "async-listen": "^3.0.1",
23977
+ axios: "^1.7.9",
23978
+ dotenv: "^16.4.7",
23979
+ inquirer: "^12.4.3",
23980
+ nanoid: "^3.3.7",
23981
+ ora: "^7.0.1",
23982
+ picocolors: "^1.0.0",
23983
+ "update-notifier": "7.3.1"
23984
+ }
23985
+ };
23986
+
23919
23987
  // ../env-helpers/dist/index.mjs
23920
23988
  var import_crypto = __toESM(require("crypto"), 1);
23921
23989
  var import_fs = require("fs");
@@ -27854,165 +27922,8 @@ ${error.response.data.error}`));
27854
27922
  }
27855
27923
  };
27856
27924
 
27857
- // src/commands/tag.ts
27858
- var import_picocolors15 = __toESM(require_picocolors());
27859
- async function createTag(args) {
27860
- const oraModule = await import("ora");
27861
- const ora = oraModule.spinners.aesthetic;
27862
- let tagName = "";
27863
- let versionId = "";
27864
- if (args) {
27865
- if (args.name) {
27866
- tagName = args.name;
27867
- }
27868
- if (args.version) {
27869
- versionId = args.version;
27870
- }
27871
- }
27872
- try {
27873
- if (!isLogedIn()) {
27874
- console.log(import_picocolors15.default.red("You must be logged in to create tags."));
27875
- await login();
27876
- return;
27877
- }
27878
- const userConfig = await readConfigFile();
27879
- if (!userConfig?.userId) {
27880
- console.log(import_picocolors15.default.red("No user ID found. Please log in again."));
27881
- return;
27882
- }
27883
- const config = await readProjectConfig();
27884
- if (!config) {
27885
- console.log(
27886
- import_picocolors15.default.red("Cannot read local .nvii folder currently. Try again.")
27887
- );
27888
- process.exit(1);
27889
- }
27890
- const projectId = config.projectId;
27891
- if (!projectId) {
27892
- console.error(
27893
- import_picocolors15.default.red(
27894
- "\u274C Project not linked. Please run 'nvii link' to link your project first."
27895
- )
27896
- );
27897
- process.exit(1);
27898
- }
27899
- const client = await getConfiguredClient();
27900
- if (!versionId) {
27901
- const versionsResponse = await client.get(
27902
- `/projects/${userConfig.userId}/${projectId}/versions?limit=1`
27903
- );
27904
- const versions = versionsResponse.data;
27905
- if (versions.length === 0) {
27906
- console.log(import_picocolors15.default.yellow("No versions available to tag."));
27907
- return;
27908
- }
27909
- versionId = versions[0].id;
27910
- }
27911
- if (!tagName) {
27912
- const { inputTagName } = await esm_default12.prompt([
27913
- {
27914
- type: "input",
27915
- name: "inputTagName",
27916
- message: "Enter tag name:",
27917
- validate: (input) => {
27918
- if (!input.trim())
27919
- return "Tag name cannot be empty";
27920
- if (!/^[a-zA-Z0-9._-]+$/.test(input))
27921
- return "Tag name can only contain letters, numbers, dots, underscores, and hyphens";
27922
- return true;
27923
- }
27924
- }
27925
- ]);
27926
- tagName = inputTagName;
27927
- }
27928
- const response = await client.post(
27929
- `/projects/${userConfig.userId}/${projectId}/versions/tags`,
27930
- {
27931
- versionId,
27932
- tagName
27933
- }
27934
- );
27935
- console.log(
27936
- import_picocolors15.default.green(
27937
- `\u2705 Successfully created tag '${tagName}' for version ${versionId?.slice(0, 8)}`
27938
- )
27939
- );
27940
- } catch (error) {
27941
- if (error.response?.status === 409) {
27942
- console.error(
27943
- import_picocolors15.default.red("\u274C Tag name already exists. Choose a different name.")
27944
- );
27945
- } else {
27946
- console.error(import_picocolors15.default.red("Error creating tag:"), error.message);
27947
- }
27948
- process.exit(1);
27949
- }
27950
- }
27951
- async function listTags() {
27952
- try {
27953
- if (!isLogedIn()) {
27954
- console.log(import_picocolors15.default.red("You must be logged in to list tags."));
27955
- await login();
27956
- return;
27957
- }
27958
- const userConfig = await readConfigFile();
27959
- if (!userConfig?.userId) {
27960
- console.log(import_picocolors15.default.red("No user ID found. Please log in again."));
27961
- return;
27962
- }
27963
- const config = await readProjectConfig();
27964
- if (!config) {
27965
- console.log(
27966
- import_picocolors15.default.red("Cannot read local .nvii folder currently. Try again.")
27967
- );
27968
- process.exit(1);
27969
- }
27970
- const projectId = config.projectId;
27971
- if (!projectId) {
27972
- console.error(
27973
- import_picocolors15.default.red(
27974
- "\u274C Project not linked. Please run 'nvii link' to link your project first."
27975
- )
27976
- );
27977
- process.exit(1);
27978
- }
27979
- const client = await getConfiguredClient();
27980
- const response = await client.get(
27981
- `/projects/${userConfig.userId}/${projectId}/versions/tags`
27982
- );
27983
- const tags = response.data;
27984
- if (!tags || tags.length === 0) {
27985
- console.log(import_picocolors15.default.yellow("No tags found for this project."));
27986
- return;
27987
- }
27988
- console.log(import_picocolors15.default.bold(`
27989
- \u{1F3F7}\uFE0F Tags for project ${import_picocolors15.default.cyan(projectId)}`));
27990
- console.log(import_picocolors15.default.dim("--------------------------------------------------"));
27991
- tags.forEach((tag) => {
27992
- console.log(
27993
- `${import_picocolors15.default.yellow(tag.name)} -> ${import_picocolors15.default.dim(`version ${tag.versionId.slice(0, 8)}`)}`
27994
- );
27995
- console.log(` ${tag.description || "No description"}`);
27996
- console.log(` ${new Date(tag.createdAt).toLocaleDateString()}`);
27997
- console.log(import_picocolors15.default.dim("--------------------------------------------------"));
27998
- });
27999
- } catch (error) {
28000
- if (error.response) {
28001
- console.error(import_picocolors15.default.yellow(`
28002
- ${error.response.data.error}`));
28003
- return;
28004
- }
28005
- if (error.message.includes("User force closed the prompt with SIGINT")) {
28006
- console.log(import_picocolors15.default.yellow("\nTag cancelled."));
28007
- return;
28008
- }
28009
- console.error(import_picocolors15.default.red("Error listing tags:"), error.message);
28010
- process.exit(1);
28011
- }
28012
- }
28013
-
28014
27925
  // src/commands/branch.ts
28015
- var import_picocolors16 = __toESM(require_picocolors());
27926
+ var import_picocolors15 = __toESM(require_picocolors());
28016
27927
  async function createBranch(args) {
28017
27928
  let branchName = "";
28018
27929
  let baseVersionId = "";
@@ -28026,26 +27937,26 @@ async function createBranch(args) {
28026
27937
  }
28027
27938
  try {
28028
27939
  if (!isLogedIn()) {
28029
- console.log(import_picocolors16.default.red("You must be logged in to create branches."));
27940
+ console.log(import_picocolors15.default.red("You must be logged in to create branches."));
28030
27941
  await login();
28031
27942
  return;
28032
27943
  }
28033
27944
  const userConfig = await readConfigFile();
28034
27945
  if (!userConfig?.userId) {
28035
- console.log(import_picocolors16.default.red("No user ID found. Please log in again."));
27946
+ console.log(import_picocolors15.default.red("No user ID found. Please log in again."));
28036
27947
  return;
28037
27948
  }
28038
27949
  const config = await readProjectConfig();
28039
27950
  if (!config) {
28040
27951
  console.log(
28041
- import_picocolors16.default.red("Cannot read local .nvii folder currently. Try again.")
27952
+ import_picocolors15.default.red("Cannot read local .nvii folder currently. Try again.")
28042
27953
  );
28043
27954
  process.exit(1);
28044
27955
  }
28045
27956
  const projectId = config.projectId;
28046
27957
  if (!projectId) {
28047
27958
  console.error(
28048
- import_picocolors16.default.red(
27959
+ import_picocolors15.default.red(
28049
27960
  "\u274C Project not linked. Please run 'nvii link' to link your project first."
28050
27961
  )
28051
27962
  );
@@ -28075,7 +27986,7 @@ async function createBranch(args) {
28075
27986
  );
28076
27987
  const versions = versionsResponse.data;
28077
27988
  if (versions.length === 0) {
28078
- console.log(import_picocolors16.default.yellow("No versions available to branch from."));
27989
+ console.log(import_picocolors15.default.yellow("No versions available to branch from."));
28079
27990
  return;
28080
27991
  }
28081
27992
  baseVersionId = versions[0].id;
@@ -28089,21 +28000,21 @@ async function createBranch(args) {
28089
28000
  }
28090
28001
  );
28091
28002
  if (!response || !response.data) {
28092
- console.log(import_picocolors16.default.yellow("Oops an error occurred creating new branch."));
28003
+ console.log(import_picocolors15.default.yellow("Oops an error occurred creating new branch."));
28093
28004
  process.exit(1);
28094
28005
  }
28095
28006
  console.log(
28096
- import_picocolors16.default.green(
28007
+ import_picocolors15.default.green(
28097
28008
  `\u2705 Successfully created branch '${branchName}' from version ${baseVersionId?.slice(0, 8)}`
28098
28009
  )
28099
28010
  );
28100
28011
  } catch (error) {
28101
28012
  if (error.response?.status === 409) {
28102
28013
  console.error(
28103
- import_picocolors16.default.red("\u274C Branch name already exists. Choose a different name.")
28014
+ import_picocolors15.default.red("\u274C Branch name already exists. Choose a different name.")
28104
28015
  );
28105
28016
  } else {
28106
- console.error(import_picocolors16.default.red("Error creating branch:"), error.message);
28017
+ console.error(import_picocolors15.default.red("Error creating branch:"), error.message);
28107
28018
  }
28108
28019
  process.exit(1);
28109
28020
  }
@@ -28113,26 +28024,26 @@ async function listBranches() {
28113
28024
  const ora = oraModule.default;
28114
28025
  try {
28115
28026
  if (!isLogedIn()) {
28116
- console.log(import_picocolors16.default.red("You must be logged in to list branches."));
28027
+ console.log(import_picocolors15.default.red("You must be logged in to list branches."));
28117
28028
  await login();
28118
28029
  return;
28119
28030
  }
28120
28031
  const userConfig = await readConfigFile();
28121
28032
  if (!userConfig?.userId) {
28122
- console.log(import_picocolors16.default.red("No user ID found. Please log in again."));
28033
+ console.log(import_picocolors15.default.red("No user ID found. Please log in again."));
28123
28034
  return;
28124
28035
  }
28125
28036
  const config = await readProjectConfig();
28126
28037
  if (!config) {
28127
28038
  console.log(
28128
- import_picocolors16.default.red("Cannot read local .nvii folder currently. Try again.")
28039
+ import_picocolors15.default.red("Cannot read local .nvii folder currently. Try again.")
28129
28040
  );
28130
28041
  process.exit(1);
28131
28042
  }
28132
28043
  const projectId = config.projectId;
28133
28044
  if (!projectId) {
28134
28045
  console.error(
28135
- import_picocolors16.default.red(
28046
+ import_picocolors15.default.red(
28136
28047
  "\u274C Project not linked. Please run 'nvii link' to link your project first."
28137
28048
  )
28138
28049
  );
@@ -28146,34 +28057,34 @@ async function listBranches() {
28146
28057
  spinner.stop();
28147
28058
  const branches = response.data;
28148
28059
  if (!branches || branches.length === 0) {
28149
- console.log(import_picocolors16.default.yellow("No branches found for this project."));
28060
+ console.log(import_picocolors15.default.yellow("No branches found for this project."));
28150
28061
  return;
28151
28062
  }
28152
- console.log(import_picocolors16.default.bold(`
28153
- \u{1F33F} Branches for project ${import_picocolors16.default.cyan(projectId)}`));
28154
- console.log(import_picocolors16.default.dim("--------------------------------------------------"));
28063
+ console.log(import_picocolors15.default.bold(`
28064
+ \u{1F33F} Branches for project ${import_picocolors15.default.cyan(projectId)}`));
28065
+ console.log(import_picocolors15.default.dim("--------------------------------------------------"));
28155
28066
  const projectConfig = await readProjectConfig();
28156
28067
  branches.forEach((branch) => {
28157
- const isActive = branch.isActive ? import_picocolors16.default.green("* ") : " ";
28068
+ const isActive = branch.isActive ? import_picocolors15.default.green("* ") : " ";
28158
28069
  console.log(
28159
- `${isActive}${import_picocolors16.default.cyan(projectConfig?.branch === branch.name ? `*${branch.name}` : branch.name)} -> ${import_picocolors16.default.dim(`version ${branch.baseVersionId.slice(0, 8)}`)}`
28070
+ `${isActive}${import_picocolors15.default.cyan(projectConfig?.branch === branch.name ? `*${branch.name}` : branch.name)} -> ${import_picocolors15.default.dim(`version ${branch.baseVersionId.slice(0, 8)}`)}`
28160
28071
  );
28161
28072
  console.log(
28162
28073
  ` Created: ${new Date(branch.createdAt).toLocaleDateString()}`
28163
28074
  );
28164
- console.log(import_picocolors16.default.dim("--------------------------------------------------"));
28075
+ console.log(import_picocolors15.default.dim("--------------------------------------------------"));
28165
28076
  });
28166
28077
  } catch (error) {
28167
28078
  if (error.response) {
28168
- console.error(import_picocolors16.default.yellow(`
28079
+ console.error(import_picocolors15.default.yellow(`
28169
28080
  ${error.response.data.error}`));
28170
28081
  return;
28171
28082
  }
28172
28083
  if (error.message.includes("User force closed the prompt with SIGINT")) {
28173
- console.log(import_picocolors16.default.yellow("\nBranch create cancelled."));
28084
+ console.log(import_picocolors15.default.yellow("\nBranch create cancelled."));
28174
28085
  return;
28175
28086
  }
28176
- console.error(import_picocolors16.default.red("Error listing branches:"), error.message);
28087
+ console.error(import_picocolors15.default.red("Error listing branches:"), error.message);
28177
28088
  process.exit(1);
28178
28089
  }
28179
28090
  }
@@ -28186,26 +28097,26 @@ async function switchBranch(args) {
28186
28097
  }
28187
28098
  try {
28188
28099
  if (!isLogedIn()) {
28189
- console.log(import_picocolors16.default.red("You must be logged in to switch branches."));
28100
+ console.log(import_picocolors15.default.red("You must be logged in to switch branches."));
28190
28101
  await login();
28191
28102
  return;
28192
28103
  }
28193
28104
  const userConfig = await readConfigFile();
28194
28105
  if (!userConfig?.userId) {
28195
- console.log(import_picocolors16.default.red("No user ID found. Please log in again."));
28106
+ console.log(import_picocolors15.default.red("No user ID found. Please log in again."));
28196
28107
  return;
28197
28108
  }
28198
28109
  const config = await readProjectConfig();
28199
28110
  if (!config) {
28200
28111
  console.log(
28201
- import_picocolors16.default.red("Cannot read local .nvii folder currently. Try again.")
28112
+ import_picocolors15.default.red("Cannot read local .nvii folder currently. Try again.")
28202
28113
  );
28203
28114
  process.exit(1);
28204
28115
  }
28205
28116
  const projectId = config.projectId;
28206
28117
  if (!projectId) {
28207
28118
  console.error(
28208
- import_picocolors16.default.red(
28119
+ import_picocolors15.default.red(
28209
28120
  "\u274C Project not linked. Please run 'nvii link' to link your project first."
28210
28121
  )
28211
28122
  );
@@ -28218,7 +28129,7 @@ async function switchBranch(args) {
28218
28129
  );
28219
28130
  const branches = branchesResponse.data;
28220
28131
  if (!branches || branches.length === 0) {
28221
- console.log(import_picocolors16.default.yellow("No branches found for this project."));
28132
+ console.log(import_picocolors15.default.yellow("No branches found for this project."));
28222
28133
  return;
28223
28134
  }
28224
28135
  const { selectedBranch } = await esm_default12.prompt([
@@ -28239,39 +28150,39 @@ async function switchBranch(args) {
28239
28150
  );
28240
28151
  branchName = remoteUpdateResponse.data.name;
28241
28152
  await writeProjectConfig(projectId, branchName);
28242
- console.log(import_picocolors16.default.green(`\u2705 Switched to branch '${branchName}'`));
28153
+ console.log(import_picocolors15.default.green(`\u2705 Switched to branch '${branchName}'`));
28243
28154
  } catch (error) {
28244
28155
  if (error.response) {
28245
- console.error(import_picocolors16.default.yellow(`
28156
+ console.error(import_picocolors15.default.yellow(`
28246
28157
  ${error.response.data.error}`));
28247
28158
  return;
28248
28159
  }
28249
28160
  if (error.message.includes("User force closed the prompt with SIGINT")) {
28250
- console.log(import_picocolors16.default.yellow("\nBranch switch cancelled."));
28161
+ console.log(import_picocolors15.default.yellow("\nBranch switch cancelled."));
28251
28162
  return;
28252
28163
  }
28253
28164
  if (error.response?.status === 404) {
28254
- console.error(import_picocolors16.default.red("\u274C Branch not found."));
28165
+ console.error(import_picocolors15.default.red("\u274C Branch not found."));
28255
28166
  } else {
28256
- console.error(import_picocolors16.default.red("Error switching branch:"), error.message);
28167
+ console.error(import_picocolors15.default.red("Error switching branch:"), error.message);
28257
28168
  }
28258
28169
  process.exit(1);
28259
28170
  }
28260
28171
  }
28261
28172
 
28262
28173
  // src/commands/rollback.ts
28263
- var import_picocolors17 = __toESM(require_picocolors());
28174
+ var import_picocolors16 = __toESM(require_picocolors());
28264
28175
  var skipConfirmationPrompt = async (skipConfirmation, description, id) => {
28265
28176
  if (!skipConfirmation) {
28266
28177
  const { confirmRollback } = await esm_default12.prompt([
28267
28178
  {
28268
28179
  type: "confirm",
28269
28180
  name: "confirmRollback",
28270
- message: `Are you sure you want to rollback to <${import_picocolors17.default.dim(`${description} - id: ${id}`)}>?`
28181
+ message: `Are you sure you want to rollback to <${import_picocolors16.default.dim(`${description} - id: ${id}`)}>?`
28271
28182
  }
28272
28183
  ]);
28273
28184
  if (!confirmRollback) {
28274
- console.log(import_picocolors17.default.cyan("Skipping rollback..."));
28185
+ console.log(import_picocolors16.default.cyan("Skipping rollback..."));
28275
28186
  process.exit(0);
28276
28187
  }
28277
28188
  }
@@ -28289,7 +28200,7 @@ async function rollback(args) {
28289
28200
  }
28290
28201
  try {
28291
28202
  if (!isLogedIn()) {
28292
- console.log(import_picocolors17.default.red("You must be logged in to roll back."));
28203
+ console.log(import_picocolors16.default.red("You must be logged in to roll back."));
28293
28204
  await login();
28294
28205
  return;
28295
28206
  }
@@ -28297,14 +28208,14 @@ async function rollback(args) {
28297
28208
  const config = await readProjectConfig();
28298
28209
  if (!config) {
28299
28210
  console.log(
28300
- import_picocolors17.default.red("Cannot read local .nvii folder currently. Try again.")
28211
+ import_picocolors16.default.red("Cannot read local .nvii folder currently. Try again.")
28301
28212
  );
28302
28213
  process.exit(1);
28303
28214
  }
28304
28215
  const projectId = config.projectId;
28305
28216
  if (!userConfig?.userId || !projectId) {
28306
28217
  console.error(
28307
- import_picocolors17.default.red(
28218
+ import_picocolors16.default.red(
28308
28219
  "Project not linked or user not configured. Please run 'nvii link'."
28309
28220
  )
28310
28221
  );
@@ -28317,7 +28228,7 @@ async function rollback(args) {
28317
28228
  );
28318
28229
  const version = response2.data;
28319
28230
  if (!version) {
28320
- console.log(import_picocolors17.default.red(`Version with id <${versionId}> not found.`));
28231
+ console.log(import_picocolors16.default.red(`Version with id <${versionId}> not found.`));
28321
28232
  return;
28322
28233
  }
28323
28234
  await skipConfirmationPrompt(
@@ -28325,16 +28236,16 @@ async function rollback(args) {
28325
28236
  version.description,
28326
28237
  version.id
28327
28238
  );
28328
- console.log(import_picocolors17.default.cyan("Updating local .env file..."));
28239
+ console.log(import_picocolors16.default.cyan("Updating local .env file..."));
28329
28240
  const values2 = await writeEnvFile(
28330
28241
  version?.content
28331
28242
  );
28332
28243
  if (!values2) {
28333
- console.error(import_picocolors17.default.red("\nOops an unexpected error occurred."));
28244
+ console.error(import_picocolors16.default.red("\nOops an unexpected error occurred."));
28334
28245
  process.exit(1);
28335
28246
  }
28336
28247
  console.log(
28337
- import_picocolors17.default.green(
28248
+ import_picocolors16.default.green(
28338
28249
  "\u2705 Local .env file has been updated to match the rollback version."
28339
28250
  )
28340
28251
  );
@@ -28345,7 +28256,7 @@ async function rollback(args) {
28345
28256
  );
28346
28257
  const versions = versionsResponse.data;
28347
28258
  if (versions.length < 2) {
28348
- console.log(import_picocolors17.default.yellow("Not enough versions to roll back."));
28259
+ console.log(import_picocolors16.default.yellow("Not enough versions to roll back."));
28349
28260
  return;
28350
28261
  }
28351
28262
  const { versionIdToRollback } = await esm_default12.prompt([
@@ -28365,7 +28276,7 @@ async function rollback(args) {
28365
28276
  const versionToRollback = response.data;
28366
28277
  if (!versionToRollback.content) {
28367
28278
  console.error(
28368
- import_picocolors17.default.red("Selected version has no content. Cannot roll back.")
28279
+ import_picocolors16.default.red("Selected version has no content. Cannot roll back.")
28369
28280
  );
28370
28281
  return;
28371
28282
  }
@@ -28374,19 +28285,176 @@ async function rollback(args) {
28374
28285
  versionToRollback.description,
28375
28286
  versionToRollback.id
28376
28287
  );
28377
- console.log(import_picocolors17.default.cyan("Updating local .env file..."));
28288
+ console.log(import_picocolors16.default.cyan("Updating local .env file..."));
28378
28289
  const values = await writeEnvFile(
28379
28290
  versionToRollback?.content
28380
28291
  );
28381
28292
  if (!values) {
28382
- console.error(import_picocolors17.default.red("\nOops an unexpected error occurred."));
28293
+ console.error(import_picocolors16.default.red("\nOops an unexpected error occurred."));
28383
28294
  process.exit(1);
28384
28295
  }
28385
28296
  console.log(
28386
- import_picocolors17.default.green(
28297
+ import_picocolors16.default.green(
28387
28298
  "\u2705 Local .env file has been updated to match the rollback version."
28388
28299
  )
28389
28300
  );
28301
+ } catch (error) {
28302
+ if (error.response) {
28303
+ console.error(import_picocolors16.default.yellow(`
28304
+ ${error.response.data.error}`));
28305
+ return;
28306
+ }
28307
+ if (error.message.includes("User force closed the prompt with SIGINT")) {
28308
+ console.log(import_picocolors16.default.yellow("\nRollback cancelled."));
28309
+ return;
28310
+ }
28311
+ console.error(import_picocolors16.default.red("\nError during rollback:"), error.message);
28312
+ process.exit(1);
28313
+ }
28314
+ }
28315
+
28316
+ // src/commands/tag.ts
28317
+ var import_picocolors17 = __toESM(require_picocolors());
28318
+ async function createTag(args) {
28319
+ const oraModule = await import("ora");
28320
+ const ora = oraModule.spinners.aesthetic;
28321
+ let tagName = "";
28322
+ let versionId = "";
28323
+ if (args) {
28324
+ if (args.name) {
28325
+ tagName = args.name;
28326
+ }
28327
+ if (args.version) {
28328
+ versionId = args.version;
28329
+ }
28330
+ }
28331
+ try {
28332
+ if (!isLogedIn()) {
28333
+ console.log(import_picocolors17.default.red("You must be logged in to create tags."));
28334
+ await login();
28335
+ return;
28336
+ }
28337
+ const userConfig = await readConfigFile();
28338
+ if (!userConfig?.userId) {
28339
+ console.log(import_picocolors17.default.red("No user ID found. Please log in again."));
28340
+ return;
28341
+ }
28342
+ const config = await readProjectConfig();
28343
+ if (!config) {
28344
+ console.log(
28345
+ import_picocolors17.default.red("Cannot read local .nvii folder currently. Try again.")
28346
+ );
28347
+ process.exit(1);
28348
+ }
28349
+ const projectId = config.projectId;
28350
+ if (!projectId) {
28351
+ console.error(
28352
+ import_picocolors17.default.red(
28353
+ "\u274C Project not linked. Please run 'nvii link' to link your project first."
28354
+ )
28355
+ );
28356
+ process.exit(1);
28357
+ }
28358
+ const client = await getConfiguredClient();
28359
+ if (!versionId) {
28360
+ const versionsResponse = await client.get(
28361
+ `/projects/${userConfig.userId}/${projectId}/versions?limit=1`
28362
+ );
28363
+ const versions = versionsResponse.data;
28364
+ if (versions.length === 0) {
28365
+ console.log(import_picocolors17.default.yellow("No versions available to tag."));
28366
+ return;
28367
+ }
28368
+ versionId = versions[0].id;
28369
+ }
28370
+ if (!tagName) {
28371
+ const { inputTagName } = await esm_default12.prompt([
28372
+ {
28373
+ type: "input",
28374
+ name: "inputTagName",
28375
+ message: "Enter tag name:",
28376
+ validate: (input) => {
28377
+ if (!input.trim())
28378
+ return "Tag name cannot be empty";
28379
+ if (!/^[a-zA-Z0-9._-]+$/.test(input))
28380
+ return "Tag name can only contain letters, numbers, dots, underscores, and hyphens";
28381
+ return true;
28382
+ }
28383
+ }
28384
+ ]);
28385
+ tagName = inputTagName;
28386
+ }
28387
+ const response = await client.post(
28388
+ `/projects/${userConfig.userId}/${projectId}/versions/tags`,
28389
+ {
28390
+ versionId,
28391
+ tagName
28392
+ }
28393
+ );
28394
+ console.log(
28395
+ import_picocolors17.default.green(
28396
+ `\u2705 Successfully created tag '${tagName}' for version ${versionId?.slice(0, 8)}`
28397
+ )
28398
+ );
28399
+ } catch (error) {
28400
+ if (error.response?.status === 409) {
28401
+ console.error(
28402
+ import_picocolors17.default.red("\u274C Tag name already exists. Choose a different name.")
28403
+ );
28404
+ } else {
28405
+ console.error(import_picocolors17.default.red("Error creating tag:"), error.message);
28406
+ }
28407
+ process.exit(1);
28408
+ }
28409
+ }
28410
+ async function listTags() {
28411
+ try {
28412
+ if (!isLogedIn()) {
28413
+ console.log(import_picocolors17.default.red("You must be logged in to list tags."));
28414
+ await login();
28415
+ return;
28416
+ }
28417
+ const userConfig = await readConfigFile();
28418
+ if (!userConfig?.userId) {
28419
+ console.log(import_picocolors17.default.red("No user ID found. Please log in again."));
28420
+ return;
28421
+ }
28422
+ const config = await readProjectConfig();
28423
+ if (!config) {
28424
+ console.log(
28425
+ import_picocolors17.default.red("Cannot read local .nvii folder currently. Try again.")
28426
+ );
28427
+ process.exit(1);
28428
+ }
28429
+ const projectId = config.projectId;
28430
+ if (!projectId) {
28431
+ console.error(
28432
+ import_picocolors17.default.red(
28433
+ "\u274C Project not linked. Please run 'nvii link' to link your project first."
28434
+ )
28435
+ );
28436
+ process.exit(1);
28437
+ }
28438
+ const client = await getConfiguredClient();
28439
+ const response = await client.get(
28440
+ `/projects/${userConfig.userId}/${projectId}/versions/tags`
28441
+ );
28442
+ const tags = response.data;
28443
+ if (!tags || tags.length === 0) {
28444
+ console.log(import_picocolors17.default.yellow("No tags found for this project."));
28445
+ return;
28446
+ }
28447
+ console.log(import_picocolors17.default.bold(`
28448
+ \u{1F3F7}\uFE0F Tags for project ${import_picocolors17.default.cyan(projectId)}`));
28449
+ console.log(import_picocolors17.default.dim("--------------------------------------------------"));
28450
+ tags.forEach((tag) => {
28451
+ console.log(
28452
+ `${import_picocolors17.default.yellow(tag.name)} -> ${import_picocolors17.default.dim(`version ${tag.versionId.slice(0, 8)}`)}`
28453
+ );
28454
+ console.log(` ${tag.description || "No description"}`);
28455
+ console.log(` ${new Date(tag.createdAt).toLocaleDateString()}`);
28456
+ console.log(import_picocolors17.default.dim("--------------------------------------------------"));
28457
+ });
28390
28458
  } catch (error) {
28391
28459
  if (error.response) {
28392
28460
  console.error(import_picocolors17.default.yellow(`
@@ -28394,19 +28462,44 @@ ${error.response.data.error}`));
28394
28462
  return;
28395
28463
  }
28396
28464
  if (error.message.includes("User force closed the prompt with SIGINT")) {
28397
- console.log(import_picocolors17.default.yellow("\nRollback cancelled."));
28465
+ console.log(import_picocolors17.default.yellow("\nTag cancelled."));
28398
28466
  return;
28399
28467
  }
28400
- console.error(import_picocolors17.default.red("\nError during rollback:"), error.message);
28468
+ console.error(import_picocolors17.default.red("Error listing tags:"), error.message);
28401
28469
  process.exit(1);
28402
28470
  }
28403
28471
  }
28404
28472
 
28473
+ // src/lib/utils.ts
28474
+ var import_update_notifier = __toESM(require("update-notifier"));
28475
+ var import_picocolors18 = __toESM(require_picocolors());
28476
+ function checkForUpdates({
28477
+ pkg,
28478
+ message,
28479
+ updateCheckInterval = 1e3 * 60 * 60 * 24 * 7
28480
+ // Default: 7 days
28481
+ }) {
28482
+ const notifier = (0, import_update_notifier.default)({
28483
+ pkg,
28484
+ updateCheckInterval
28485
+ });
28486
+ if (notifier.update) {
28487
+ notifier.notify({
28488
+ isGlobal: true,
28489
+ message: message ?? `\u{1F680} Whoa! A new version (${import_picocolors18.default.green("{latestVersion}")}) is out! (You have ${import_picocolors18.default.red("{currentVersion}")})
28490
+ \u2728 Upgrade with: ${import_picocolors18.default.blue("{updateCommand}")}
28491
+ Don't miss out on the cool stuff!`
28492
+ });
28493
+ }
28494
+ }
28495
+
28405
28496
  // src/index.ts
28406
28497
  var program2 = new Command();
28498
+ var cliVersion = package_default.version || "1.0.0";
28499
+ checkForUpdates({ pkg: package_default });
28407
28500
  program2.name("nvii").description(
28408
28501
  "Secure environment variable management for modern development teams"
28409
- ).version("1.0.0").configureHelp({
28502
+ ).version(cliVersion).configureHelp({
28410
28503
  sortSubcommands: true,
28411
28504
  showGlobalOptions: true
28412
28505
  }).addHelpText(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nvii",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Secure environment variable management CLI for modern development teams",
5
5
  "keywords": [
6
6
  "environment",
@@ -33,6 +33,7 @@
33
33
  "devDependencies": {
34
34
  "@swc/core": "^1.3.99",
35
35
  "@types/node": "^20.17.10",
36
+ "@types/update-notifier": "^6.0.8",
36
37
  "commander": "^11.1.0",
37
38
  "concurrently": "^9.2.0",
38
39
  "nodemon": "^3.1.10",
@@ -40,9 +41,9 @@
40
41
  "ts-node-dev": "^2.0.0",
41
42
  "tsup": "^7.3.0",
42
43
  "typescript": "^5.7.2",
43
- "@nvii/env-helpers": "0.0.1",
44
44
  "@nvii/typescript-config": "0.0.0",
45
- "@nvii/db": "1.0.0"
45
+ "@nvii/db": "1.0.0",
46
+ "@nvii/env-helpers": "0.0.1"
46
47
  },
47
48
  "dependencies": {
48
49
  "async-listen": "^3.0.1",
@@ -51,7 +52,8 @@
51
52
  "inquirer": "^12.4.3",
52
53
  "nanoid": "^3.3.7",
53
54
  "ora": "^7.0.1",
54
- "picocolors": "^1.0.0"
55
+ "picocolors": "^1.0.0",
56
+ "update-notifier": "7.3.1"
55
57
  },
56
58
  "scripts": {
57
59
  "build": "tsup",