@shoper/cli 0.1.0-9 → 0.2.1-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 (184) 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/base_command.js +14 -0
  5. package/build/cli/class/errors/file_system_errors_factory.js +1 -1
  6. package/build/cli/class/errors/http/http_errors_constants.js +1 -0
  7. package/build/cli/class/errors/{http_errors_factory.js → http/http_errors_factory.js} +3 -2
  8. package/build/cli/commands/auth/cli_auth_add_token_command.js +22 -19
  9. package/build/cli/commands/auth/cli_auth_commands_constants.js +3 -0
  10. package/build/cli/commands/auth/cli_auth_commands_utils.js +46 -0
  11. package/build/cli/commands/auth/cli_auth_list_tokens_command.js +19 -6
  12. package/build/cli/commands/auth/cli_auth_remove_token_command.js +37 -13
  13. package/build/cli/commands/auth/cli_auth_switch_token_command.js +20 -11
  14. package/build/cli/commands/auth/ui/invalid_token_index_error.js +11 -0
  15. package/build/cli/commands/auth/ui/missing_credentials_error.js +9 -0
  16. package/build/cli/commands/auth/ui/missing_token_index_error.js +19 -0
  17. package/build/cli/commands/cli_ui_dump_command.js +11 -0
  18. package/build/cli/commands/cli_update_command.js +13 -4
  19. package/build/cli/commands/commands_constants.js +6 -4
  20. package/build/cli/core/cli_setup.js +33 -14
  21. package/build/cli/features/controls/controls_constants.js +12 -0
  22. package/build/cli/features/controls/controls_dto_mappers.js +55 -0
  23. package/build/cli/features/controls/ui/controls_mappers.js +62 -0
  24. package/build/cli/features/controls/ui/form.js +4 -0
  25. package/build/cli/features/controls/ui/form_constants.js +7 -0
  26. package/build/cli/features/controls/validators/greater_eq_than_validator.js +5 -0
  27. package/build/cli/features/controls/validators/length_validator.js +6 -0
  28. package/build/cli/features/controls/validators/required_validator.js +5 -0
  29. package/build/cli/features/controls/validators/validator_constants.js +13 -0
  30. package/build/cli/features/execution_context/execution_context_service.js +5 -5
  31. package/build/cli/features/http_requester/http_requester_initializer.js +1 -1
  32. package/build/cli/hooks/authorization/ensure_authorization_hook.js +2 -2
  33. package/build/cli/hooks/authorization/ensure_authorization_hook_constants.js +7 -8
  34. package/build/index.js +37 -19
  35. package/build/theme/class/archive/theme_archive.js +44 -0
  36. package/build/theme/class/archive/theme_archive_errors_factory.js +11 -0
  37. package/build/theme/class/checksums/theme_checksums.js +170 -0
  38. package/build/theme/{features/theme/utils → class}/checksums/theme_checksums_error_factory.js +1 -1
  39. package/build/theme/class/checksums/theme_checksums_utils.js +17 -0
  40. package/build/theme/class/fetch_resources/fetch_resources.js +1 -0
  41. package/build/theme/class/fetch_resources/fetch_resources_errors_factory.js +1 -1
  42. package/build/theme/class/fetch_resources/fetch_resources_utils.js +4 -1
  43. package/build/theme/class/files_upload/theme_files_upload.js +61 -0
  44. package/build/theme/class/files_upload/theme_files_upload_http_api.js +23 -0
  45. package/build/theme/commands/delete/theme_delete_command.js +97 -0
  46. package/build/theme/commands/delete/ui/theme_deleted_successfully.js +15 -0
  47. package/build/theme/commands/delete/ui/theme_deletion_warning.js +10 -0
  48. package/build/theme/commands/info/theme_info_command.js +79 -0
  49. package/build/theme/commands/info/theme_info_command_utils.js +39 -0
  50. package/build/theme/commands/init/theme_init_command.js +84 -0
  51. package/build/theme/commands/init/ui/theme_created_success.js +15 -0
  52. package/build/theme/commands/list/theme_list_command.js +25 -0
  53. package/build/theme/commands/list/theme_list_command_utils.js +27 -0
  54. package/build/theme/commands/publish/theme_publish_command.js +76 -0
  55. package/build/theme/commands/pull/theme_pull_command.js +174 -0
  56. package/build/theme/commands/pull/ui/theme_pull_id_mismatch_error.js +7 -0
  57. package/build/theme/commands/pull/ui/theme_pull_unpublished_changes_warning.js +10 -0
  58. package/build/theme/commands/pull/ui/theme_pulled_success.js +5 -0
  59. package/build/theme/commands/push/theme_push_command.js +112 -0
  60. package/build/theme/commands/push/ui/theme_push_skip_into.js +7 -0
  61. package/build/theme/commands/push/ui/theme_pushed_success.js +5 -0
  62. package/build/theme/commands/push/ui/theme_unpermitted_actions_error.js +12 -0
  63. package/build/theme/commands/theme_commands_constants.js +9 -6
  64. package/build/theme/commands/theme_verify_command.js +64 -22
  65. package/build/theme/commands/ui/invalid_theme_id.js +11 -0
  66. package/build/theme/commands/ui/missing_theme_files.js +15 -0
  67. package/build/theme/commands/ui/missing_theme_id_error.js +13 -0
  68. package/build/theme/commands/ui/ouside_of_theme_directory_context_error.js +7 -0
  69. package/build/theme/commands/ui/theme_directory_context_error.js +7 -0
  70. package/build/theme/commands/ui/theme_error.js +29 -0
  71. package/build/theme/commands/ui/theme_work_url_mismatch.js +17 -0
  72. package/build/theme/commands/ui/unpermitted_command_error.js +18 -0
  73. package/build/theme/features/theme/actions/api/theme_actions_api.js +3 -0
  74. package/build/theme/features/theme/actions/service/theme_actions_service.js +15 -3
  75. package/build/theme/features/theme/actions/service/theme_actions_service_constants.js +1 -0
  76. package/build/theme/features/theme/actions/theme_actions_constants.js +5 -2
  77. package/build/theme/features/theme/actions/theme_actions_initializer.js +1 -1
  78. package/build/theme/features/theme/actions/theme_actions_utils.js +60 -7
  79. package/build/theme/features/theme/delete/api/theme_delete_api.js +13 -0
  80. package/build/theme/features/theme/delete/http/theme_delete_http_api.js +17 -0
  81. package/build/theme/features/theme/delete/service/theme_delete_service.js +31 -0
  82. package/build/theme/features/theme/delete/theme_delete_constants.js +2 -0
  83. package/build/theme/features/theme/delete/theme_delete_initalizer.js +20 -0
  84. package/build/theme/features/theme/fetch/service/theme_fetch_service.js +30 -10
  85. package/build/theme/features/theme/info/theme_info_utils.js +9 -0
  86. package/build/theme/features/theme/init/service/theme_init_service.js +9 -4
  87. package/build/theme/features/theme/init/theme_init_initializer.js +3 -3
  88. package/build/theme/features/theme/merge/api/theme_merge_api.js +0 -12
  89. package/build/theme/features/theme/merge/service/theme_merge_service.js +20 -28
  90. package/build/theme/features/theme/push/service/theme_push_service.js +67 -166
  91. package/build/theme/features/theme/push/theme_push_constants.js +2 -0
  92. package/build/theme/features/theme/push/theme_push_errors_factory.js +7 -4
  93. package/build/theme/features/theme/push/theme_push_initializer.js +1 -7
  94. package/build/theme/features/theme/push/theme_push_utils.js +25 -0
  95. package/build/theme/features/theme/skinstore/api/theme_skinstore_api.js +19 -0
  96. package/build/theme/features/theme/skinstore/http/theme_skinstore_http_api.js +17 -0
  97. package/build/theme/features/theme/skinstore/service/theme_skinstore_service.js +32 -0
  98. package/build/theme/features/theme/skinstore/theme_publish_constants.js +4 -0
  99. package/build/theme/features/theme/skinstore/theme_skinstore_initialzier.js +20 -0
  100. package/build/theme/features/theme/utils/files_structure/theme_file_structure_errors_factory.js +10 -0
  101. package/build/theme/features/theme/utils/files_structure/theme_files_structure_utils.js +76 -0
  102. package/build/theme/features/theme/utils/hidden_directory/hidden_directory_utils.js +32 -0
  103. package/build/theme/features/theme/utils/meta_data/theme_meta_data_constants.js +1 -0
  104. package/build/theme/features/theme/utils/meta_data/theme_meta_data_error_factory.js +15 -0
  105. package/build/theme/features/theme/utils/meta_data/theme_meta_data_utils.js +39 -0
  106. package/build/theme/features/theme/utils/{directories → resources}/theme_resources_with_id_directory_utils.js +3 -14
  107. package/build/theme/features/theme/utils/theme_images_utils.js +1 -19
  108. package/build/theme/features/theme/verify/api/theme_verify_api.js +13 -0
  109. package/build/theme/features/theme/verify/http/theme_verify_http_api.js +30 -0
  110. package/build/theme/features/theme/verify/theme_verify_constants.js +2 -0
  111. package/build/theme/features/theme/verify/theme_verify_initializer.js +19 -0
  112. package/build/theme/features/theme/verify/verify/theme_verify_service.js +55 -0
  113. package/build/theme/features/themes/list/api/themes_list_api.js +3 -0
  114. package/build/theme/features/themes/list/services/themes_list_service.js +13 -7
  115. package/build/theme/hooks/{ensure_theme_meta_data_untouched.js → ensure_theme_meta_data_untouched_hook.js} +2 -2
  116. package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_constants.js +1 -2
  117. 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
  118. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook.js +1 -0
  119. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +1 -1
  120. package/build/theme/index.js +34 -8
  121. package/build/theme/utils/directory_validator/directory_validator_constants.js +2 -6
  122. package/build/theme/utils/directory_validator/directory_validator_utils.js +7 -25
  123. package/build/ui/box.js +2 -0
  124. package/build/ui/color_constants.js +30 -0
  125. package/build/ui/command.js +6 -0
  126. package/build/ui/file_name.js +6 -0
  127. package/build/ui/flag.js +6 -0
  128. package/build/ui/icons/error_icon.js +7 -0
  129. package/build/ui/icons/info_icon.js +7 -0
  130. package/build/ui/icons/success_icon.js +7 -0
  131. package/build/ui/icons/warning_icon.js +7 -0
  132. package/build/ui/link.js +8 -0
  133. package/build/ui/list/list.js +10 -0
  134. package/build/ui/list/list_constants.js +4 -0
  135. package/build/ui/list/list_item.js +11 -0
  136. package/build/ui/message_box/error.js +4 -0
  137. package/build/ui/message_box/info.js +4 -0
  138. package/build/ui/message_box/message_box.js +11 -0
  139. package/build/ui/message_box/message_box_constants.js +24 -0
  140. package/build/ui/message_box/success.js +4 -0
  141. package/build/ui/message_box/warning.js +4 -0
  142. package/build/ui/prompts/prompt_confirmation.js +11 -0
  143. package/build/ui/prompts/prompt_input.js +10 -0
  144. package/build/ui/table/t_cell.js +7 -0
  145. package/build/ui/table/t_header.js +9 -0
  146. package/build/ui/table/t_row.js +5 -0
  147. package/build/ui/table/table.js +18 -0
  148. package/build/ui/text.js +2 -0
  149. package/build/ui/tip.js +9 -0
  150. package/build/ui/ui_dump/ui_component_box.js +9 -0
  151. package/build/ui/ui_dump/ui_dump.js +53 -0
  152. package/build/ui/ui_dump/ui_dump_constants.js +21 -0
  153. package/build/ui/ui_utils.js +11 -0
  154. package/build/ui/validation_errors/validation_error_content.js +19 -0
  155. package/build/ui/validation_errors/validation_errors.js +21 -0
  156. package/build/ui/validation_errors/validation_errors_utils.js +17 -0
  157. package/build/utils/checksums/checksums_utils.js +9 -26
  158. package/build/utils/download_file/download_file_errors_factory.js +1 -1
  159. package/build/utils/download_file/download_file_utils.js +4 -2
  160. package/build/utils/fs/errors/stream_read_error.js +1 -1
  161. package/build/utils/fs/errors/stream_write_error.js +1 -1
  162. package/build/utils/fs/fs_utils.js +12 -1
  163. package/build/utils/path_utils.js +18 -2
  164. package/build/utils/platform_utils.js +3 -0
  165. package/build/utils/zip/create_zip_utils.js +1 -1
  166. package/build/utils/zip/errors/create_zip_error.js +1 -1
  167. package/build/utils/zip/errors/open_zip_error.js +1 -1
  168. package/oclif.config.js +3 -3
  169. package/package.json +14 -9
  170. package/build/cli/commands/files_diff_command.js +0 -174
  171. package/build/theme/commands/theme_init_command.js +0 -53
  172. package/build/theme/commands/theme_list_command.js +0 -16
  173. package/build/theme/commands/theme_pull_command.js +0 -126
  174. package/build/theme/commands/theme_push_command.js +0 -65
  175. package/build/theme/commands/theme_show_changes_command.js +0 -60
  176. package/build/theme/features/theme/directory/theme_directory_utils.js +0 -76
  177. package/build/theme/features/theme/publish/theme_publish_constants.js +0 -2
  178. package/build/theme/features/theme/utils/checksums/theme_checksums_utils.js +0 -94
  179. /package/build/cli/{features → class}/caches/cache_factory.js +0 -0
  180. /package/build/cli/{features → class}/caches/json_cache/json_cache.js +0 -0
  181. /package/build/cli/{features → class}/caches/memory_cache.js +0 -0
  182. /package/build/cli/class/errors/{app_error → app}/app_error.js +0 -0
  183. /package/build/cli/class/errors/{app_error → app}/app_error_constants.js +0 -0
  184. /package/build/theme/features/theme/{publish → skinstore}/theme_publish_utils.js +0 -0
