@tolgee/cli 1.0.1 → 1.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.
@@ -23,17 +23,19 @@ async function compareHandler(pattern) {
23
23
  }
24
24
  console.log('Your code project and Tolgee project are out of sync.');
25
25
  if (diff.added.length) {
26
- console.log(ansi_colors_1.default.green.bold(`${diff.added.length} new strings`));
26
+ const key = diff.added.length === 1 ? 'key' : 'keys';
27
+ console.log(ansi_colors_1.default.green.bold(`${diff.added.length} new ${key} found`));
27
28
  for (const key of diff.added) {
28
- (0, syncUtils_1.printKey)(key, 'added');
29
+ (0, syncUtils_1.printKey)(key, false);
29
30
  }
30
31
  // Line break
31
32
  console.log('');
32
33
  }
33
34
  if (diff.removed.length) {
34
- console.log(ansi_colors_1.default.red.bold(`${diff.removed.length} removed strings`));
35
+ const key = diff.removed.length === 1 ? 'key' : 'keys';
36
+ console.log(ansi_colors_1.default.red.bold(`${diff.removed.length} unused ${key}`));
35
37
  for (const key of diff.removed) {
36
- (0, syncUtils_1.printKey)(key, 'removed');
38
+ (0, syncUtils_1.printKey)(key, true);
37
39
  }
38
40
  // Line break
39
41
  console.log('');
@@ -27,8 +27,8 @@ async function askForConfirmation(keys, operation) {
27
27
  process.exit(1);
28
28
  }
29
29
  const str = `The following keys will be ${operation}:`;
30
- console.log(operation === 'added' ? ansi_colors_1.default.bold.green(str) : ansi_colors_1.default.bold.red(str));
31
- keys.forEach((k) => (0, syncUtils_1.printKey)(k, operation));
30
+ console.log(operation === 'created' ? ansi_colors_1.default.bold.green(str) : ansi_colors_1.default.bold.red(str));
31
+ keys.forEach((k) => (0, syncUtils_1.printKey)(k, operation === 'deleted'));
32
32
  const shouldContinue = await (0, ask_1.askBoolean)('Does this look correct?', true);
33
33
  if (!shouldContinue) {
34
34
  (0, logger_1.error)('Aborting.');
@@ -65,7 +65,7 @@ async function syncHandler(pattern) {
65
65
  // Create new keys
66
66
  if (diff.added.length) {
67
67
  if (!opts.yes) {
68
- await askForConfirmation(diff.added, 'added');
68
+ await askForConfirmation(diff.added, 'created');
69
69
  }
70
70
  const keys = diff.added.map((key) => ({
71
71
  name: key.keyName,
@@ -80,7 +80,7 @@ async function syncHandler(pattern) {
80
80
  // Delete unused keys.
81
81
  if (diff.removed.length) {
82
82
  if (!opts.yes) {
83
- await askForConfirmation(diff.removed, 'removed');
83
+ await askForConfirmation(diff.removed, 'deleted');
84
84
  }
85
85
  const ids = await diff.removed.map((k) => k.id);
86
86
  await (0, logger_1.loading)('Deleting unused keys...', opts.client.project.deleteBulkKeys(ids));
@@ -10,17 +10,17 @@ const ansi_colors_1 = __importDefault(require("ansi-colors"));
10
10
  * Prints information about a key, with coloring and formatting.
11
11
  *
12
12
  * @param key The key to print.
13
- * @param type Whether this is an addition or a removal.
13
+ * @param deletion True if the key is about to be deleted.
14
14
  */
15
- function printKey(key, type) {
15
+ function printKey(key, deletion) {
16
16
  const namespace = key.namespace
17
17
  ? ` ${ansi_colors_1.default.italic(`(namespace: ${key.namespace})`)}`
18
18
  : '';
19
- if (type === 'added') {
20
- console.log(`${ansi_colors_1.default.green(`+ ${key.keyName}`)}${namespace}`);
19
+ if (deletion) {
20
+ console.log(`${ansi_colors_1.default.red(`- ${key.keyName}`)}${namespace}`);
21
21
  }
22
22
  else {
23
- console.log(`${ansi_colors_1.default.red(`- ${key.keyName}`)}${namespace}`);
23
+ console.log(`${ansi_colors_1.default.green(`+ ${key.keyName}`)}${namespace}`);
24
24
  }
25
25
  }
26
26
  exports.printKey = printKey;
@@ -47,18 +47,36 @@ function compareKeys(local, remote) {
47
47
  }
48
48
  }
49
49
  // Added keys
50
- const namespaces = [...Object.keys(local), runner_1.NullNamespace];
50
+ const namespaces = [runner_1.NullNamespace, ...Object.keys(local).sort()];
51
51
  for (const namespace of namespaces) {
52
52
  if (namespace in local && local[namespace].size) {
53
- for (const [keyName, defaultValue] of local[namespace].entries()) {
53
+ const keys = local[namespace];
54
+ const keyNames = Array.from(local[namespace].keys()).sort();
55
+ for (const keyName of keyNames) {
54
56
  result.added.push({
55
57
  keyName: keyName,
56
58
  namespace: namespace === runner_1.NullNamespace ? undefined : namespace,
57
- defaultValue: defaultValue || undefined,
59
+ defaultValue: keys.get(keyName) || undefined,
58
60
  });
59
61
  }
60
62
  }
61
63
  }
64
+ // Sort keys
65
+ // This is only necessary for unused keys, because the added keys are sorted directly as they're added.
66
+ result.removed.sort((a, b) => {
67
+ if (a.namespace === b.namespace) {
68
+ return a.keyName > b.keyName ? 1 : a.keyName < b.keyName ? -1 : 0;
69
+ }
70
+ if (!a.namespace && b.namespace)
71
+ return -1;
72
+ if (a.namespace && !b.namespace)
73
+ return 1;
74
+ return a.namespace > b.namespace
75
+ ? 1
76
+ : a.namespace < b.namespace
77
+ ? -1
78
+ : 0;
79
+ });
62
80
  return result;
63
81
  }
64
82
  exports.compareKeys = compareKeys;
@@ -26,10 +26,10 @@ function parseConfig(rc) {
26
26
  }
27
27
  }
28
28
  if ('projectId' in rc) {
29
- if (typeof rc.projectId !== 'number') {
30
- throw new Error('Invalid config: projectId is not a number');
29
+ cfg.projectId = Number(rc.projectId); // Number("") returns 0
30
+ if (!Number.isInteger(cfg.projectId) || cfg.projectId <= 0) {
31
+ throw new Error('Invalid config: projectId should be an integer representing your project Id');
31
32
  }
32
- cfg.projectId = rc.projectId;
33
33
  }
34
34
  if ('sdk' in rc) {
35
35
  if (!constants_1.SDKS.includes(rc.sdk)) {
@@ -393,6 +393,30 @@ exports.default = (0, xstate_1.createMachine)({
393
393
  target: 'idle',
394
394
  actions: ['dynamicChildren', 'pushKey'],
395
395
  },
396
+ 'variable.other.object.ts': {
397
+ target: 'idle',
398
+ actions: ['dynamicChildren', 'pushKey'],
399
+ },
400
+ 'entity.name.function.ts': {
401
+ target: 'idle',
402
+ actions: ['dynamicChildren', 'pushKey'],
403
+ },
404
+ 'storage.type.function.ts': {
405
+ target: 'idle',
406
+ actions: ['dynamicChildren', 'pushKey'],
407
+ },
408
+ 'storage.type.class.ts': {
409
+ target: 'idle',
410
+ actions: ['dynamicChildren', 'pushKey'],
411
+ },
412
+ 'keyword.operator.new.ts': {
413
+ target: 'idle',
414
+ actions: ['dynamicChildren', 'pushKey'],
415
+ },
416
+ 'punctuation.definition.block.ts': {
417
+ target: 'idle',
418
+ actions: ['dynamicChildren', 'pushKey'],
419
+ },
396
420
  'punctuation.definition.template-expression.begin.ts': {
397
421
  target: 'idle',
398
422
  actions: ['dynamicChildren', 'pushKey'],
package/dist/index.js CHANGED
@@ -26,36 +26,31 @@ function topLevelName(command) {
26
26
  ? topLevelName(command.parent)
27
27
  : command.name();
28
28
  }
29
- async function validateApiKey(cmd) {
29
+ async function loadApiKey(cmd) {
30
30
  const opts = cmd.optsWithGlobals();
31
- if (!opts.apiKey) {
32
- // Attempt to load --api-key from config store if not specified
33
- // This is not done as part of the init routine or via the mandatory flag, as this is dependent on the API URL.
34
- const key = await (0, credentials_1.getApiKey)(opts.apiUrl, opts.projectId);
35
- if (!key) {
36
- (0, logger_1.error)('No API key has been provided. You must either provide one via --api-key, or login via `tolgee login`.');
37
- process.exit(1);
31
+ // API Key is already loaded
32
+ if (opts.apiKey)
33
+ return;
34
+ // Attempt to load --api-key from config store if not specified
35
+ // This is not done as part of the init routine or via the mandatory flag, as this is dependent on the API URL.
36
+ const key = await (0, credentials_1.getApiKey)(opts.apiUrl, opts.projectId);
37
+ // No key in store, stop here.
38
+ if (!key)
39
+ return;
40
+ cmd.setOptionValue('apiKey', key);
41
+ program.setOptionValue('_removeApiKeyFromStore', () => {
42
+ if (key.startsWith(constants_1.API_KEY_PAT_PREFIX)) {
43
+ (0, credentials_1.savePat)(opts.apiUrl);
38
44
  }
39
- cmd.setOptionValue('apiKey', key);
40
- program.setOptionValue('_removeApiKeyFromStore', () => {
41
- if (key.startsWith(constants_1.API_KEY_PAT_PREFIX)) {
42
- (0, credentials_1.savePat)(opts.apiUrl);
43
- }
44
- else {
45
- (0, credentials_1.savePak)(opts.apiUrl, opts.projectId);
46
- }
47
- });
48
- }
45
+ else {
46
+ (0, credentials_1.savePak)(opts.apiUrl, opts.projectId);
47
+ }
48
+ });
49
49
  }
50
- function validateProjectId(cmd) {
50
+ function loadProjectId(cmd) {
51
51
  const opts = cmd.optsWithGlobals();
52
- // Validate --project-id is present when using Project API keys
53
- if (opts.projectId === -1 && opts.apiKey.startsWith(constants_1.API_KEY_PAT_PREFIX)) {
54
- (0, logger_1.error)('You must specify a Project ID.');
55
- process.exit(1);
56
- }
57
52
  if (opts.apiKey.startsWith(constants_1.API_KEY_PAK_PREFIX)) {
58
- // Parse the key to ensure we can access the specified Project ID
53
+ // Parse the key and ensure we can access the specified Project ID
59
54
  const projectId = client_1.default.projectIdFromKey(opts.apiKey);
60
55
  program.setOptionValue('projectId', projectId);
61
56
  if (opts.projectId !== -1 && opts.projectId !== projectId) {
@@ -66,10 +61,23 @@ function validateProjectId(cmd) {
66
61
  }
67
62
  }
68
63
  }
64
+ function validateOptions(cmd) {
65
+ const opts = cmd.optsWithGlobals();
66
+ if (opts.projectId === -1) {
67
+ (0, logger_1.error)('No Project ID have been specified. You must either provide one via --project-ir, or by setting up a `.tolgeerc` file.');
68
+ (0, logger_1.info)('Learn more about configuring the CLI here: https://tolgee.io/tolgee-cli/project-configuration');
69
+ process.exit(1);
70
+ }
71
+ if (!opts.apiKey) {
72
+ (0, logger_1.error)('No API key has been provided. You must either provide one via --api-key, or login via `tolgee login`.');
73
+ process.exit(1);
74
+ }
75
+ }
69
76
  async function preHandler(prog, cmd) {
70
77
  if (!NO_KEY_COMMANDS.includes(topLevelName(cmd))) {
71
- await validateApiKey(cmd);
72
- await validateProjectId(cmd);
78
+ await loadApiKey(cmd);
79
+ loadProjectId(cmd);
80
+ validateOptions(cmd);
73
81
  const opts = cmd.optsWithGlobals();
74
82
  const client = new client_1.default({
75
83
  apiUrl: opts.apiUrl,
package/dist/options.js CHANGED
@@ -7,7 +7,7 @@ const commander_1 = require("commander");
7
7
  const constants_1 = require("./constants");
8
8
  function parseProjectId(v) {
9
9
  const val = Number(v);
10
- if (isNaN(val) || val < 1) {
10
+ if (!Number.isInteger(val) || val < 1) {
11
11
  throw new commander_1.InvalidArgumentError('Not a valid project ID.');
12
12
  }
13
13
  return val;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tolgee/cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "type": "commonjs",
5
5
  "description": "A tool to interact with the Tolgee Platform through CLI",
6
6
  "bin": {