@shoper/cli 0.5.2 → 0.6.0

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 (93) hide show
  1. package/README.md +4 -2
  2. package/build/cli/auth/cli_auth_errors_factory.js +1 -1
  3. package/build/cli/auth/cli_auth_initializer.js +6 -1
  4. package/build/cli/auth/service/cli_auth_service.js +11 -2
  5. package/build/cli/auth/tokens/cli_auth_tokens_errors_factory.js +1 -1
  6. package/build/cli/auth/tokens/cli_auth_tokens_initalizer.js +6 -1
  7. package/build/cli/auth/tokens/service/cli_auth_tokens_service.js +8 -1
  8. package/build/cli/class/base_command.js +15 -1
  9. package/build/cli/class/cli_help.js +24 -0
  10. package/build/cli/class/errors/file_system_errors_factory.js +3 -3
  11. package/build/cli/class/errors/http/http_errors_factory.js +1 -1
  12. package/build/cli/commands/auth/cli_auth_add_token_command.js +5 -0
  13. package/build/cli/commands/auth/cli_auth_list_tokens_command.js +20 -11
  14. package/build/cli/commands/auth/cli_auth_logout_command.js +5 -0
  15. package/build/cli/commands/auth/cli_auth_remove_token_command.js +5 -0
  16. package/build/cli/commands/auth/cli_auth_switch_token_command.js +8 -0
  17. package/build/cli/commands/cli_update_command.js +5 -0
  18. package/build/cli/core/cli_setup.js +5 -13
  19. package/build/cli/features/execution_context/execution_context_service.js +2 -0
  20. package/build/cli/features/version/service/cli_version_service.js +2 -2
  21. package/build/cli/hooks/authorization/ensure_authorization_hook.js +9 -2
  22. package/build/cli/hooks/ensure_cli_initialized_hook.js +1 -6
  23. package/build/cli/hooks/ensure_logs_flushed_hook.js +7 -0
  24. package/build/cli/{features → utilities/features}/http_requester/http_client.js +2 -2
  25. package/build/cli/{features → utilities/features}/http_requester/http_requester_initializer.js +1 -1
  26. package/build/cli/utilities/features/logger/api/logger_api.js +28 -0
  27. package/build/cli/utilities/features/logger/logger_constants.js +7 -0
  28. package/build/cli/utilities/features/logger/logger_initializer.js +44 -0
  29. package/build/cli/utilities/features/logger/logs/app_error.js +14 -0
  30. package/build/cli/utilities/features/logger/logs/app_log.js +40 -0
  31. package/build/cli/{class/errors/app/app_error_constants.js → utilities/features/logger/logs/app_logs_constants.js} +1 -1
  32. package/build/cli/utilities/features/logger/service/logger_service.js +108 -0
  33. package/build/cli/utilities/features/logger/transports/log_object_map_transport.js +15 -0
  34. package/build/index.js +14 -2
  35. package/build/theme/class/archive/theme_archive.js +2 -1
  36. package/build/theme/class/archive/theme_archive_errors_factory.js +2 -2
  37. package/build/theme/class/checksums/theme_checksums.js +25 -5
  38. package/build/theme/class/checksums/theme_checksums_error_factory.js +3 -3
  39. package/build/theme/class/fetch_resources/fetch_resources.js +34 -4
  40. package/build/theme/class/fetch_resources/fetch_resources_errors_factory.js +1 -1
  41. package/build/theme/commands/delete/theme_delete_command.js +3 -2
  42. package/build/theme/commands/info/theme_info_command.js +3 -0
  43. package/build/theme/commands/init/theme_init_command.js +10 -1
  44. package/build/theme/commands/list/theme_list_command.js +22 -8
  45. package/build/theme/commands/publish/theme_publish_command.js +5 -1
  46. package/build/theme/commands/pull/theme_pull_command.js +17 -5
  47. package/build/theme/commands/push/theme_push_command.js +7 -1
  48. package/build/theme/commands/theme_verify_command.js +6 -1
  49. package/build/theme/commands/ui/theme_error.js +1 -1
  50. package/build/theme/features/theme/actions/service/theme_actions_service.js +42 -2
  51. package/build/theme/features/theme/actions/theme_actions_initializer.js +3 -1
  52. package/build/theme/features/theme/delete/service/theme_delete_service.js +12 -1
  53. package/build/theme/features/theme/delete/theme_delete_initalizer.js +6 -1
  54. package/build/theme/features/theme/fetch/service/theme_fetch_service.js +35 -6
  55. package/build/theme/features/theme/fetch/theme_fetch_initializer.js +3 -0
  56. package/build/theme/features/theme/init/service/theme_init_service.js +32 -6
  57. package/build/theme/features/theme/init/theme_init_initializer.js +4 -1
  58. package/build/theme/features/theme/merge/service/theme_merge_service.js +38 -4
  59. package/build/theme/features/theme/merge/theme_merge_initializer.js +3 -1
  60. package/build/theme/features/theme/push/service/theme_push_service.js +38 -10
  61. package/build/theme/features/theme/push/theme_push_errors_factory.js +2 -2
  62. package/build/theme/features/theme/push/theme_push_initializer.js +3 -1
  63. package/build/theme/features/theme/push/theme_push_utils.js +1 -1
  64. package/build/theme/features/theme/utils/files_structure/theme_file_structure_errors_factory.js +2 -3
  65. package/build/theme/features/theme/utils/hidden_directory/hidden_directory_utils.js +5 -2
  66. package/build/theme/features/theme/utils/meta_data/theme_meta_data_error_factory.js +1 -1
  67. package/build/theme/features/theme/utils/resources/theme_resources_with_id_directory_utils.js +5 -2
  68. package/build/theme/features/theme/verify/theme_verify_initializer.js +4 -3
  69. package/build/theme/features/theme/verify/verify/theme_verify_service.js +20 -2
  70. package/build/theme/features/theme/watch/api/theme_watch_api.js +11 -0
  71. package/build/theme/features/theme/watch/service/theme_watch_service.js +48 -0
  72. package/build/theme/features/theme/watch/theme_watch_constants.js +2 -0
  73. package/build/theme/features/theme/watch/theme_watch_initializer.js +20 -0
  74. package/build/theme/features/themes/list/services/themes_list_service.js +36 -5
  75. package/build/theme/features/themes/list/themes_list_initializer.js +3 -1
  76. package/build/theme/hooks/ensure_theme_meta_data_untouched_hook.js +4 -2
  77. package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_hook.js +7 -2
  78. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook.js +2 -3
  79. package/build/ui/gradient.js +2 -0
  80. package/build/ui/hooks/stream_hook.js +26 -0
  81. package/build/utils/download_file/download_file_errors_factory.js +1 -1
  82. package/build/utils/download_file/download_file_utils.js +19 -1
  83. package/build/utils/fs/errors/stream_read_error.js +7 -5
  84. package/build/utils/fs/errors/stream_write_error.js +7 -5
  85. package/build/utils/get_api.js +9 -0
  86. package/build/utils/use_api.js +5 -0
  87. package/build/utils/zip/create_zip_utils.js +21 -9
  88. package/build/utils/zip/errors/create_zip_error.js +7 -5
  89. package/build/utils/zip/errors/open_zip_error.js +7 -5
  90. package/build/utils/zip/extract_zip_utils.js +90 -15
  91. package/oclif.config.js +3 -1
  92. package/package.json +13 -4
  93. package/build/cli/class/errors/app/app_error.js +0 -17
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
- # shoper-cli
1
+ ![Shoper CLI](.docs/images/shoper-for-developers.svg)
2
2
 
