@shoper/cli 0.1.0-8 → 0.2.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 (170) hide show
  1. package/build/cli/auth/cli_auth_errors_factory.js +1 -1
  2. package/build/cli/auth/tokens/cli_auth_tokens_errors_factory.js +1 -1
  3. package/build/cli/auth/tokens/cli_auth_tokens_initalizer.js +1 -1
  4. package/build/cli/class/errors/file_system_errors_factory.js +1 -1
  5. package/build/cli/class/errors/http/http_errors_constants.js +1 -0
  6. package/build/cli/class/errors/{http_errors_factory.js → http/http_errors_factory.js} +3 -2
  7. package/build/cli/commands/auth/cli_auth_add_token_command.js +22 -19
  8. package/build/cli/commands/auth/cli_auth_commands_constants.js +3 -0
  9. package/build/cli/commands/auth/cli_auth_commands_utils.js +46 -0
  10. package/build/cli/commands/auth/cli_auth_list_tokens_command.js +19 -6
  11. package/build/cli/commands/auth/cli_auth_remove_token_command.js +36 -10
  12. package/build/cli/commands/auth/cli_auth_switch_token_command.js +19 -9
  13. package/build/cli/commands/auth/ui/invalid_token_index_error.js +11 -0
  14. package/build/cli/commands/auth/ui/missing_credentials_error.js +9 -0
  15. package/build/cli/commands/auth/ui/missing_token_index_error.js +19 -0
  16. package/build/cli/commands/cli_ui_dump_command.js +11 -0
  17. package/build/cli/commands/cli_update_command.js +13 -4
  18. package/build/cli/commands/commands_constants.js +2 -1
  19. package/build/cli/core/cli_setup.js +5 -1
  20. package/build/cli/features/controls/controls_constants.js +12 -0
  21. package/build/cli/features/controls/controls_dto_mappers.js +55 -0
  22. package/build/cli/features/controls/ui/controls_mappers.js +62 -0
  23. package/build/cli/features/controls/ui/form.js +4 -0
  24. package/build/cli/features/controls/ui/form_constants.js +7 -0
  25. package/build/cli/features/controls/validators/greater_eq_than_validator.js +5 -0
  26. package/build/cli/features/controls/validators/length_validator.js +6 -0
  27. package/build/cli/features/controls/validators/required_validator.js +5 -0
  28. package/build/cli/features/controls/validators/validator_constants.js +13 -0
  29. package/build/cli/features/execution_context/execution_context_service.js +5 -5
  30. package/build/cli/features/http_requester/http_requester_initializer.js +1 -1
  31. package/build/cli/hooks/authorization/ensure_authorization_hook.js +2 -2
  32. package/build/cli/hooks/authorization/ensure_authorization_hook_constants.js +8 -8
  33. package/build/index.js +37 -19
  34. package/build/theme/class/checksums/theme_checksums.js +174 -0
  35. package/build/theme/{features/theme/utils → class}/checksums/theme_checksums_error_factory.js +1 -1
  36. package/build/theme/class/checksums/theme_checksums_utils.js +17 -0
  37. package/build/theme/class/fetch_resources/fetch_resources.js +5 -3
  38. package/build/theme/class/fetch_resources/fetch_resources_errors_factory.js +1 -1
  39. package/build/theme/class/fetch_resources/fetch_resources_utils.js +4 -1
  40. package/build/theme/commands/delete/theme_delete_command.js +111 -0
  41. package/build/theme/commands/delete/ui/theme_deleted_successfully.js +15 -0
  42. package/build/theme/commands/delete/ui/theme_deletion_warning.js +10 -0
  43. package/build/theme/commands/info/theme_info_command.js +94 -0
  44. package/build/theme/commands/info/theme_info_command_utils.js +39 -0
  45. package/build/theme/commands/init/theme_init_command.js +97 -0
  46. package/build/theme/commands/init/ui/theme_created_success.js +15 -0
  47. package/build/theme/commands/list/theme_list_command.js +25 -0
  48. package/build/theme/commands/list/theme_list_command_utils.js +27 -0
  49. package/build/theme/commands/publish/theme_publish_command.js +92 -0
  50. package/build/theme/commands/pull/theme_pull_command.js +194 -0
  51. package/build/theme/commands/pull/ui/theme_pull_id_mismatch_error.js +7 -0
  52. package/build/theme/commands/pull/ui/theme_pull_unpublished_changes_warning.js +10 -0
  53. package/build/theme/commands/pull/ui/theme_pulled_success.js +5 -0
  54. package/build/theme/commands/push/theme_push_command.js +134 -0
  55. package/build/theme/commands/push/ui/theme_push_skip_into.js +7 -0
  56. package/build/theme/commands/push/ui/theme_pushed_success.js +5 -0
  57. package/build/theme/commands/push/ui/theme_unpermitted_actions_error.js +12 -0
  58. package/build/theme/commands/theme_commands_constants.js +4 -1
  59. package/build/theme/commands/theme_show_changes_command.js +1 -0
  60. package/build/theme/commands/theme_verify_command.js +8 -7
  61. package/build/theme/commands/ui/invalid_theme_id.js +11 -0
  62. package/build/theme/commands/ui/missing_theme_files.js +15 -0
  63. package/build/theme/commands/ui/missing_theme_id_error.js +13 -0
  64. package/build/theme/commands/ui/ouside_of_theme_directory_context_error.js +7 -0
  65. package/build/theme/commands/ui/theme_directory_context_error.js +7 -0
  66. package/build/theme/commands/ui/theme_work_url_mismatch.js +17 -0
  67. package/build/theme/commands/ui/unpermitted_command_error.js +18 -0
  68. package/build/theme/features/theme/actions/api/theme_actions_api.js +3 -0
  69. package/build/theme/features/theme/actions/service/theme_actions_service.js +15 -3
  70. package/build/theme/features/theme/actions/service/theme_actions_service_constants.js +1 -0
  71. package/build/theme/features/theme/actions/theme_actions_constants.js +3 -1
  72. package/build/theme/features/theme/actions/theme_actions_initializer.js +1 -1
  73. package/build/theme/features/theme/actions/theme_actions_utils.js +20 -7
  74. package/build/theme/features/theme/delete/api/theme_delete_api.js +13 -0
  75. package/build/theme/features/theme/delete/http/theme_delete_http_api.js +17 -0
  76. package/build/theme/features/theme/delete/service/theme_delete_service.js +31 -0
  77. package/build/theme/features/theme/delete/theme_delete_constants.js +2 -0
  78. package/build/theme/features/theme/delete/theme_delete_initalizer.js +20 -0
  79. package/build/theme/features/theme/fetch/service/theme_fetch_service.js +30 -10
  80. package/build/theme/features/theme/info/theme_info_utils.js +9 -0
  81. package/build/theme/features/theme/init/service/theme_init_service.js +9 -4
  82. package/build/theme/features/theme/merge/api/theme_merge_api.js +0 -12
  83. package/build/theme/features/theme/merge/service/theme_merge_service.js +20 -28
  84. package/build/theme/features/theme/push/service/theme_push_service.js +102 -73
  85. package/build/theme/features/theme/push/theme_push_constants.js +2 -0
  86. package/build/theme/features/theme/push/theme_push_errors_factory.js +7 -4
  87. package/build/theme/features/theme/push/theme_push_initializer.js +0 -3
  88. package/build/theme/features/theme/push/theme_push_utils.js +25 -0
  89. package/build/theme/features/theme/skinstore/api/theme_skinstore_api.js +19 -0
  90. package/build/theme/features/theme/skinstore/http/theme_skinstore_http_api.js +17 -0
  91. package/build/theme/features/theme/skinstore/service/theme_skinstore_service.js +32 -0
  92. package/build/theme/features/theme/skinstore/theme_publish_constants.js +4 -0
  93. package/build/theme/features/theme/skinstore/theme_skinstore_initialzier.js +20 -0
  94. package/build/theme/features/theme/utils/files_structure/theme_files_structure_utils.js +40 -0
  95. package/build/theme/features/theme/utils/hidden_directory/hidden_directory_utils.js +32 -0
  96. package/build/theme/features/theme/utils/meta_data/theme_meta_data_constants.js +1 -0
  97. package/build/theme/features/theme/utils/meta_data/theme_meta_data_error_factory.js +15 -0
  98. package/build/theme/features/theme/utils/meta_data/theme_meta_data_utils.js +39 -0
  99. package/build/theme/features/theme/utils/{directories → resources}/theme_resources_with_id_directory_utils.js +3 -14
  100. package/build/theme/features/theme/utils/theme_images_utils.js +5 -6
  101. package/build/theme/features/themes/list/api/themes_list_api.js +3 -0
  102. package/build/theme/features/themes/list/services/themes_list_service.js +13 -7
  103. package/build/theme/hooks/{ensure_theme_meta_data_untouched.js → ensure_theme_meta_data_untouched_hook.js} +2 -2
  104. package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_constants.js +1 -1
  105. package/build/theme/hooks/theme_checksums/{ensure_theme_current_checksums_up_to_date.js → ensure_theme_current_checksums_up_to_date_hook.js} +2 -5
  106. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook.js +1 -0
  107. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +1 -0
  108. package/build/theme/index.js +11 -5
  109. package/build/theme/utils/directory_validator/directory_validator_constants.js +2 -6
  110. package/build/theme/utils/directory_validator/directory_validator_utils.js +18 -38
  111. package/build/ui/box.js +2 -0
  112. package/build/ui/color_constants.js +30 -0
  113. package/build/ui/command.js +6 -0
  114. package/build/ui/file_name.js +6 -0
  115. package/build/ui/flag.js +6 -0
  116. package/build/ui/icons/error_icon.js +7 -0
  117. package/build/ui/icons/info_icon.js +7 -0
  118. package/build/ui/icons/success_icon.js +7 -0
  119. package/build/ui/icons/warning_icon.js +7 -0
  120. package/build/ui/link.js +8 -0
  121. package/build/ui/list/list.js +10 -0
  122. package/build/ui/list/list_constants.js +4 -0
  123. package/build/ui/list/list_item.js +11 -0
  124. package/build/ui/message_box/error.js +4 -0
  125. package/build/ui/message_box/info.js +4 -0
  126. package/build/ui/message_box/message_box.js +11 -0
  127. package/build/ui/message_box/message_box_constants.js +24 -0
  128. package/build/ui/message_box/success.js +4 -0
  129. package/build/ui/message_box/warning.js +4 -0
  130. package/build/ui/prompts/prompt_confirmation.js +11 -0
  131. package/build/ui/prompts/prompt_input.js +10 -0
  132. package/build/ui/table/t_cell.js +7 -0
  133. package/build/ui/table/t_header.js +9 -0
  134. package/build/ui/table/t_row.js +5 -0
  135. package/build/ui/table/table.js +18 -0
  136. package/build/ui/text.js +2 -0
  137. package/build/ui/tip.js +9 -0
  138. package/build/ui/ui_dump/ui_component_box.js +9 -0
  139. package/build/ui/ui_dump/ui_dump.js +53 -0
  140. package/build/ui/ui_dump/ui_dump_constants.js +21 -0
  141. package/build/ui/ui_utils.js +11 -0
  142. package/build/ui/validation_errors/validation_error_content.js +19 -0
  143. package/build/ui/validation_errors/validation_errors.js +21 -0
  144. package/build/ui/validation_errors/validation_errors_utils.js +17 -0
  145. package/build/utils/checksums/checksums_utils.js +9 -26
  146. package/build/utils/download_file/download_file_errors_factory.js +1 -1
  147. package/build/utils/download_file/download_file_utils.js +4 -2
  148. package/build/utils/fs/errors/stream_read_error.js +1 -1
  149. package/build/utils/fs/errors/stream_write_error.js +1 -1
  150. package/build/utils/fs/fs_utils.js +17 -3
  151. package/build/utils/path_utils.js +20 -1
  152. package/build/utils/platform_utils.js +3 -0
  153. package/build/utils/zip/create_zip_utils.js +1 -1
  154. package/build/utils/zip/errors/create_zip_error.js +1 -1
  155. package/build/utils/zip/errors/open_zip_error.js +1 -1
  156. package/oclif.config.js +2 -2
  157. package/package.json +15 -8
  158. package/build/theme/commands/theme_init_command.js +0 -53
  159. package/build/theme/commands/theme_list_command.js +0 -16
  160. package/build/theme/commands/theme_pull_command.js +0 -124
  161. package/build/theme/commands/theme_push_command.js +0 -65
  162. package/build/theme/features/theme/directory/theme_directory_utils.js +0 -76
  163. package/build/theme/features/theme/publish/theme_publish_constants.js +0 -2
  164. package/build/theme/features/theme/utils/checksums/theme_checksums_utils.js +0 -94
  165. /package/build/cli/{features → class}/caches/cache_factory.js +0 -0
  166. /package/build/cli/{features → class}/caches/json_cache/json_cache.js +0 -0
  167. /package/build/cli/{features → class}/caches/memory_cache.js +0 -0
  168. /package/build/cli/class/errors/{app_error → app}/app_error.js +0 -0
  169. /package/build/cli/class/errors/{app_error → app}/app_error_constants.js +0 -0
  170. /package/build/theme/features/theme/{publish → skinstore}/theme_publish_utils.js +0 -0