@@ -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
+ };
@@ -1,10 +1,10 @@
1
1
  import process from 'node:process';
2
2
  import { EXECUTION_CONTEXTS } from './execution_context_constants.js';
3
- import { ThemeDirectoryUtils } from '../../../theme/features/theme/directory/theme_directory_utils.js';
3
+ import { ThemeMetaDataUtils } from '../../../theme/features/theme/utils/meta_data/theme_meta_data_utils.js';
4
4
  export class ExecutionContextService {
5
5
  #executionContext;
6
6
  async _obtainExecutionContext() {
7
- if (await ThemeDirectoryUtils.closestThemeRootDirectory(process.cwd())) {
7
+ if (await ThemeMetaDataUtils.closestThemeRootDirectory(process.cwd())) {
8
8
  return await this.getThemeExecutionContext();
9
9
  }
10
10
  return await this._getGlobalExecutionContext();
@@ -20,14 +20,14 @@ export class ExecutionContextService {
20
20
  return this.#executionContext;
21
21
  }
22
22
  async getThemeExecutionContext() {
23
- const themeRoot = await ThemeDirectoryUtils.closestThemeRootDirectory(process.cwd());
23
+ const themeRoot = await ThemeMetaDataUtils.closestThemeRootDirectory(process.cwd());
24
24
  //TODO errors
25
25
  if (!themeRoot)
26
26
  throw 'Theme root directory not found';
27
- const themeDirectoryMetadata = await ThemeDirectoryUtils.getThemeDirectoryMetadata(themeRoot);
27
+ const themeMetaData = await ThemeMetaDataUtils.getThemeMetadata(themeRoot);
28
28
  return {
29
29
  type: EXECUTION_CONTEXTS.theme,
30
- themeId: themeDirectoryMetadata.themeId,
30
+ themeId: themeMetaData.themeId,
31
31
  executionDir: process.cwd(),
32
32
  themeRootDir: themeRoot
33
33
  };
@@ -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 '../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() {
@@ -1,11 +1,11 @@
1
- import { COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION } from './ensure_authorization_hook_constants.js';
1
+ import { COMMANDS_THAT_REQUIRE_AUTHORIZATION } from './ensure_authorization_hook_constants.js';
2
2
  import { useApi } from '../ensure_cli_initialized_hook.js';
3
3
  import { CLI_AUTH_API_NAME } from '../../auth/cli_auth_constants.js';
4
4
  import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
5
5
  import { promptForToken } from '../../commands/utils/prompt_for_token_utils.js';
6
6
  import { CliAuthUtils } from '../../auth/cli_auth_utils.js';
7
7
  const ensureAuthorizationHook = async ({ Command }) => {
8
- if (COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION.includes(Command.id))
8
+ if (!COMMANDS_THAT_REQUIRE_AUTHORIZATION.includes(Command.id))
9
9
  return;
10
10
  const cliAuthApi = useApi(CLI_AUTH_API_NAME);
11
11
  const cliAuthTokensApi = useApi(CLI_AUTH_TOKENS_API_NAME);
@@ -1,9 +1,8 @@
1
- import { CLI_COMMANDS_NAMES } from '../../commands/commands_constants.js';
2
- export const COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION = [
3
- CLI_COMMANDS_NAMES.update,
4
- CLI_COMMANDS_NAMES.update,
5
- CLI_COMMANDS_NAMES.authAddToken,
6
- CLI_COMMANDS_NAMES.authRemoveToken,
7
- CLI_COMMANDS_NAMES.authListTokens,
8
- CLI_COMMANDS_NAMES.switchToken
1
+ import { THEME_COMMANDS_NAME } from '../../../theme/commands/theme_commands_constants.js';
2
+ export const COMMANDS_THAT_REQUIRE_AUTHORIZATION = [
3
+ THEME_COMMANDS_NAME.push,
4
+ THEME_COMMANDS_NAME.pull,
5
+ THEME_COMMANDS_NAME.list,
6
+ THEME_COMMANDS_NAME.init,
7
+ THEME_COMMANDS_NAME.verify
9
8
  ];
package/build/index.js CHANGED
@@ -7,6 +7,7 @@ import { CliAuthListTokensCommand } from './cli/commands/auth/cli_auth_list_toke
7
7
  import { CliAuthAddTokenCommand } from './cli/commands/auth/cli_auth_add_token_command.js';
8
8
  import { CliAuthRemoveTokenCommand } from './cli/commands/auth/cli_auth_remove_token_command.js';
9
9
  import { CliAuthSwitchTokenCommand } from './cli/commands/auth/cli_auth_switch_token_command.js';
10
+ import { CliUIDumpCommand } from './cli/commands/cli_ui_dump_command.js';
10
11
  //TODO
11
12
  //@ts-ignore
12
13
  if (typeof global.crypto !== 'object') {
@@ -42,27 +43,44 @@ export const COMMANDS = {
42
43
  [CLI_COMMANDS_NAMES.authAddToken]: CliAuthAddTokenCommand,
43
44
  [CLI_COMMANDS_NAMES.authRemoveToken]: CliAuthRemoveTokenCommand,
44
45
  [CLI_COMMANDS_NAMES.switchToken]: CliAuthSwitchTokenCommand,
46
+ [CLI_COMMANDS_NAMES.uiDump]: CliUIDumpCommand,
45
47
  ...THEME_COMMANDS
46
48
  };
47
49
  export { runCLI } from './cli/index.js';
48
50
  /**
49
- * TODO:
50
- * testy verify
51
- * - usuniecie po koleji .shoper, macros, modules, settings, styles...
52
- * testy theme show-changes
53
- * - macro
54
- * - dodawanie, zmienianie i usuwanie makr
55
- * testy theme verify
56
- * - makro
57
- * - dodawanie, zmienianie i usuwanie makr
58
- * testy pull push
59
- * - nie skinstore
60
- * - push nowego modułu, podmieni sie folder i checksumy przywróćenie foledu bez checksum i push error z permissions
61
- * - dodawanie, modzenie i usuwanie customowych makr
62
- * - modzenie makr
63
- * - dodawanie i usuwanie customowych modułów
64
- * - podmiana thumbnail
65
- * - skinstore
66
- * - modzenie danych settingsów skinstore
67
- * - dodawanie, usuwanie, podmienianie obrazków
51
+ * Przetestowane na win
52
+ * oglne
53
+ * moduly:
54
+ * - stworzony w admince
55
+ * - pull w cli - v
56
+ * - updejt modulu w adminc i pull w cli - v
57
+ * - zmiana nazwy katalogu w cli, modzenie w admince i pull - v
58
+ * - kopiowanie stworzonego modulu w admince i push (usuniety id i code) - v
59
+ * - zminaa w cli i push - v
60
+ * - tworzenie modulu w cli, min plikow i push
61
+ * - aktualizowanie js/twig/settings/schema
62
+ * - zmiana w adminc i pull
63
+ * - usuwanie modulu z cli - v
64
+ * - usuwanie modulu z adminki - v
65
+ * - dodanie niedozwolonego pliku do folderu modulu
66
+ * - dodanie niedozwolonego pliku do folderu modules/
67
+ * - translacje - v
68
+ * macro:
69
+ * - dodawanie pliku do macros - v
70
+ * - usuniecie macro - v
71
+ * - modzneie makro - v
72
+ * - dodawanie customowego macro - v
73
+ * - push customowego macro - v
74
+ * - modzenie w admince i pull - v
75
+ * settingsy:
76
+ * - uzupelniania schemy w admince, pull w cli
77
+ * - uzupelnianie wartosci a admince i pull
78
+ * - modzenie w cli
79
+ * - usuniecie pliku w cli
80
+ * styles:
81
+ * - modzenie stylu w src - niedozwolone - v
82
+ * - modzenie custom - v
83
+ * - usuniecie custom - v
84
+ * - modzenie schema i settings - v
85
+ * dodanie czegos w .shoper
68
86
  */
@@ -0,0 +1,44 @@
1
+ import globs from 'fast-glob';
2
+ import { createZip } from '../../../utils/zip/create_zip_utils.js';
3
+ import { ThemeFilesStructureUtils } from '../../features/theme/utils/files_structure/theme_files_structure_utils.js';
4
+ import { extname, join } from '../../../utils/path_utils.js';
5
+ import { formatJSONFile } from '../../../utils/fs/fs_utils.js';
6
+ import { ThemeArchiveErrorsFactory } from './theme_archive_errors_factory.js';
7
+ import { ThemeFileStructureErrorsFactory } from '../../features/theme/utils/files_structure/theme_file_structure_errors_factory.js';
8
+ import { ThemeActionsUtils } from '../../features/theme/actions/theme_actions_utils.js';
9
+ export class ThemeArchive {
10
+ #themeRootDir;
11
+ constructor(themeRootDir) {
12
+ this.#themeRootDir = themeRootDir;
13
+ }
14
+ async createFullArchive({ dist, actionValue, actionType }) {
15
+ const filesStructure = await ThemeFilesStructureUtils.getThemeFilesStructure(this.#themeRootDir);
16
+ if (!filesStructure)
17
+ throw ThemeFileStructureErrorsFactory.createNoFilesStructureError();
18
+ try {
19
+ const filesInThemeDirectory = await globs(ThemeActionsUtils.getFilesGlobsThatMatchesActionName({
20
+ actionType,
21
+ actionValue,
22
+ filesStructure
23
+ }), {
24
+ suppressErrors: true,
25
+ onlyFiles: true,
26
+ cwd: this.#themeRootDir
27
+ });
28
+ await this._formatJsonFiles(this.#themeRootDir, filesInThemeDirectory);
29
+ return createZip({
30
+ files: filesInThemeDirectory,
31
+ baseDir: this.#themeRootDir,
32
+ dist
33
+ });
34
+ }
35
+ catch (err) {
36
+ throw ThemeArchiveErrorsFactory.createErrorWhileCreatingThemeArchive(err);
37
+ }
38
+ }
39
+ async _formatJsonFiles(themeRootDir, filesToUpload) {
40
+ await Promise.all(filesToUpload
41
+ .filter((path) => extname(path).toLowerCase() === '.json')
42
+ .map((jsonFile) => formatJSONFile(join(themeRootDir, jsonFile))));
43
+ }
44
+ }
@@ -0,0 +1,11 @@
1
+ import { AppError } from '../../../cli/class/errors/app/app_error.js';
2
+ export class ThemeArchiveErrorsFactory {
3
+ static createErrorWhileCreatingThemeArchive(error) {
4
+ return new AppError({
5
+ code: 'theme_archive.error_creating_archive',
6
+ message: `Error while creating theme archive`,
7
+ level: 'error',
8
+ stack: error.stack
9
+ });
10
+ }
11
+ }
@@ -0,0 +1,170 @@
1
+ import { copyFile, fileExists, readJSONFile, readJSONFileSync, removeFile } from '../../../utils/fs/fs_utils.js';
2
+ import { ThemeChecksumsUtils } from './theme_checksums_utils.js';
3
+ import { isWindowsOs } from '../../../utils/platform_utils.js';
4
+ import { join, mapKeysPathsToWindowPlatform, toCurrentPlatformPath } from '../../../utils/path_utils.js';
5
+ import { createWriteStream } from 'node:fs';
6
+ import { JSON_FILE_INDENT } from '../../../cli/cli_constants.js';
7
+ import { ThemeChecksumsErrorFactory } from './theme_checksums_error_factory.js';
8
+ import { computeChecksumsFromFilesStructure, computeDirectoriesChecksums, computeFileChecksum } from '../../../utils/checksums/checksums_utils.js';
9
+ import { normalize } from 'node:path';
10
+ import { ThemePushUtils } from '../../features/theme/push/theme_push_utils.js';
11
+ import { SHOPER_THEME_METADATA_DIR } from '../../constants/directory_contstants.js';
12
+ import { THEME_CURRENT_CHECKSUMS_FILE_NAME, THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME, THEME_INITIAL_CHECKSUMS_FILE_NAME, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME } from '../../features/theme/theme_constants.js';
13
+ export class ThemeChecksums {
14
+ #themeDir;
15
+ #currentChecksumsFilePath;
16
+ #currentChecksumsVerificationFilePath;
17
+ #initialChecksumsFilePath;
18
+ #initialChecksumsVerificationFilePath;
19
+ #initialChecksums;
20
+ #currentChecksums;
21
+ constructor(themeDir) {
22
+ this.#themeDir = themeDir;
23
+ this.#currentChecksumsFilePath = ThemeChecksumsUtils.getCurrentThemeChecksumsFilePath(themeDir);
24
+ this.#currentChecksumsVerificationFilePath = ThemeChecksumsUtils.getCurrentThemeChecksumsVerificationFilePath(themeDir);
25
+ this.#initialChecksumsFilePath = ThemeChecksumsUtils.getInitialThemeChecksumsFilePath(themeDir);
26
+ this.#initialChecksumsVerificationFilePath = ThemeChecksumsUtils.getInitialThemeChecksumsVerificationFilePath(themeDir);
27
+ }
28
+ async getInitialChecksums() {
29
+ if (this.#initialChecksums)
30
+ return this.#initialChecksums;
31
+ this.#initialChecksums = await this._getChecksums(this.#initialChecksumsFilePath);
32
+ return this.#initialChecksums;
33
+ }
34
+ getInitialChecksumsSync() {
35
+ if (this.#initialChecksums)
36
+ return this.#initialChecksums;
37
+ this.#initialChecksums = this._getChecksumsSync(this.#initialChecksumsFilePath);
38
+ return this.#initialChecksums;
39
+ }
40
+ async getCurrentChecksums() {
41
+ if (this.#currentChecksums)
42
+ return this.#currentChecksums;
43
+ this.#currentChecksums = await this._getChecksums(this.#currentChecksumsFilePath);
44
+ return this.#currentChecksums;
45
+ }
46
+ getCurrentChecksumsSync() {
47
+ if (this.#currentChecksums)
48
+ return this.#currentChecksums;
49
+ this.#currentChecksums = this._getChecksumsSync(this.#currentChecksumsFilePath);
50
+ return this.#currentChecksums;
51
+ }
52
+ async getCurrentChecksumFromPath(path) {
53
+ const checksums = await this.getCurrentChecksums();
54
+ return checksums[toCurrentPlatformPath(path)];
55
+ }
56
+ getCurrentChecksumFromPathSync(path) {
57
+ const checksums = this.getCurrentChecksumsSync();
58
+ return checksums[toCurrentPlatformPath(path)];
59
+ }
60
+ async getInitialChecksumFromPath(path) {
61
+ const checksums = await this.getInitialChecksums();
62
+ return checksums[toCurrentPlatformPath(path)];
63
+ }
64
+ async hasThemeBeenModified() {
65
+ const initialChecksums = await this._getInitialChecksumsVerification();
66
+ const currentChecksums = await this._getCurrentChecksumsVerification();
67
+ return !!initialChecksums && !!currentChecksums && initialChecksums !== currentChecksums;
68
+ }
69
+ async hasThemeFileBeenCreated(path) {
70
+ const initialChecksum = await this.getInitialChecksumFromPath(path);
71
+ return !initialChecksum && (await fileExists(join(this.#themeDir, path)));
72
+ }
73
+ async hasThemeFileBeenModified(path) {
74
+ const currentChecksum = await this.getCurrentChecksumFromPath(path);
75
+ const initialChecksum = await this.getInitialChecksumFromPath(path);
76
+ return !!currentChecksum && !!initialChecksum && currentChecksum !== initialChecksum;
77
+ }
78
+ async verify() {
79
+ const initialChecksumFilePath = this.#initialChecksumsFilePath;
80
+ const initialChecksumVerifyFilePath = this.#initialChecksumsVerificationFilePath;
81
+ const initialChecksum = await computeFileChecksum(initialChecksumFilePath);
82
+ const initialChecksumVerify = await readJSONFile(initialChecksumVerifyFilePath);
83
+ return initialChecksum === initialChecksumVerify;
84
+ }
85
+ async updateAllChecksums() {
86
+ const checksums = await this.computeThemeChecksums();
87
+ return new Promise((resolve, reject) => {
88
+ const currentChecksumFilePath = this.#currentChecksumsFilePath;
89
+ const initialChecksumFilePath = this.#initialChecksumsFilePath;
90
+ const checksumStream = createWriteStream(initialChecksumFilePath);
91
+ checksumStream.write(JSON.stringify(checksums, null, JSON_FILE_INDENT));
92
+ checksumStream.end();
93
+ checksumStream
94
+ .on('finish', async () => {
95
+ const initialChecksumVerifyFilePath = this.#initialChecksumsVerificationFilePath;
96
+ const currentChecksumVerifyFilePath = this.#currentChecksumsVerificationFilePath;
97
+ await this._createThemeChecksumVerifyFile(initialChecksumFilePath, initialChecksumVerifyFilePath);
98
+ await copyFile(initialChecksumFilePath, currentChecksumFilePath);
99
+ await copyFile(initialChecksumVerifyFilePath, currentChecksumVerifyFilePath);
100
+ resolve();
101
+ })
102
+ .on('error', async (err) => {
103
+ await removeFile(initialChecksumFilePath, { force: true });
104
+ reject(ThemeChecksumsErrorFactory.createThemeChecksumError(err.stack));
105
+ });
106
+ });
107
+ }
108
+ async updateCurrentChecksums() {
109
+ const checksums = await this.computeThemeChecksums();
110
+ return new Promise((resolve, reject) => {
111
+ const currentChecksumFilePath = this.#currentChecksumsFilePath;
112
+ const checksumStream = createWriteStream(currentChecksumFilePath);
113
+ checksumStream.write(JSON.stringify(checksums, null, JSON_FILE_INDENT));
114
+ checksumStream.end();
115
+ checksumStream
116
+ .on('finish', async () => {
117
+ const currentChecksumVerifyFilePath = this.#currentChecksumsVerificationFilePath;
118
+ await this._createThemeChecksumVerifyFile(currentChecksumFilePath, currentChecksumVerifyFilePath);
119
+ resolve();
120
+ })
121
+ .on('error', async (err) => {
122
+ await removeFile(currentChecksumFilePath, { force: true });
123
+ reject(ThemeChecksumsErrorFactory.createThemeChecksumError(err.stack));
124
+ });
125
+ });
126
+ }
127
+ async computeThemeChecksums() {
128
+ const filesToIgnoreInChecksums = [
129
+ join(SHOPER_THEME_METADATA_DIR, THEME_CURRENT_CHECKSUMS_FILE_NAME),
130
+ join(SHOPER_THEME_METADATA_DIR, THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME),
131
+ join(SHOPER_THEME_METADATA_DIR, THEME_INITIAL_CHECKSUMS_FILE_NAME),
132
+ join(SHOPER_THEME_METADATA_DIR, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME)
133
+ ];
134
+ const filesToComputeChecksums = (await ThemePushUtils.getAllFilesThatAreSendToRemote(this.#themeDir))
135
+ .filter((path) => !filesToIgnoreInChecksums.some((ignorePath) => normalize(path) === ignorePath))
136
+ .map((relativePath) => join(this.#themeDir, relativePath));
137
+ const { filesChecksumsInDirectories, filesChecksums } = await computeChecksumsFromFilesStructure(filesToComputeChecksums, this.#themeDir);
138
+ const directoriesChecksums = computeDirectoriesChecksums(filesChecksumsInDirectories);
139
+ return { ...filesChecksums, ...directoriesChecksums };
140
+ }
141
+ async _getInitialChecksumsVerification() {
142
+ return await readJSONFile(this.#initialChecksumsVerificationFilePath);
143
+ }
144
+ async _getCurrentChecksumsVerification() {
145
+ return await readJSONFile(this.#currentChecksumsVerificationFilePath);
146
+ }
147
+ async _getChecksums(path) {
148
+ const checksums = await readJSONFile(path);
149
+ if (!isWindowsOs())
150
+ return checksums;
151
+ return mapKeysPathsToWindowPlatform(checksums);
152
+ }
153
+ _getChecksumsSync(path) {
154
+ const checksums = readJSONFileSync(path);
155
+ if (!isWindowsOs())
156
+ return checksums;
157
+ return mapKeysPathsToWindowPlatform(checksums);
158
+ }
159
+ async _createThemeChecksumVerifyFile(checksumFilePath, checksumVerifyFullPath) {
160
+ const checksumVerifyStream = createWriteStream(checksumVerifyFullPath);
161
+ const checksumVerify = await computeFileChecksum(checksumFilePath);
162
+ checksumVerifyStream
163
+ .on('error', async (err) => {
164
+ await removeFile(checksumFilePath, { force: true });
165
+ throw ThemeChecksumsErrorFactory.createThemeChecksumError(err.stack);
166
+ })
167
+ .write(JSON.stringify(checksumVerify));
168
+ checksumVerifyStream.end();
169
+ }
170
+ }
@@ -1,4 +1,4 @@
1
- import { AppError } from '../../../../../cli/class/errors/app_error/app_error.js';
1
+ import { AppError } from '../../../cli/class/errors/app/app_error.js';
2
2
  export class ThemeChecksumsErrorFactory {
3
3
  static createThemeChecksumError(stack) {
4
4
  return new AppError({
@@ -0,0 +1,17 @@
1
+ import { join } from '../../../utils/path_utils.js';
2
+ import { THEME_CURRENT_CHECKSUMS_FILE_NAME, THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME, THEME_INITIAL_CHECKSUMS_FILE_NAME, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME } from '../../features/theme/theme_constants.js';
3
+ import { HiddenDirectoryUtils } from '../../features/theme/utils/hidden_directory/hidden_directory_utils.js';
4
+ export class ThemeChecksumsUtils {
5
+ static getCurrentThemeChecksumsFilePath(themeDir) {
6
+ return join(HiddenDirectoryUtils.getThemeHiddenDirectoryPath(themeDir), THEME_CURRENT_CHECKSUMS_FILE_NAME);
7
+ }
8
+ static getInitialThemeChecksumsFilePath(themeDir) {
9
+ return join(HiddenDirectoryUtils.getThemeHiddenDirectoryPath(themeDir), THEME_INITIAL_CHECKSUMS_FILE_NAME);
10
+ }
11
+ static getCurrentThemeChecksumsVerificationFilePath(themeDir) {
12
+ return join(HiddenDirectoryUtils.getThemeHiddenDirectoryPath(themeDir), THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME);
13
+ }
14
+ static getInitialThemeChecksumsVerificationFilePath(themeDir) {
15
+ return join(HiddenDirectoryUtils.getThemeHiddenDirectoryPath(themeDir), THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME);
16
+ }
17
+ }
@@ -58,6 +58,7 @@ export class FetchResources {
58
58
  });
59
59
  }));
60
60
  }
61
+ return;
61
62
  }
62
63
  async _getResourcesFileContent(resourcePath) {
63
64
  return mapResourcesToTree(await readJSONFile(resourcePath));
@@ -1,4 +1,4 @@
1
- import { AppError } from '../../../cli/class/errors/app_error/app_error.js';
1
+ import { AppError } from '../../../cli/class/errors/app/app_error.js';
2
2
  export class FetchResourcesErrorsFactory {
3
3
  static createErrorFetchingResource(shopUrl, messages) {
4
4
  return new AppError({
@@ -1,7 +1,7 @@
1
1
  import { join } from '../../../utils/path_utils.js';
2
2
  import { RESOURCES_FILE_NAME } from './fetch_resources_constants.js';
3
3
  import { SHOPER_THEME_METADATA_DIR } from '../../constants/directory_contstants.js';
4
- import { fileExists, readJSONFile } from '../../../utils/fs/fs_utils.js';
4
+ import { fileExists, readJSONFile, removeFiles } from '../../../utils/fs/fs_utils.js';
5
5
  export const isResourceObject = (resource) => {
6
6
  return typeof resource === 'object' && resource !== null && 'url' in resource && typeof resource.url === 'string';
7
7
  };
@@ -15,6 +15,9 @@ export const getResources = async (root) => {
15
15
  }
16
16
  return await readJSONFile(resourcesPath);
17
17
  };
18
+ export const removeOldResources = async (rootDir, resources) => {
19
+ await removeFiles(Object.keys(resources).map((path) => join(rootDir, path)));
20
+ };
18
21
  export const mapResourcesToTree = (resources, separator = '/') => {
19
22
  const tree = {};
20
23
  Object.entries(resources).forEach(([path, value]) => {
@@ -0,0 +1,61 @@
1
+ import { basename, dirname } from '../../../utils/path_utils.js';
2
+ import { createReadStream } from 'node:fs';
3
+ import { THEME_WILDCARD_ACTION_NAME } from '../../features/theme/actions/service/theme_actions_service_constants.js';
4
+ import { ThemePushErrorsFactory } from '../../features/theme/push/theme_push_errors_factory.js';
5
+ export class ThemeFilesUpload {
6
+ #credentials;
7
+ #themeFilesUploadHttpApi;
8
+ constructor({ credentials, themeFilesUploadHttpApi }) {
9
+ this.#themeFilesUploadHttpApi = themeFilesUploadHttpApi;
10
+ this.#credentials = credentials;
11
+ }
12
+ async uploadArchive({ action, themeArchivePath, credentials }) {
13
+ try {
14
+ const request = this.#themeFilesUploadHttpApi.uploadFiles({
15
+ actionData: action.data[THEME_WILDCARD_ACTION_NAME],
16
+ stream: createReadStream(themeArchivePath),
17
+ shopUrl: credentials.shopUrl
18
+ });
19
+ const response = await request.response;
20
+ if (response.status !== 200 || !response.data.isSuccess)
21
+ throw response;
22
+ return response.data;
23
+ }
24
+ catch (err) {
25
+ throw ThemePushErrorsFactory.createErrorWhileUploadingTheme(credentials.shopUrl, err.response.data.messages);
26
+ }
27
+ }
28
+ async uploadFiles(uploadData) {
29
+ const uploadedImageData = [];
30
+ const rejectedImageData = [];
31
+ await Promise.all(uploadData.map(({ actionData, path }) => this.#themeFilesUploadHttpApi
32
+ //TODO tajpings
33
+ .uploadFiles({
34
+ actionData,
35
+ stream: createReadStream(path),
36
+ shopUrl: this.#credentials.shopUrl
37
+ })
38
+ .response.then((response) => {
39
+ const { imageId, messages, isSuccess } = response.data;
40
+ uploadedImageData.push({
41
+ isSuccess,
42
+ messages,
43
+ location: dirname(path),
44
+ originalFilename: basename(path),
45
+ uploadedFilename: imageId
46
+ });
47
+ })
48
+ .catch((err) => {
49
+ rejectedImageData.push({
50
+ isSuccess: err?.response?.data?.isSuccess ?? false,
51
+ messages: err?.response?.data?.messages ?? [],
52
+ location: dirname(path),
53
+ originalFilename: basename(path)
54
+ });
55
+ })));
56
+ return {
57
+ uploadedImageData,
58
+ rejectedImageData
59
+ };
60
+ }
61
+ }
@@ -0,0 +1,23 @@
1
+ export class ThemeFilesUploadHttpApi {
2
+ #httpApi;
3
+ constructor(httpApi) {
4
+ this.#httpApi = httpApi;
5
+ }
6
+ uploadFiles({ actionData, shopUrl, stream }) {
7
+ const { method, url } = actionData;
8
+ return this.#httpApi.fetch({
9
+ url: `${shopUrl}${url}`,
10
+ method,
11
+ //TODO Remove after fix
12
+ // method: 'POST',
13
+ data: stream,
14
+ sanitizeOptions: {
15
+ disable: true
16
+ },
17
+ headers: {
18
+ 'Content-Type': 'application/octet-stream'
19
+ },
20
+ isPrivate: true
21
+ });
22
+ }
23
+ }