3
- Comming soon...
3
+ # Shoper CLI
4
+
5
+ Learn more in the [commands docs](https://storefront.developers.shoper.pl/cli/)
@@ -1,4 +1,4 @@
1
- import { AppError } from '../class/errors/app/app_error.js';
1
+ import { AppError } from '../utilities/features/logger/logs/app_error.js';
2
2
  export class CliAuthErrorsFactory {
3
3
  static createCredentialNotFoundError() {
4
4
  return new AppError({
@@ -3,15 +3,20 @@ import { CliAuthService } from './service/cli_auth_service.js';
3
3
  import { CliAuthApi } from './api/cli_auth_api.js';
4
4
  import { CLI_AUTH_TOKENS_API_NAME } from './tokens/cli_auth_tokens_constants.js';
5
5
  import { CLI_AUTH_FEATURE_NAME } from './cli_auth_constants.js';
6
+ import { LOGGER_API_NAME } from '../utilities/features/logger/logger_constants.js';
6
7
  export class CliAuthInitializer extends SyncFeatureInitializer {
7
8
  static featureName = CLI_AUTH_FEATURE_NAME;
8
9
  init() {
9
10
  const cliAuthTokensApi = this.getApiSync(CLI_AUTH_TOKENS_API_NAME);
11
+ const loggerApi = this.getApiSync(LOGGER_API_NAME);
10
12
  return {
11
13
  cores: [
12
14
  {
13
15
  type: FEATURE_CORES_TYPES.api,
14
- instance: new CliAuthApi(new CliAuthService(cliAuthTokensApi))
16
+ instance: new CliAuthApi(new CliAuthService({
17
+ cliAuthTokensApi,
18
+ loggerApi
19
+ }))
15
20
  }
16
21
  ]
17
22
  };
@@ -3,27 +3,35 @@ import { CliAuthErrorsFactory } from '../cli_auth_errors_factory.js';
3
3
  export class CliAuthService {
4
4
  #cliAuthTokensApi;
5
5
  #credentials = null;
6
- constructor(cliAuthTokensApi) {
6
+ #loggerApi;
7
+ constructor({ loggerApi, cliAuthTokensApi }) {
7
8
  this.#cliAuthTokensApi = cliAuthTokensApi;
9
+ this.#loggerApi = loggerApi;
8
10
  this._setCredentials();
9
11
  }
10
12
  _setCredentials() {
13
+ this.#loggerApi.debug('Setting credentials from default token.');
11
14
  const defaultTokenPayload = this.#cliAuthTokensApi.getDefaultTokenPayload();
12
- if (!defaultTokenPayload)
15
+ if (!defaultTokenPayload) {
16
+ this.#loggerApi.debug('No default token payload found. Credentials not set.');
13
17
  return;
18
+ }
14
19
  this.#credentials = new CliCredentials({
15
20
  shopUrl: defaultTokenPayload.iss,
16
21
  scopes: defaultTokenPayload.scope.split(';'),
17
22
  expires: defaultTokenPayload.exp
18
23
  });
24
+ this.#loggerApi.debug('Credentials set successfully.');
19
25
  }
20
26
  getCredentials() {
27
+ this.#loggerApi.debug('Getting credentials.');
21
28
  if (this.#credentials)
22
29
  return this.#credentials;
23
30
  this._setCredentials();
24
31
  return this.#credentials;
25
32
  }
26
33
  hasCredentialsExpired() {
34
+ this.#loggerApi.debug('Checking if credentials have expired.');
27
35
  if (!this.#credentials)
28
36
  throw CliAuthErrorsFactory.createCredentialNotFoundError();
29
37
  const defaultTokenIndex = this.#cliAuthTokensApi.getDefaultTokenIndex();
@@ -32,6 +40,7 @@ export class CliAuthService {
32
40
  return this.#cliAuthTokensApi.hasTokenExpired(defaultTokenIndex);
33
41
  }
34
42
  clearCredentials() {
43
+ this.#loggerApi.debug('Clearing credentials and tokens.');
35
44
  this.#credentials = null;
36
45
  this.#cliAuthTokensApi.clearTokens();
37
46
  }
@@ -1,4 +1,4 @@
1
- import { AppError } from '../../class/errors/app/app_error.js';
1
+ import { AppError } from '../../utilities/features/logger/logs/app_error.js';
2
2
  export class CliAuthTokensErrorsFactory {
3
3
  static createTokenNotFoundError(index) {
4
4
  return new AppError({
@@ -4,6 +4,7 @@ import { CLiAuthTokensService } from './service/cli_auth_tokens_service.js';
4
4
  import { CLI_AUTH_TOKENS_FEATURE_NAME, CLI_AUTH_TOKENS_FILE_NAME } from './cli_auth_tokens_constants.js';
5
5
  import { CLI_DATA_DIRECTORY_API_NAME } from '../../features/data_directory/cli_data_directory_constants.js';
6
6
  import { JsonCache } from '../../class/caches/json_cache/json_cache.js';
7
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
7
8
  // schema
8
9
  // {
9
10
  // default: string;
@@ -18,6 +19,7 @@ export class CliAuthTokensInitializer extends SyncFeatureInitializer {
18
19
  static featureName = CLI_AUTH_TOKENS_FEATURE_NAME;
19
20
  init() {
20
21
  const cliDataDirectoryApi = this.getApiSync(CLI_DATA_DIRECTORY_API_NAME);
22
+ const loggerApi = this.getApiSync(LOGGER_API_NAME);
21
23
  const tokensStore = new JsonCache({
22
24
  path: cliDataDirectoryApi.getDataDirectoryFullPath(),
23
25
  configFileMode: 0o600,
@@ -27,7 +29,10 @@ export class CliAuthTokensInitializer extends SyncFeatureInitializer {
27
29
  cores: [
28
30
  {
29
31
  type: FEATURE_CORES_TYPES.api,
30
- instance: new CliAuthTokensApi(new CLiAuthTokensService(tokensStore))
32
+ instance: new CliAuthTokensApi(new CLiAuthTokensService({
33
+ tokensStore,
34
+ loggerApi
35
+ }))
31
36
  }
32
37
  ]
33
38
  };
@@ -4,10 +4,13 @@ import { CLI_AUTH_DEFAULT_TOKEN_NAME, CLI_AUTH_TOKENS_KEY } from './cli_auth_tok
4
4
  import { CliAuthTokensErrorsFactory } from '../cli_auth_tokens_errors_factory.js';
5
5
  export class CLiAuthTokensService {
6
6
  #tokensStore;
7
- constructor(tokensStore) {
7
+ #loggerApi;
8
+ constructor({ tokensStore, loggerApi }) {
8
9
  this.#tokensStore = tokensStore;
10
+ this.#loggerApi = loggerApi;
9
11
  }
10
12
  addToken(token) {
13
+ this.#loggerApi.debug('Adding new token.');
11
14
  const tokeItem = {
12
15
  token,
13
16
  type: CLI_AUTH_TOKENS_TYPES.jwt
@@ -17,12 +20,14 @@ export class CLiAuthTokensService {
17
20
  this._setTokens(tokens);
18
21
  }
19
22
  validateToken(token) {
23
+ this.#loggerApi.debug('Validating token.');
20
24
  return CLiAuthTokensUtils.isValidJWT(token);
21
25
  }
22
26
  hasToken(index) {
23
27
  return index <= this.getTokensCount();
24
28
  }
25
29
  removeToken(index) {
30
+ this.#loggerApi.debug('Removing token.', { details: { index } });
26
31
  if (!this.hasToken(index))
27
32
  return;
28
33
  const tokens = this._getTokenItems();
@@ -54,6 +59,7 @@ export class CLiAuthTokensService {
54
59
  * Index starts from 1
55
60
  */
56
61
  setDefaultToken(index) {
62
+ this.#loggerApi.debug('Setting default token.', { details: { index } });
57
63
  const tokens = this._getTokenItems();
58
64
  if (tokens.length < index)
59
65
  throw CliAuthTokensErrorsFactory.createTokenNotFoundError(index);
@@ -87,6 +93,7 @@ export class CLiAuthTokensService {
87
93
  return tokens.map((tokenItem) => CLiAuthTokensUtils.getTokenPayload(tokenItem.token));
88
94
  }
89
95
  clearTokens() {
96
+ this.#loggerApi.debug('Clearing all tokens.');
90
97
  this.#tokensStore.clear();
91
98
  }
92
99
  }
@@ -1,10 +1,24 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command, Flags } from '@oclif/core';
2
2
  import { API_RESOLVER_QUERIES, AppError, getStarCoreEnvironment, QueryMessage } from '@dreamcommerce/star_core';
3
3
  export class BaseCommand extends Command {
4
4
  queryBus;
5
5
  commandBus;
6
6
  eventBus;
7
7
  globalCoresContainersRegistry;
8
+ static baseFlags = {
9
+ v: Flags.boolean({
10
+ default: false,
11
+ summary: 'Enable verbose output'
12
+ }),
13
+ vv: Flags.boolean({
14
+ default: false,
15
+ summary: 'Enable very verbose output'
16
+ }),
17
+ 'log-file': Flags.boolean({
18
+ default: false,
19
+ summary: 'Save log to file in the current directory. E.g., --log-file'
20
+ })
21
+ };
8
22
  flags;
9
23
  args;
10
24
  constructor(argv, config) {
@@ -0,0 +1,24 @@
1
+ import { Help } from '@oclif/core';
2
+ import figlet from 'figlet';
3
+ import { renderOnce } from '../../ui/ui_utils.js';
4
+ import { Gradient } from '../../ui/gradient.js';
5
+ import React from 'react';
6
+ import { Text } from '../../ui/text.js';
7
+ export default class CliHelp extends Help {
8
+ async showCommandHelp(cmd) {
9
+ this._showBanner();
10
+ super.showCommandHelp(cmd);
11
+ }
12
+ async showTopicHelp(topic) {
13
+ this._showBanner();
14
+ super.showTopicHelp(topic);
15
+ }
16
+ async showRootHelp() {
17
+ this._showBanner();
18
+ super.showRootHelp();
19
+ }
20
+ _showBanner() {
21
+ renderOnce(React.createElement(Gradient, { name: "retro" },
22
+ React.createElement(Text, null, figlet.textSync('Shoper CLI', { font: 'ANSI Regular' }))));
23
+ }
24
+ }
@@ -1,4 +1,4 @@
1
- import { AppError } from './app/app_error.js';
1
+ import { AppError } from '../../utilities/features/logger/logs/app_error.js';
2
2
  export class FileSystemErrorsFactory {
3
3
  static createDiskFullError() {
4
4
  return new AppError({
@@ -12,7 +12,7 @@ export class FileSystemErrorsFactory {
12
12
  code: 'file_system.error_moving_file',
13
13
  message: `Failed to move file from ${source} to ${destination}`,
14
14
  level: 'error',
15
- stack: err.stack
15
+ error: err
16
16
  });
17
17
  }
18
18
  static createErrorCopyingFile(source, destination, err) {
@@ -20,7 +20,7 @@ export class FileSystemErrorsFactory {
20
20
  code: 'file_system.error_copying_file',
21
21
  message: `Failed to copy file from ${source} to ${destination}`,
22
22
  level: 'error',
23
- stack: err.stack
23
+ error: err
24
24
  });
25
25
  }
26
26
  }
@@ -1,4 +1,4 @@
1
- import { AppError } from '../app/app_error.js';
1
+ import { AppError } from '../../../utilities/features/logger/logs/app_error.js';
2
2
  import { HTTP_NOT_FOUND_ERROR_CODE } from './http_errors_constants.js';
3
3
  export class HttpErrorsFactory {
4
4
  static createUnauthorizedError() {
@@ -8,12 +8,14 @@ import { Box } from '../../../ui/box.js';
8
8
  import { Command } from '../../../ui/command.js';
9
9
  import React from 'react';
10
10
  import { Error } from '../../../ui/message_box/error.js';
11
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
11
12
  export class CliAuthAddTokenCommand extends BaseCliCommand {
12
13
  static summary = 'Adds a new authentication token and saves it locally.';
13
14
  static description = 'The added token will be set as your default authentication token.\n\nUse this when you’ve generated a token in your store panel and want to authenticate your CLI commands.';
14
15
  static examples = ['<%= config.bin %> <%= command.id %>'];
15
16
  async run() {
16
17
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
18
+ const loggerApi = this.getApi(LOGGER_API_NAME);
17
19
  try {
18
20
  const { input: token } = await promptInput('Please paste your CLI token:');
19
21
  const { isValid, message } = cliAuthTokensApi.validateToken(token);
@@ -34,6 +36,9 @@ export class CliAuthAddTokenCommand extends BaseCliCommand {
34
36
  " to view your saved tokens."))));
35
37
  }
36
38
  catch (err) {
39
+ loggerApi.error('Error while adding auth token', {
40
+ error: err
41
+ });
37
42
  renderOnce(React.createElement(Error, { header: "Error: Failed to add token: " },
38
43
  React.createElement(Box, null,
39
44
  React.createElement(Text, null, err.toString()))));
@@ -3,28 +3,37 @@ import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_cons
3
3
  import React from 'react';
4
4
  import { CliAuthCommandsUtils } from './cli_auth_commands_utils.js';
5
5
  import { Table } from '../../../ui/table/table.js';
6
- import { render } from '../../../ui/ui_utils.js';
6
+ import { render, renderOnce } from '../../../ui/ui_utils.js';
7
7
  import { Box } from '../../../ui/box.js';
8
8
  import { Tip } from '../../../ui/tip.js';
9
9
  import { Command } from '../../../ui/command.js';
10
10
  import { Text } from '../../../ui/text.js';
11
11
  import { Info } from '../../../ui/message_box/info.js';
12
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
12
13
  export class CliAuthListTokensCommand extends BaseCliCommand {
13
14
  static summary = 'Displays a list of all authentication tokens stored locally.';
14
15
  static description = 'For each token, you’ll see its name, index, assigned store URL, access scope and expiration date.\n\nUse this to review your tokens and check which one is set as the default.';
15
16
  static examples = ['<%= config.bin %> <%= command.id %>'];
16
17
  async run() {
17
18
  const tokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
18
- const tokensPayloads = tokensApi.getAllTokensPayloads();
19
- if (!tokensPayloads.length) {
20
- await render(React.createElement(Info, null,
21
- React.createElement(Box, null,
22
- React.createElement(Text, null, "No tokens found")),
23
- React.createElement(Tip, null,
24
- "Generate one using ",
25
- React.createElement(Command, null, "shoper auth add-token"))));
26
- return;
19
+ const loggerApi = this.getApi(LOGGER_API_NAME);
20
+ try {
21
+ const tokensPayloads = tokensApi.getAllTokensPayloads();
22
+ if (!tokensPayloads.length) {
23
+ await render(React.createElement(Info, null,
24
+ React.createElement(Box, null,
25
+ React.createElement(Text, null, "No tokens found")),
26
+ React.createElement(Tip, null,
27
+ "Generate one using ",
28
+ React.createElement(Command, null, "shoper auth add-token"))));
29
+ return;
30
+ }
31
+ renderOnce(React.createElement(Table, { data: CliAuthCommandsUtils.mapToTableData(tokensPayloads, tokensApi.getDefaultTokenIndex(), tokensApi) }));
32
+ }
33
+ catch (err) {
34
+ loggerApi.error('Error while listing auth tokens', {
35
+ error: err
36
+ });
27
37
  }
28
- await render(React.createElement(Table, { data: CliAuthCommandsUtils.mapToTableData(tokensPayloads, tokensApi.getDefaultTokenIndex(), tokensApi) }));
29
38
  }
30
39
  }
@@ -7,17 +7,22 @@ import React from 'react';
7
7
  import { Error } from '../../../ui/message_box/error.js';
8
8
  import { Box } from '../../../ui/box.js';
9
9
  import { Text } from '../../../ui/text.js';
10
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
10
11
  export class CliAuthLogoutCommand extends BaseCliCommand {
11
12
  static summary = 'Clears all stored CLI authentication data';
12
13
  async run() {
13
14
  const themeActionsApi = this.getApi(THEME_ACTIONS_API_NAME);
14
15
  const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
16
+ const loggerApi = this.getApi(LOGGER_API_NAME);
15
17
  try {
16
18
  themeActionsApi.clearAllActions();
17
19
  cliAuthApi.clearCredentials();
18
20
  renderOnce(React.createElement(Success, { header: "Logout successful" }));
19
21
  }
20
22
  catch (err) {
23
+ loggerApi.error('Error while logging out', {
24
+ error: err
25
+ });
21
26
  renderOnce(React.createElement(Error, { header: "Logout failed" },
22
27
  React.createElement(Box, null,
23
28
  React.createElement(Text, null, err.toString()))));
@@ -13,6 +13,7 @@ import { Info } from '../../../ui/message_box/info.js';
13
13
  import { Success } from '../../../ui/message_box/success.js';
14
14
  import { Warning } from '../../../ui/message_box/warning.js';
15
15
  import { Error } from '../../../ui/message_box/error.js';
16
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
16
17
  export class CliAuthRemoveTokenCommand extends BaseCliCommand {
17
18
  static summary = 'Removes a locally saved authentication token.';
18
19
  static description = 'Use this to clean up tokens you no longer need.';
@@ -30,6 +31,7 @@ export class CliAuthRemoveTokenCommand extends BaseCliCommand {
30
31
  };
31
32
  async run() {
32
33
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
34
+ const loggerApi = this.getApi(LOGGER_API_NAME);
33
35
  const { index } = this.args;
34
36
  if (!index || !cliAuthTokensApi.hasToken(index)) {
35
37
  renderOnce(React.createElement(MissingTokenIndexError, { command: React.createElement(Command, null, "shoper auth remove-token [TOKEN_INDEX]") }));
@@ -53,6 +55,9 @@ export class CliAuthRemoveTokenCommand extends BaseCliCommand {
53
55
  React.createElement(Text, null, "Token removal was cancelled.")));
54
56
  }
55
57
  catch (err) {
58
+ loggerApi.error('Error while removing auth token', {
59
+ error: err
60
+ });
56
61
  renderOnce(React.createElement(Error, { header: "Error: Failed to remove token: " },
57
62
  React.createElement(Box, null,
58
63
  React.createElement(Text, null, err.toString()))));
@@ -9,6 +9,7 @@ import { MissingTokenIndexError } from './ui/missing_token_index_error.js';
9
9
  import { Command } from '../../../ui/command.js';
10
10
  import { Error } from '../../../ui/message_box/error.js';
11
11
  import { Success } from '../../../ui/message_box/success.js';
12
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
12
13
  export class CliAuthSwitchTokenCommand extends BaseCliCommand {
13
14
  static summary = 'Changes the active authentication token used by the CLI.';
14
15
  static description = 'Use this to switch between multiple saved tokens when working with different stores.';
@@ -26,6 +27,7 @@ export class CliAuthSwitchTokenCommand extends BaseCliCommand {
26
27
  };
27
28
  async run() {
28
29
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
30
+ const loggerApi = this.getApi(LOGGER_API_NAME);
29
31
  const { index } = this.args;
30
32
  if (!index || !cliAuthTokensApi.hasToken(index)) {
31
33
  renderOnce(React.createElement(MissingTokenIndexError, { command: React.createElement(Command, null, "shoper auth switch-token [TOKEN_INDEX]") }));
@@ -37,6 +39,12 @@ export class CliAuthSwitchTokenCommand extends BaseCliCommand {
37
39
  renderOnce(React.createElement(Success, { header: `Success: Token "${defaultToken?.name}" assigned to "${defaultToken?.iss}" is now active` }));
38
40
  }
39
41
  catch (err) {
42
+ loggerApi.error('Failed to switch token', {
43
+ error: err,
44
+ details: {
45
+ tokenIndex: index
46
+ }
47
+ });
40
48
  renderOnce(React.createElement(Error, { header: "Error: Failed to switch token: " },
41
49
  React.createElement(Box, null,
42
50
  React.createElement(Text, null, err.toString()))));
@@ -4,12 +4,14 @@ import { BaseCliCommand } from '../class/base_cli_command.js';
4
4
  import { renderOnce } from '../../ui/ui_utils.js';
5
5
  import React from 'react';
6
6
  import { Error } from '../../ui/message_box/error.js';
7
+ import { LOGGER_API_NAME } from '../utilities/features/logger/logger_constants.js';
7
8
  export class CliUpdateCommand extends BaseCliCommand {
8
9
  static summary = 'Update the Shoper CLI';
9
10
  static description = 'Update the Shoper CLI to the latest version.';
10
11
  static examples = [`$ shoper update`];
11
12
  async run() {
12
13
  const cliVersionApi = this.getApi(CLI_VERSION_API_NAME);
14
+ const loggerApi = this.getApi(LOGGER_API_NAME);
13
15
  try {
14
16
  const installedVersion = await cliVersionApi.getGloballyInstalledVersion();
15
17
  if (!installedVersion) {
@@ -23,6 +25,9 @@ export class CliUpdateCommand extends BaseCliCommand {
23
25
  this.log(stdout);
24
26
  }
25
27
  catch (error) {
28
+ loggerApi.error('Error while updating the CLI', {
29
+ error
30
+ });
26
31
  //npm code for EACCES
27
32
  if (error?.code === 243) {
28
33
  renderOnce(React.createElement(Error, { header: error.message }));
@@ -1,7 +1,7 @@
1
1
  import { getOSRootDirectory } from '../../utils/fs/fs_utils.js';
2
2
  import * as process from 'process';
3
3
  import tmp from 'tmp-promise';
4
- import { HTTPRequesterInitializer } from '../features/http_requester/http_requester_initializer.js';
4
+ import { HTTPRequesterInitializer } from '../utilities/features/http_requester/http_requester_initializer.js';
5
5
  import { SanitizerInitializer, StarCoreSetup } from '@dreamcommerce/star_core';
6
6
  import { CliDataDirectoryInitializer } from '../features/data_directory/cli_data_directory_initializer.js';
7
7
  import { ExecutionContextInitializer } from '../features/execution_context/execution_context_initalizer.js';
@@ -13,6 +13,7 @@ import { getThemeInitializersForCommand } from '../../theme/index.js';
13
13
  import { CLI_AUTH_TOPIC_NAME, CLI_COMMANDS_NAMES } from '../commands/commands_constants.js';
14
14
  import { ThemeActionsInitializer } from '../../theme/features/theme/actions/theme_actions_initializer.js';
15
15
  import { ThemesListInitializer } from '../../theme/features/themes/list/themes_list_initializer.js';
16
+ import { LoggerInitializer } from '../utilities/features/logger/logger_initializer.js';
16
17
  tmp.setGracefulCleanup();
17
18
  export const cliSetup = async () => {
18
19
  //TODO jakis ładny komuniakt błedu
@@ -24,6 +25,8 @@ export const cliSetup = async () => {
24
25
  HTTPRequesterInitializer,
25
26
  CliDataDirectoryInitializer,
26
27
  ExecutionContextInitializer,
28
+ CliVersionInitializer,
29
+ LoggerInitializer,
27
30
  CliAuthTokensInitializer,
28
31
  CliAuthInitializer,
29
32
  ...getCommandBaseInitializers()
@@ -35,10 +38,9 @@ export const cliSetup = async () => {
35
38
  });
36
39
  };
37
40
  const getCommandBaseInitializers = () => {
38
- // console.log('process.argv', process.argv);
39
41
  if (isCommandsTopic(process.argv[2]))
40
42
  return getCommandWithTopicBaseInitializers();
41
- return getCommandWithoutTopicBaseInitializers();
43
+ return [];
42
44
  };
43
45
  const isCommandsTopic = (arg) => {
44
46
  return arg === THEME_TOPIC_NAME || arg === CLI_AUTH_TOPIC_NAME;
@@ -61,13 +63,3 @@ const getCommandWithTopicBaseInitializers = () => {
61
63
  }
62
64
  return [];
63
65
  };
64
- const getCommandWithoutTopicBaseInitializers = () => {
65
- const command = process.argv[2];
66
- switch (command) {
67
- case CLI_COMMANDS_NAMES.version:
68
- case CLI_COMMANDS_NAMES.update: {
69
- return [CliVersionInitializer];
70
- }
71
- }
72
- return [];
73
- };
@@ -11,6 +11,7 @@ export class ExecutionContextService {
11
11
  }
12
12
  async _getGlobalExecutionContext() {
13
13
  return {
14
+ command: process.argv,
14
15
  type: EXECUTION_CONTEXTS.global
15
16
  };
16
17
  }
@@ -26,6 +27,7 @@ export class ExecutionContextService {
26
27
  throw 'Theme root directory not found';
27
28
  const themeMetaData = await ThemeMetaDataUtils.getThemeMetadata(themeRoot);
28
29
  return {
30
+ command: process.argv,
29
31
  type: EXECUTION_CONTEXTS.theme,
30
32
  themeId: themeMetaData.themeId,
31
33
  executionDir: process.cwd(),
@@ -11,14 +11,14 @@ export class CliVersionService {
11
11
  });
12
12
  }
13
13
  getGloballyInstalledVersion() {
14
- return new Promise((resolve) => {
14
+ return new Promise((resolve, reject) => {
15
15
  exec(`npm list -g ${CLI_NAME} --depth=0 --json`, (_, stdout) => {
16
16
  try {
17
17
  const versionInfo = JSON.parse(stdout);
18
18
  resolve(versionInfo.dependencies?.[CLI_NAME]?.version);
19
19
  }
20
20
  catch {
21
- resolve(undefined);
21
+ reject('Failed to parse version information');
22
22
  }
23
23
  });
24
24
  });
@@ -1,16 +1,23 @@
1
1
  import { COMMANDS_THAT_REQUIRE_AUTHORIZATION } from './ensure_authorization_hook_constants.js';
2
- import { useApi } from '../ensure_cli_initialized_hook.js';
3
2
  import { CLI_AUTH_API_NAME } from '../../auth/cli_auth_constants.js';
4
3
  import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
5
4
  import { promptForToken } from '../../commands/utils/prompt_for_token_utils.js';
6
5
  import { CliAuthUtils } from '../../auth/cli_auth_utils.js';
6
+ import { LOGGER_API_NAME } from '../../utilities/features/logger/logger_constants.js';
7
+ import { useApi } from '../../../utils/use_api.js';
7
8
  const ensureAuthorizationHook = async ({ Command }) => {
8
- if (!COMMANDS_THAT_REQUIRE_AUTHORIZATION.includes(Command.id))
9
+ const loggerApi = useApi(LOGGER_API_NAME);
10
+ if (!COMMANDS_THAT_REQUIRE_AUTHORIZATION.includes(Command.id)) {
11
+ loggerApi.debug('Skipping authorization check for command.', { details: { commandId: Command.id } });
9
12
  return;
13
+ }
14
+ loggerApi.info('Ensuring user is authorized for command.', { details: { commandId: Command.id } });
10
15
  const cliAuthApi = useApi(CLI_AUTH_API_NAME);
11
16
  const cliAuthTokensApi = useApi(CLI_AUTH_TOKENS_API_NAME);
12
17
  while (!CliAuthUtils.checkCredentials(cliAuthApi, Command)) {
18
+ loggerApi.info('User is not authorized. Prompting for token.');
13
19
  await promptForToken(cliAuthTokensApi);
14
20
  }
21
+ loggerApi.info('User is authorized.');
15
22
  };
16
23
  export default ensureAuthorizationHook;
@@ -1,10 +1,5 @@
1
- import { API_RESOLVER_QUERIES, getStarCoreEnvironment, QueryMessage } from '@dreamcommerce/star_core';
2
1
  import { CLI_DATA_DIRECTORY_API_NAME } from '../features/data_directory/cli_data_directory_constants.js'; //TODO move to star_core
3
- //TODO move to star_core
4
- export function useApi(apiName) {
5
- const { queryBus } = getStarCoreEnvironment();
6
- return queryBus.executeSync(new QueryMessage(API_RESOLVER_QUERIES.getApiSync, apiName));
7
- }
2
+ import { useApi } from '../../utils/use_api.js';
8
3
  const ensureCliInitializedHook = async () => {
9
4
  const projectApi = useApi(CLI_DATA_DIRECTORY_API_NAME);
10
5
  await projectApi.ensureDataDirectory();
@@ -0,0 +1,7 @@
1
+ import { LOGGER_API_NAME } from '../utilities/features/logger/logger_constants.js';
2
+ import { useApi } from '../../utils/use_api.js';
3
+ const ensureLogsFlushed = async () => {
4
+ const loggerApi = useApi(LOGGER_API_NAME);
5
+ await loggerApi.flush();
6
+ };
7
+ export default ensureLogsFlushed;
@@ -1,7 +1,7 @@
1
1
  import axios from 'axios';
2
2
  import { FeatureCore } from '@dreamcommerce/star_core';
3
- import { CLI_AUTH_API_NAME } from '../../auth/cli_auth_constants.js';
4
- import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
3
+ import { CLI_AUTH_API_NAME } from '../../../auth/cli_auth_constants.js';
4
+ import { CLI_AUTH_TOKENS_API_NAME } from '../../../auth/tokens/cli_auth_tokens_constants.js';
5
5
  export class HttpClient extends FeatureCore {
6
6
  #axios;
7
7
  constructor() {
@@ -1,6 +1,6 @@
1
1
  import { CACHE_TYPES, CacheService, DEFAULT_REQUESTER_CACHE_NAMESPACE, FEATURE_CORES_TYPES, HTTP_REQUESTER_FEATURE_NAME, HTTPRequesterApi, HTTPRequesterBalancer, REQUEST_SOURCE, Requester, RequesterCacheServiceKeySerializer, SANITIZER_API_NAME, StrategiesContainer, SyncFeatureInitializer } from '@dreamcommerce/star_core';
2
2
  import { HttpClient } from './http_client.js';
3
- import { CacheFactory } from '../../class/caches/cache_factory.js';
3
+ import { CacheFactory } from '../../../class/caches/cache_factory.js';
4
4
  export class HTTPRequesterInitializer extends SyncFeatureInitializer {
5
5
  static featureName = HTTP_REQUESTER_FEATURE_NAME;
6
6
  init() {
@@ -0,0 +1,28 @@
1
+ import { FeatureApi } from '@dreamcommerce/star_core';
2
+ import { LOGGER_API_NAME } from '../logger_constants.js';
3
+ export class LoggerApi extends FeatureApi {
4
+ moduleName = LOGGER_API_NAME;
5
+ #service;
6
+ constructor(loggerService) {
7
+ super();
8
+ this.#service = loggerService;
9
+ }
10
+ debug(message, props) {
11
+ this.#service.debug(message, props);
12
+ }
13
+ info(message, props) {
14
+ this.#service.info(message, props);
15
+ }
16
+ warn(message, props) {
17
+ this.#service.warn(message, props);
18
+ }
19
+ error(message, props) {
20
+ this.#service.error(message, props);
21
+ }
22
+ fatal(message, props) {
23
+ this.#service.fatal(message, props);
24
+ }
25
+ async flush() {
26
+ await this.#service.flush();
27
+ }
28
+ }
@@ -0,0 +1,7 @@
1
+ export const LOGGER_FEATURE_NAME = 'LoggerFeature';
2
+ export const LOGGER_API_NAME = 'LoggerApi';
3
+ export const LOGGER_DEBUG_MODES = {
4
+ none: 'none',
5
+ standard: 'standard',
6
+ detailed: 'detailed'
7
+ };