@@ -1,4 +1,4 @@
1
- import { AppError } from '../class/errors/app_error/app_error.js';
1
+ import { AppError } from '../class/errors/app/app_error.js';
2
2
  export class CliAuthErrorsFactory {
3
3
  static createCredentialNotFoundError() {
4
4
  return new AppError({
@@ -1,4 +1,4 @@
1
- import { AppError } from '../../class/errors/app_error/app_error.js';
1
+ import { AppError } from '../../class/errors/app/app_error.js';
2
2
  export class CliAuthTokensErrorsFactory {
3
3
  static createTokenNotFoundError(index) {
4
4
  return new AppError({
@@ -3,7 +3,7 @@ import { CliAuthTokensApi } from './api/cli_auth_tokens_api.js';
3
3
  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
- import { JsonCache } from '../../features/caches/json_cache/json_cache.js';
6
+ import { JsonCache } from '../../class/caches/json_cache/json_cache.js';
7
7
  // schema
8
8
  // {
9
9
  // default: string;
@@ -1,4 +1,4 @@
1
- import { AppError } from './app_error/app_error.js';
1
+ import { AppError } from './app/app_error.js';
2
2
  export class FileSystemErrorsFactory {
3
3
  static createDiskFullError() {
4
4
  return new AppError({
@@ -0,0 +1 @@
1
+ export const HTTP_NOT_FOUND_ERROR_CODE = 'not_found';
@@ -1,4 +1,5 @@
1
- import { AppError } from './app_error/app_error.js';
1
+ import { AppError } from '../app/app_error.js';
2
+ import { HTTP_NOT_FOUND_ERROR_CODE } from './http_errors_constants.js';
2
3
  export class HttpErrorsFactory {
3
4
  static createUnauthorizedError() {
4
5
  return new AppError({
@@ -15,7 +16,7 @@ export class HttpErrorsFactory {
15
16
  static createNotFoundError() {
16
17
  return new AppError({
17
18
  message: 'Not found',
18
- code: 'not_found'
19
+ code: HTTP_NOT_FOUND_ERROR_CODE
19
20
  });
20
21
  }
21
22
  }
@@ -1,32 +1,35 @@
1
1
  import { BaseCliCommand } from '../../class/base_cli_command.js';
2
2
  import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
3
- import inquirer from 'inquirer';
3
+ import { promptInput } from '../../../ui/prompts/prompt_input.js';
4
+ import { renderOnce } from '../../../ui/ui_utils.js';
5
+ import { Success } from '../../../ui/message_box/success.js';
6
+ import { Text } from '../../../ui/text.js';
7
+ import { Box } from '../../../ui/box.js';
8
+ import { Command } from '../../../ui/command.js';
9
+ import React from 'react';
10
+ import { Error } from '../../../ui/message_box/error.js';
4
11
  export class CliAuthAddTokenCommand extends BaseCliCommand {
5
- static description = 'Add token';
6
- //TODO
7
- static examples = [
8
- {
9
- description: 'Add token.',
10
- command: '<%= config.bin %> <%= command.id %>'
11
- }
12
- ];
12
+ static summary = 'Adds a new authentication token and saves it locally.';
13
+ 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
+ static examples = ['<%= config.bin %> <%= command.id %>'];
13
15
  async run() {
14
16
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
15
- const { token } = await inquirer.prompt([
16
- {
17
- type: 'input',
18
- name: 'token',
19
- message: 'Enter token:'
20
- }
21
- ]);
22
17
  try {
18
+ const { input: token } = await promptInput('Please paste your CLI token:');
23
19
  cliAuthTokensApi.addToken(token);
24
20
  cliAuthTokensApi.setDefaultToken(cliAuthTokensApi.getTokensCount());
25
- console.log('Token added successfully');
21
+ renderOnce(React.createElement(Success, null,
22
+ React.createElement(Text, null, "Token saved locally and set as your default. You can now authenticate using this token."),
23
+ React.createElement(Box, null,
24
+ React.createElement(Text, null,
25
+ "Run ",
26
+ React.createElement(Command, null, "shoper auth list-tokens"),
27
+ " to view your saved tokens."))));
26
28
  }
27
29
  catch (err) {
28
- //TODO handle error
29
- this.error(`${err}`);
30
+ renderOnce(React.createElement(Error, { header: "Error: Failed to add token: " },
31
+ React.createElement(Box, null,
32
+ React.createElement(Text, null, err.toString()))));
30
33
  }
31
34
  }
32
35
  }
@@ -0,0 +1,3 @@
1
+ export const TOKEN_SCOPE_TO_DESCRIPTION = {
2
+ theme: 'Edit store themes'
3
+ };
@@ -0,0 +1,46 @@
1
+ import { Text } from '../../../ui/text.js';
2
+ import { TOKEN_SCOPE_TO_DESCRIPTION } from './cli_auth_commands_constants.js';
3
+ import { CSS_BACKGROUND_COLORS, CSS_TEXT_COLORS } from '../../../ui/color_constants.js';
4
+ import { DateUtils } from '@dreamcommerce/utilities';
5
+ import React from 'react';
6
+ export class CliAuthCommandsUtils {
7
+ static mapToTableData(data, defaultIndex, tokensApi) {
8
+ return {
9
+ headers: [
10
+ {
11
+ content: 'Index',
12
+ width: 10
13
+ },
14
+ {
15
+ content: 'Token Name',
16
+ width: 40
17
+ },
18
+ {
19
+ content: 'Store',
20
+ width: 40
21
+ },
22
+ {
23
+ content: 'Access Scope',
24
+ width: 20
25
+ },
26
+ {
27
+ content: 'Valid until',
28
+ width: 20
29
+ }
30
+ ],
31
+ rows: data.map((tokenData, index) => {
32
+ const tokenIndex = index + 1;
33
+ const isDefault = defaultIndex !== null && tokenIndex === defaultIndex;
34
+ const tokenName = isDefault ? React.createElement(Text, { bold: true }, `${tokenData.name} (Default)`) : tokenData.name;
35
+ const hasExpired = tokensApi.hasTokenExpired(tokenIndex);
36
+ return [
37
+ React.createElement(Text, { bold: isDefault }, tokenIndex),
38
+ tokenName,
39
+ React.createElement(Text, { bold: isDefault }, tokenData.iss),
40
+ TOKEN_SCOPE_TO_DESCRIPTION[tokenData.scope],
41
+ React.createElement(Text, { color: hasExpired ? CSS_TEXT_COLORS.invert : undefined, backgroundColor: hasExpired ? CSS_BACKGROUND_COLORS.danger : undefined }, DateUtils.toLocaleDate(new Date(tokenData.exp * 1000), 'pl-PL'))
42
+ ];
43
+ })
44
+ };
45
+ }
46
+ }
@@ -1,17 +1,30 @@
1
1
  import { BaseCliCommand } from '../../class/base_cli_command.js';
2
2
  import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
3
+ import React from 'react';
4
+ import { CliAuthCommandsUtils } from './cli_auth_commands_utils.js';
5
+ import { Table } from '../../../ui/table/table.js';
6
+ import { render } from '../../../ui/ui_utils.js';
7
+ import { Box } from '../../../ui/box.js';
8
+ import { Tip } from '../../../ui/tip.js';
9
+ import { Command } from '../../../ui/command.js';
10
+ import { Text } from '../../../ui/text.js';
11
+ import { Info } from '../../../ui/message_box/info.js';
3
12
  export class CliAuthListTokensCommand extends BaseCliCommand {
4
- static description = 'List all added tokens';
5
- static examples = [`$ cli token:list`];
13
+ static summary = 'Displays a list of all authentication tokens stored locally.';
14
+ 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
+ static examples = ['<%= config.bin %> <%= command.id %>'];
6
16
  async run() {
7
17
  const tokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
8
18
  const tokensPayloads = tokensApi.getAllTokensPayloads();
9
19
  if (!tokensPayloads.length) {
10
- this.log('No tokens found');
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"))));
11
26
  return;
12
27
  }
13
- tokensPayloads.forEach((tokenPayload) => {
14
- this.log(`Token name: ${tokenPayload.name}, storeUrl: ${tokenPayload.iss}`);
15
- });
28
+ await render(React.createElement(Table, { data: CliAuthCommandsUtils.mapToTableData(tokensPayloads, tokensApi.getDefaultTokenIndex(), tokensApi) }));
16
29
  }
17
30
  }
@@ -1,9 +1,21 @@
1
1
  import { BaseCliCommand } from '../../class/base_cli_command.js';
2
2
  import { Args } from '@oclif/core';
3
3
  import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
4
+ import { renderOnce } from '../../../ui/ui_utils.js';
5
+ import { MissingTokenIndexError } from './ui/missing_token_index_error.js';
6
+ import { InvalidTokenIndexError } from './ui/invalid_token_index_error.js';
7
+ import React from 'react';
8
+ import { Text } from '../../../ui/text.js';
9
+ import { Command } from '../../../ui/command.js';
10
+ import { Box } from '../../../ui/box.js';
11
+ import { promptConfirmation } from '../../../ui/prompts/prompt_confirmation.js';
12
+ import { Info } from '../../../ui/message_box/info.js';
13
+ import { Success } from '../../../ui/message_box/success.js';
14
+ import { Warning } from '../../../ui/message_box/warning.js';
15
+ import { Error } from '../../../ui/message_box/error.js';
4
16
  export class CliAuthRemoveTokenCommand extends BaseCliCommand {
5
- static summary = 'Remove the access token';
6
- static description = 'Remove the access token with the provided index.';
17
+ static summary = 'Removes a locally saved authentication token.';
18
+ static description = 'Use this to clean up tokens you no longer need.';
7
19
  static examples = [
8
20
  {
9
21
  description: 'Remove token with index 2',
@@ -13,7 +25,7 @@ export class CliAuthRemoveTokenCommand extends BaseCliCommand {
13
25
  static args = {
14
26
  index: Args.integer({
15
27
  description: 'Index of the token to remove',
16
- required: true
28
+ required: false
17
29
  })
18
30
  };
19
31
  async run() {
@@ -21,17 +33,31 @@ export class CliAuthRemoveTokenCommand extends BaseCliCommand {
21
33
  const data = await this.parse(CliAuthRemoveTokenCommand);
22
34
  const { args } = data;
23
35
  const { index } = args;
24
- if (!cliAuthTokensApi.hasToken(index)) {
25
- this.log(`Token with index "${index}" does not exist.`);
36
+ if (!index || !cliAuthTokensApi.hasToken(index)) {
37
+ renderOnce(React.createElement(MissingTokenIndexError, { command: React.createElement(Command, null, "shoper auth remove-token [TOKEN_INDEX]") }));
38
+ return;
39
+ }
40
+ const token = cliAuthTokensApi.getTokenPayload(index);
41
+ if (!token) {
42
+ renderOnce(React.createElement(InvalidTokenIndexError, null));
26
43
  return;
27
44
  }
28
45
  try {
29
- cliAuthTokensApi.removeToken(index);
30
- cliAuthTokensApi.setDefaultToken(cliAuthTokensApi.getTokensCount());
31
- this.log(`Access token ${index} removed successfully.`);
46
+ renderOnce(React.createElement(Warning, { header: `Warning: This will permanently delete the token "${token.name}" assigned to "${token.iss}". This action cannot be undone.` }));
47
+ const { proceed } = await promptConfirmation('Proceed?');
48
+ if (proceed) {
49
+ cliAuthTokensApi.removeToken(index);
50
+ cliAuthTokensApi.setDefaultToken(cliAuthTokensApi.getTokensCount());
51
+ renderOnce(React.createElement(Success, { header: `Success: Token "${token.name}" has been removed.` }));
52
+ return;
53
+ }
54
+ renderOnce(React.createElement(Info, null,
55
+ React.createElement(Text, null, "Token removal was cancelled.")));
32
56
  }
33
- catch {
34
- this.error('Failed to remove the access token. Please try again later.');
57
+ catch (err) {
58
+ renderOnce(React.createElement(Error, { header: "Error: Failed to remove token: " },
59
+ React.createElement(Box, null,
60
+ React.createElement(Text, null, err.toString()))));
35
61
  }
36
62
  }
37
63
  }
@@ -1,36 +1,46 @@
1
1
  import { BaseCliCommand } from '../../class/base_cli_command.js';
2
2
  import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
3
+ import { renderOnce } from '../../../ui/ui_utils.js';
4
+ import React from 'react';
5
+ import { Text } from '../../../ui/text.js';
6
+ import { Box } from '../../../ui/box.js';
3
7
  import { Args } from '@oclif/core';
8
+ import { MissingTokenIndexError } from './ui/missing_token_index_error.js';
9
+ import { Command } from '../../../ui/command.js';
10
+ import { Error } from '../../../ui/message_box/error.js';
11
+ import { Success } from '../../../ui/message_box/success.js';
4
12
  export class CliAuthSwitchTokenCommand extends BaseCliCommand {
5
- static description = 'Set token with provided index as default';
6
- //TODO
13
+ static summary = 'Changes the active authentication token used by the CLI.';
14
+ static description = 'Use this to switch between multiple saved tokens when working with different stores.';
7
15
  static examples = [
8
16
  {
9
- description: 'Set token 2 as default.',
17
+ description: 'Set token with index "2" as default.',
10
18
  command: '<%= config.bin %> <%= command.id %> 2'
11
19
  }
12
20
  ];
13
21
  static args = {
14
22
  index: Args.integer({
15
23
  description: 'Index of the token to set as default',
16
- required: true
24
+ required: false
17
25
  })
18
26
  };
19
27
  async run() {
20
28
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
21
29
  const { args } = await this.parse(CliAuthSwitchTokenCommand);
22
30
  const { index } = args;
23
- if (!cliAuthTokensApi.hasToken(index)) {
24
- this.log(`Token with index "${index}" does not exist.`);
31
+ if (!index || !cliAuthTokensApi.hasToken(index)) {
32
+ renderOnce(React.createElement(MissingTokenIndexError, { command: React.createElement(Command, null, "shoper auth switch-token [TOKEN_INDEX]") }));
25
33
  return;
26
34
  }
27
35
  try {
28
36
  cliAuthTokensApi.setDefaultToken(index);
37
+ const defaultToken = cliAuthTokensApi.getDefaultTokenPayload();
38
+ renderOnce(React.createElement(Success, { header: `Success: Token "${defaultToken?.name}" assigned to "${defaultToken?.iss}" is now active` }));
29
39
  }
30
40
  catch (err) {
31
- //TODO
32
- this.log(`Error: ${err}`);
33
- return;
41
+ renderOnce(React.createElement(Error, { header: "Error: Failed to switch token: " },
42
+ React.createElement(Box, null,
43
+ React.createElement(Text, null, err.toString()))));
34
44
  }
35
45
  }
36
46
  }
@@ -0,0 +1,11 @@
1
+ import { Tip } from '../../../../ui/tip.js';
2
+ import { Command } from '../../../../ui/command.js';
3
+ import React from 'react';
4
+ import { Error } from '../../../../ui/message_box/error.js';
5
+ export const InvalidTokenIndexError = () => {
6
+ return (React.createElement(Error, { header: "Error: Invalid token index." },
7
+ React.createElement(Tip, null,
8
+ "Run ",
9
+ React.createElement(Command, null, "shoper auth list-tokens"),
10
+ " to see available token index values.")));
11
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { Box } from '../../../../ui/box.js';
3
+ import { Text } from '../../../../ui/text.js';
4
+ import { Error } from '../../../../ui/message_box/error.js';
5
+ export const MissingCredentialsError = () => {
6
+ return (React.createElement(Error, { header: "Error: Credentials not found." },
7
+ React.createElement(Box, null,
8
+ React.createElement(Text, null, "Please authorize first."))));
9
+ };
@@ -0,0 +1,19 @@
1
+ import { Box } from '../../../../ui/box.js';
2
+ import { Text } from '../../../../ui/text.js';
3
+ import { Newline } from 'ink';
4
+ import { Command } from '../../../../ui/command.js';
5
+ import { Tip } from '../../../../ui/tip.js';
6
+ import React from 'react';
7
+ import { Error } from '../../../../ui/message_box/error.js';
8
+ export const MissingTokenIndexError = ({ command }) => {
9
+ return (React.createElement(Error, { header: "Error: Missing token index." },
10
+ React.createElement(Box, null,
11
+ React.createElement(Text, null,
12
+ "Usage:",
13
+ React.createElement(Newline, null),
14
+ command)),
15
+ React.createElement(Tip, null,
16
+ "Run ",
17
+ React.createElement(Command, null, "shoper auth list-tokens"),
18
+ " to see available token index values.")));
19
+ };
@@ -0,0 +1,11 @@
1
+ import { BaseCliCommand } from '../class/base_cli_command.js';
2
+ import { render } from 'ink';
3
+ import { UiDump } from '../../ui/ui_dump/ui_dump.js';
4
+ import React from 'react';
5
+ export class CliUIDumpCommand extends BaseCliCommand {
6
+ static summary = 'Prints all CLI UI elements';
7
+ static hidden = true;
8
+ async run() {
9
+ render(React.createElement(UiDump, null));
10
+ }
11
+ }
@@ -1,6 +1,9 @@
1
1
  import { CLI_VERSION_API_NAME } from '../features/version/cli_version_constants.js';
2
2
  import { CLI_NAME } from '../cli_constants.js';
3
3
  import { BaseCliCommand } from '../class/base_cli_command.js';
4
+ import { renderOnce } from '../../ui/ui_utils.js';
5
+ import React from 'react';
6
+ import { Error } from '../../ui/message_box/error.js';
4
7
  export class CliUpdateCommand extends BaseCliCommand {
5
8
  static summary = 'Update the Shoper CLI';
6
9
  static description = 'Update the Shoper CLI to the latest version.';
@@ -9,17 +12,23 @@ export class CliUpdateCommand extends BaseCliCommand {
9
12
  const cliVersionApi = this.getApi(CLI_VERSION_API_NAME);
10
13
  try {
11
14
  const installedVersion = await cliVersionApi.getGloballyInstalledVersion();
12
- if (!installedVersion)
13
- this.error(`The Shoper CLI is not installed globally. In order to work with CLI, please install it globally. Use "npm install -g ${CLI_NAME}" to install it.`);
15
+ if (!installedVersion) {
16
+ renderOnce(React.createElement(Error, null,
17
+ "The Shoper CLI is not installed globally. In order to work with CLI, please install it globally. Use \"npm install -g $",
18
+ CLI_NAME,
19
+ "\" to install it."));
20
+ return;
21
+ }
14
22
  const stdout = await cliVersionApi.update();
15
23
  this.log(stdout);
16
24
  }
17
25
  catch (error) {
18
26
  //npm code for EACCES
19
27
  if (error?.code === 243) {
20
- this.error(error);
28
+ renderOnce(React.createElement(Error, { header: error.message }));
29
+ return;
21
30
  }
22
- this.error('Failed to update the CLI. Please try again later.');
31
+ renderOnce(React.createElement(Error, { header: "Error: Failed to update the CLI. Please try again later." }));
23
32
  }
24
33
  }
25
34
  }
@@ -5,5 +5,6 @@ export const CLI_COMMANDS_NAMES = {
5
5
  authListTokens: 'auth:list-tokens',
6
6
  authAddToken: 'auth:add-token',
7
7
  authRemoveToken: 'auth:remove-token',
8
- switchToken: 'auth:switch-token'
8
+ switchToken: 'auth:switch-token',
9
+ uiDump: 'ui-dump'
9
10
  };
@@ -14,6 +14,8 @@ import { ThemeFetchInitializer } from '../../theme/features/theme/fetch/theme_fe
14
14
  import { ThemeMergeInitializer } from '../../theme/features/theme/merge/theme_merge_initializer.js';
15
15
  import { ThemeActionsInitializer } from '../../theme/features/theme/actions/theme_actions_initializer.js';
16
16
  import { ThemePushInitializer } from '../../theme/features/theme/push/theme_push_initializer.js';
17
+ import { ThemeDeleteInitializer } from '../../theme/features/theme/delete/theme_delete_initalizer.js';
18
+ import { ThemeSkinstoreInitializer } from '../../theme/features/theme/skinstore/theme_skinstore_initialzier.js';
17
19
  tmp.setGracefulCleanup();
18
20
  export const cliSetup = async () => {
19
21
  //TODO jakis ładny komuniakt błedu
@@ -34,7 +36,9 @@ export const cliSetup = async () => {
34
36
  ThemeInitInitializer,
35
37
  ThemeMergeInitializer,
36
38
  ThemeFetchInitializer,
37
- ThemePushInitializer
39
+ ThemePushInitializer,
40
+ ThemeDeleteInitializer,
41
+ ThemeSkinstoreInitializer
38
42
  ],
39
43
  options: {
40
44
  featuresTracking: false,
@@ -0,0 +1,12 @@
1
+ export const CONTROLS_DTO_TYPES = {
2
+ text: 'text',
3
+ number: 'number',
4
+ select: 'select',
5
+ multiSelectDropDown: 'multiSelectDropDown'
6
+ };
7
+ export const CONTROLS_TYPES = {
8
+ text: 'text',
9
+ number: 'number',
10
+ select: 'select',
11
+ multiSelect: 'multiSelect'
12
+ };
@@ -0,0 +1,55 @@
1
+ import { CONTROLS_DTO_TYPES, CONTROLS_TYPES } from './controls_constants.js';
2
+ export const toTextControl = ({ validators, label, isRequired, defaultValue, name }) => {
3
+ return {
4
+ type: CONTROLS_TYPES.text,
5
+ name,
6
+ label,
7
+ isRequired,
8
+ defaultValue,
9
+ validators
10
+ };
11
+ };
12
+ export const toNumberControl = ({ validators, label, isRequired, name }) => {
13
+ return {
14
+ type: CONTROLS_TYPES.number,
15
+ name,
16
+ label,
17
+ isRequired,
18
+ validators
19
+ };
20
+ };
21
+ export const toSelectControl = ({ label, isRequired, name, options }) => {
22
+ return {
23
+ type: CONTROLS_TYPES.select,
24
+ name,
25
+ label,
26
+ isRequired,
27
+ options: options.selectOptions.map(({ label, key }) => ({ label, value: key }))
28
+ };
29
+ };
30
+ export const toMultiSelectControl = ({ label, isRequired, name, options }) => {
31
+ return {
32
+ type: CONTROLS_TYPES.multiSelect,
33
+ name,
34
+ label,
35
+ isRequired,
36
+ options: options.selectOptions.map(({ label, key }) => ({ label, value: key }))
37
+ };
38
+ };
39
+ export const toControls = (controls) => {
40
+ return controls.map(toControl);
41
+ };
42
+ export const toControl = (control) => {
43
+ switch (control.type) {
44
+ case CONTROLS_DTO_TYPES.text:
45
+ return toTextControl(control);
46
+ case CONTROLS_DTO_TYPES.number:
47
+ return toNumberControl(control);
48
+ case CONTROLS_DTO_TYPES.select:
49
+ return toSelectControl(control);
50
+ case CONTROLS_DTO_TYPES.multiSelectDropDown:
51
+ return toMultiSelectControl(control);
52
+ default:
53
+ throw new Error(`Unknown control type`);
54
+ }
55
+ };
@@ -0,0 +1,62 @@
1
+ import { CONTROLS_TYPES } from '../controls_constants.js';
2
+ const toTextControl = ({ validators, label, isRequired, defaultValue, name }) => {
3
+ return {
4
+ type: 'input',
5
+ name,
6
+ message: isRequired ? `${label} (required)` : label,
7
+ default: defaultValue,
8
+ validate: toInquirerValidate(validators)
9
+ };
10
+ };
11
+ const toNumberControl = ({ validators, label, isRequired, defaultValue, name }) => {
12
+ return {
13
+ type: 'number',
14
+ name,
15
+ message: isRequired ? `${label} (required)` : label,
16
+ default: defaultValue,
17
+ validate: toInquirerValidate(validators)
18
+ };
19
+ };
20
+ const toSelectControl = ({ validators, label, isRequired, defaultValue, name, options }) => {
21
+ return {
22
+ type: 'list',
23
+ name,
24
+ message: isRequired ? `${label} (required)` : label,
25
+ choices: options,
26
+ default: defaultValue,
27
+ validate: toInquirerValidate(validators)
28
+ };
29
+ };
30
+ const toMultiSelectControl = ({ validators, label, isRequired, defaultValue, name, options }) => {
31
+ //TODO multiple checkboxes
32
+ return {
33
+ type: 'checkbox',
34
+ name,
35
+ message: isRequired ? `${label} (required)` : label,
36
+ choices: options,
37
+ default: defaultValue,
38
+ validate: toInquirerValidate(validators)
39
+ };
40
+ };
41
+ export const toInquirerControls = (controls) => {
42
+ return controls.map(toInquirerControl);
43
+ };
44
+ export const toInquirerControl = (control) => {
45
+ switch (control.type) {
46
+ case CONTROLS_TYPES.text:
47
+ return toTextControl(control);
48
+ case CONTROLS_TYPES.number:
49
+ return toNumberControl(control);
50
+ case CONTROLS_TYPES.select:
51
+ return toSelectControl(control);
52
+ case CONTROLS_TYPES.multiSelect:
53
+ return toMultiSelectControl(control);
54
+ default:
55
+ throw new Error(`Unknown control type`);
56
+ }
57
+ };
58
+ export const toInquirerValidate = (validators) => {
59
+ return (value) => {
60
+ return validators?.find((v) => !v.isValid(value))?.getErrorMessage() ?? true;
61
+ };
62
+ };
@@ -0,0 +1,4 @@
1
+ import inquirer from 'inquirer';
2
+ export const Form = ({ controls, onSubmit }) => {
3
+ inquirer.prompt(controls).then(onSubmit);
4
+ };
@@ -0,0 +1,7 @@
1
+ export {};
2
+ // export const CONTROL_TYPE_TO_MAPPERS: Record<TControlType, Function> = {
3
+ // [CONTROLS_TYPES.text]: toTextControl,
4
+ // [CONTROLS_TYPES.number]: toNumberControl,
5
+ // [CONTROLS_TYPES.select]: toSelectControl,
6
+ // [CONTROLS_TYPES.multiSelect]: toMultiSelectControl
7
+ // };
@@ -0,0 +1,5 @@
1
+ export class GreaterEqThanValidator {
2
+ isValid(value, { min }) {
3
+ return value >= min;
4
+ }
5
+ }
@@ -0,0 +1,6 @@
1
+ export class LengthValidator {
2
+ isValid(value, { min, max }) {
3
+ const length = value.length;
4
+ return length >= min && length <= max;
5
+ }
6
+ }
@@ -0,0 +1,5 @@
1
+ export class RequiredValidator {
2
+ isValid(value) {
3
+ return value !== null && value !== undefined && value !== '';
4
+ }
5
+ }
@@ -0,0 +1,13 @@
1
+ import { RequiredValidator } from './required_validator.js';
2
+ import { GreaterEqThanValidator } from './greater_eq_than_validator.js';
3
+ import { LengthValidator } from './length_validator.js';
4
+ export const VALIDATORS_TYPES = {
5
+ required: 'required',
6
+ greaterEqThan: 'greaterEqThan',
7
+ length: 'length'
8
+ };
9
+ export const VALIDATOR_TYPE_TO_VALIDATOR = {
10
+ [VALIDATORS_TYPES.required]: new RequiredValidator(),
11
+ [VALIDATORS_TYPES.greaterEqThan]: new GreaterEqThanValidator(),
12
+ [VALIDATORS_TYPES.length]: new LengthValidator()
13
+ };