@shoper/cli 0.1.0-9 → 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 +1 -0
  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 +92 -69
  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 +1 -1
  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 +7 -25
  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 +12 -1
  151. package/build/utils/path_utils.js +18 -2
  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 +13 -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 -126
  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,20 +1,20 @@
1
1
  import { ThemeMetaData } from '../model/theme_list_metadata.js';
2
2
  import { STATUS_CODES } from '@dreamcommerce/star_core';
3
- import { HttpErrorsFactory } from '../../../../../cli/class/errors/http_errors_factory.js';
3
+ import { HttpErrorsFactory } from '../../../../../cli/class/errors/http/http_errors_factory.js';
4
4
  import { DownloadFileErrorsFactory } from '../../../../../utils/download_file/download_file_errors_factory.js';
5
5
  export class ThemesListService {
6
- httpApi;
6
+ #httpApi;
7
7
  constructor(httpApi) {
8
- this.httpApi = httpApi;
8
+ this.#httpApi = httpApi;
9
9
  }
10
10
  async getThemes({ shopUrl }) {
11
11
  try {
12
- const { response } = this.httpApi.getThemes(shopUrl);
13
- const { data, status } = await response;
14
- if (status !== STATUS_CODES.ok)
12
+ const { response: request } = this.#httpApi.getThemes(shopUrl);
13
+ const response = await request;
14
+ if (response?.status !== STATUS_CODES.ok)
15
15
  return;
16
16
  //TODO baseHttpApi + model mapper
17
- return data.map(({ _links, ...rest }) => new ThemeMetaData({
17
+ return response?.data.map(({ _links, ...rest }) => new ThemeMetaData({
18
18
  ...rest,
19
19
  links: _links
20
20
  }));
@@ -34,4 +34,10 @@ export class ThemesListService {
34
34
  }
35
35
  }
36
36
  }
37
+ async getTheme({ themeId, shopUrl }) {
38
+ const themes = await this.getThemes({ shopUrl });
39
+ if (!themes)
40
+ return;
41
+ return themes.find((theme) => String(theme.skinId) === themeId);
42
+ }
37
43
  }
@@ -1,13 +1,13 @@
1
1
  import { useApi } from '../../cli/hooks/ensure_cli_initialized_hook.js';
2
2
  import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../cli/features/execution_context/execution_context_constants.js';
3
- import { ThemeDirectoryUtils } from '../features/theme/directory/theme_directory_utils.js';
3
+ import { HiddenDirectoryUtils } from '../features/theme/utils/hidden_directory/hidden_directory_utils.js';
4
4
  const ensureThemeMetaDataUntouched = async () => {
5
5
  const executionContextApi = useApi(EXECUTION_CONTEXT_API_NAME);
6
6
  const executionContext = await executionContextApi.getExecutionContext();
7
7
  if (executionContext.type !== EXECUTION_CONTEXTS.theme)
8
8
  return;
9
9
  try {
10
- await ThemeDirectoryUtils.ensureFilesInsideThemeMetaDataDirectoryUntouched(executionContext.themeRootDir);
10
+ await HiddenDirectoryUtils.ensureFilesInsideThemeMetaDataDirectoryUntouched(executionContext.themeRootDir);
11
11
  }
12
12
  catch (err) {
13
13
  console.error(err);
@@ -2,6 +2,6 @@ import { THEME_COMMANDS_NAME } from '../../commands/theme_commands_constants.js'
2
2
  export const THEME_COMMANDS_THAT_REQUIRES_UP_TO_DATE_CHECKSUMS = [
3
3
  THEME_COMMANDS_NAME.push,
4
4
  THEME_COMMANDS_NAME.showChanges,
5
- THEME_COMMANDS_NAME.push,
5
+ THEME_COMMANDS_NAME.pull,
6
6
  THEME_COMMANDS_NAME.verify
7
7
  ];
@@ -1,10 +1,8 @@
1
1
  import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../../cli/features/execution_context/execution_context_constants.js';
2
2
  import { useApi } from '../../../cli/hooks/ensure_cli_initialized_hook.js';
3
- import { ThemeChecksumsUtils } from '../../features/theme/utils/checksums/theme_checksums_utils.js';
4
- import { computeChecksumsFromSource } from '../../../utils/checksums/checksums_utils.js';
5
3
  import { THEME_COMMANDS_THAT_REQUIRES_UP_TO_DATE_CHECKSUMS } from './ensure_theme_current_checksums_up_to_date_constants.js';
4
+ import { ThemeChecksums } from '../../../theme/class/checksums/theme_checksums.js';
6
5
  export const ensureThemeChecksumsUpToDate = async ({ Command }) => {
7
- console.log('Command', Command.id);
8
6
  if (!THEME_COMMANDS_THAT_REQUIRES_UP_TO_DATE_CHECKSUMS.includes(Command.id))
9
7
  return;
10
8
  const executionContextApi = useApi(EXECUTION_CONTEXT_API_NAME);
@@ -15,7 +13,6 @@ export const ensureThemeChecksumsUpToDate = async ({ Command }) => {
15
13
  * Naive solution, recalculate checksums every time a command based on checksums calculation is executed;
16
14
  * If performance becomes an issue, we can implement a more sophisticated solution, eg. recalculate checksums only when files in the theme directory have changed.
17
15
  */
18
- const checksums = await computeChecksumsFromSource(executionContext.themeRootDir);
19
- await ThemeChecksumsUtils.createThemeCurrentChecksumsFile(executionContext.themeRootDir, checksums);
16
+ await new ThemeChecksums(executionContext.themeRootDir).updateCurrentChecksums();
20
17
  };
21
18
  export default ensureThemeChecksumsUpToDate;
@@ -31,6 +31,7 @@ const ensureThemesActionsHook = async ({ Command, argv }) => {
31
31
  console.error('Unauthorized. Please authorize first.');
32
32
  const cliAuthTokensApi = useApi(CLI_AUTH_TOKENS_API_NAME);
33
33
  await promptForToken(cliAuthTokensApi);
34
+ //TODO loader
34
35
  await themesActionsApi.ensureThemesActions({
35
36
  credentials,
36
37
  themeId
@@ -3,5 +3,6 @@ export const THEME_COMMANDS_THAT_REQUIRED_ACTIONS_LIST = [
3
3
  THEME_COMMANDS_NAME.pull,
4
4
  THEME_COMMANDS_NAME.init,
5
5
  THEME_COMMANDS_NAME.push,
6
+ THEME_COMMANDS_NAME.delete,
6
7
  THEME_COMMANDS_NAME.showChanges
7
8
  ];
@@ -1,15 +1,21 @@
1
- import { ThemeListCommand } from './commands/theme_list_command.js';
2
- import { ThemePullCommand } from './commands/theme_pull_command.js';
3
- import { ThemeInitCommand } from './commands/theme_init_command.js';
1
+ import { ThemeListCommand } from './commands/list/theme_list_command.js';
2
+ import { ThemePullCommand } from './commands/pull/theme_pull_command.js';
3
+ import { ThemeInitCommand } from './commands/init/theme_init_command.js';
4
4
  import { THEME_COMMANDS_NAME } from './commands/theme_commands_constants.js';
5
- import { ThemePushCommand } from './commands/theme_push_command.js';
5
+ import { ThemePushCommand } from './commands/push/theme_push_command.js';
6
6
  import { ThemeShowChangesCommand } from './commands/theme_show_changes_command.js';
7
7
  import { ThemeVerifyCommand } from './commands/theme_verify_command.js';
8
+ import { ThemeInfoCommand } from './commands/info/theme_info_command.js';
9
+ import { ThemeDeleteCommand } from './commands/delete/theme_delete_command.js';
10
+ import { ThemePublishCommand } from './commands/publish/theme_publish_command.js';
8
11
  export const COMMANDS = {
9
12
  [THEME_COMMANDS_NAME.list]: ThemeListCommand,
10
13
  [THEME_COMMANDS_NAME.pull]: ThemePullCommand,
11
14
  [THEME_COMMANDS_NAME.init]: ThemeInitCommand,
12
15
  [THEME_COMMANDS_NAME.push]: ThemePushCommand,
13
16
  [THEME_COMMANDS_NAME.showChanges]: ThemeShowChangesCommand,
14
- [THEME_COMMANDS_NAME.verify]: ThemeVerifyCommand
17
+ [THEME_COMMANDS_NAME.verify]: ThemeVerifyCommand,
18
+ [THEME_COMMANDS_NAME.info]: ThemeInfoCommand,
19
+ [THEME_COMMANDS_NAME.delete]: ThemeDeleteCommand,
20
+ [THEME_COMMANDS_NAME.publish]: ThemePublishCommand
15
21
  };
@@ -1,13 +1,9 @@
1
+ import { platformSeparator } from '../../../utils/path_utils.js';
1
2
  export const FILES_MODIFICATION_TYPES = {
2
3
  add: 'add',
3
4
  remove: 'remove',
4
5
  edit: 'edit'
5
6
  };
6
7
  export const DEFAULT_PERMISSION_FOR_ALL_FILES_KEY = '*';
7
- export const DEFAULT_PERMISSION_FOR_DIRECTORY_KEY = '*/';
8
+ export const DEFAULT_PERMISSION_FOR_DIRECTORY_KEY = `*${platformSeparator}`;
8
9
  export const PERMISSION_KEY = '__permission__';
9
- export const DEFAULT_DIRECTORY_STRUCTURE_PERMISSION = {
10
- canAdd: false,
11
- canEdit: false,
12
- canDelete: false
13
- };
@@ -2,7 +2,7 @@ import { join, looksLikeDirectory, platformSeparator } from '../../../utils/path
2
2
  import { fileExists, getAllFilesAndDirectoriesInside, isDirectory } from '../../../utils/fs/fs_utils.js';
3
3
  import uniq from 'lodash/uniq.js';
4
4
  import { computeFileChecksum } from '../../../utils/checksums/checksums_utils.js';
5
- import { DEFAULT_DIRECTORY_STRUCTURE_PERMISSION, DEFAULT_PERMISSION_FOR_ALL_FILES_KEY, DEFAULT_PERMISSION_FOR_DIRECTORY_KEY, FILES_MODIFICATION_TYPES, PERMISSION_KEY } from './directory_validator_constants.js';
5
+ import { DEFAULT_PERMISSION_FOR_ALL_FILES_KEY, DEFAULT_PERMISSION_FOR_DIRECTORY_KEY, FILES_MODIFICATION_TYPES, PERMISSION_KEY } from './directory_validator_constants.js';
6
6
  import { CHECKSUM_KEY } from '../../../utils/checksums/checksums_utils_constants.js';
7
7
  import _ from 'lodash';
8
8
  export const validateDirectory = async ({ rootDirectory, permissions, checksums }) => {
@@ -32,7 +32,7 @@ const _checkPermissions = async ({ permissionPart, permissionParts, parts = [],
32
32
  const files = uniq([
33
33
  ...filesInsideCurrentDirectory,
34
34
  //TODO fix another way
35
- ...Object.keys(checksumsPart ?? {}).filter((key) => key !== CHECKSUM_KEY && key !== './')
35
+ ...Object.keys(checksumsPart ?? {}).filter((key) => key !== CHECKSUM_KEY && key !== `.${platformSeparator}`)
36
36
  ]);
37
37
  const parentPath = join(...parts);
38
38
  const filesInsideCurrentDirectoryObject = {};
@@ -47,16 +47,6 @@ const _checkPermissions = async ({ permissionPart, permissionParts, parts = [],
47
47
  permissionParts,
48
48
  permissions
49
49
  });
50
- if (!permissionKey) {
51
- console.log('permission', permission);
52
- console.log('parts', parts);
53
- console.log('permissionPart', permissionPart);
54
- console.log('permissionParts', permissionParts);
55
- console.log('permissions', permissions);
56
- console.log('file', file);
57
- console.log('fullPath', fullPath);
58
- // console.log('permission', permission, 'permissionKey', permissionKey);
59
- }
60
50
  const action = await _checkPermission({
61
51
  permission: permission[PERMISSION_KEY],
62
52
  path: file,
@@ -134,14 +124,8 @@ const _checkPermission = async ({ permission, path, checksumsPart, filesInDirect
134
124
  const _getClosestPermission = (permissions, parts) => {
135
125
  if (!parts.length) {
136
126
  return {
137
- permission: {
138
- [DEFAULT_PERMISSION_FOR_DIRECTORY_KEY]: {
139
- [PERMISSION_KEY]: DEFAULT_DIRECTORY_STRUCTURE_PERMISSION
140
- },
141
- [DEFAULT_PERMISSION_FOR_ALL_FILES_KEY]: {
142
- [PERMISSION_KEY]: DEFAULT_DIRECTORY_STRUCTURE_PERMISSION
143
- }
144
- }
127
+ permission: permissions[DEFAULT_PERMISSION_FOR_ALL_FILES_KEY],
128
+ permissionKey: DEFAULT_PERMISSION_FOR_ALL_FILES_KEY
145
129
  };
146
130
  }
147
131
  const permissionPart = _.at(permissions, parts.join('.'))?.[0];
@@ -162,19 +146,17 @@ const _getClosestPermission = (permissions, parts) => {
162
146
  export const mapToPermissionsTree = (paths) => {
163
147
  const tree = {};
164
148
  Object.entries(paths).forEach(([path, permissions]) => {
165
- //TODO Cross platform
166
- const parts = path.split('/').filter(Boolean);
149
+ const parts = path.split(platformSeparator).filter(Boolean);
167
150
  let currentLevel = tree;
168
151
  parts.forEach((part, index) => {
169
152
  if (index === parts.length - 1) {
170
- // TODO cross platform
171
- const finalPart = path.endsWith('/') ? `${part}/` : part;
153
+ const finalPart = path.endsWith(platformSeparator) ? join(part, platformSeparator) : part;
172
154
  if (!currentLevel[finalPart])
173
155
  currentLevel[finalPart] = {};
174
156
  currentLevel[finalPart][PERMISSION_KEY] = { ...permissions };
175
157
  }
176
158
  if (index !== parts.length - 1) {
177
- const finalPart = `${part}/`;
159
+ const finalPart = join(part, platformSeparator);
178
160
  if (!currentLevel[finalPart])
179
161
  currentLevel[finalPart] = {};
180
162
  currentLevel = currentLevel[finalPart];
@@ -0,0 +1,2 @@
1
+ import { Box as InkBox } from 'ink';
2
+ export const Box = InkBox;
@@ -0,0 +1,30 @@
1
+ export const CSS_COLOR_TOKENS_VALUES = {
2
+ theme1: '#E23F46',
3
+ theme2: '#24B26F',
4
+ theme3: '#F2C533',
5
+ theme4: '#33A2F2',
6
+ theme5: '#FFEA00',
7
+ theme6: '#D75F5F',
8
+ theme7: '#5FD7FF',
9
+ theme8: '#EEEEEE',
10
+ theme9: '#BFBFBF',
11
+ theme10: '#000000'
12
+ };
13
+ export const CSS_TEXT_COLORS = {
14
+ danger: CSS_COLOR_TOKENS_VALUES.theme1,
15
+ success: CSS_COLOR_TOKENS_VALUES.theme2,
16
+ warning: CSS_COLOR_TOKENS_VALUES.theme3,
17
+ warningLight: CSS_COLOR_TOKENS_VALUES.theme5,
18
+ info: CSS_COLOR_TOKENS_VALUES.theme4,
19
+ infoLight: CSS_COLOR_TOKENS_VALUES.theme7,
20
+ invert: CSS_COLOR_TOKENS_VALUES.theme10
21
+ };
22
+ export const CSS_BORDER_COLORS = {
23
+ danger: CSS_COLOR_TOKENS_VALUES.theme1,
24
+ warning: CSS_COLOR_TOKENS_VALUES.theme3,
25
+ info: CSS_COLOR_TOKENS_VALUES.theme9,
26
+ success: CSS_COLOR_TOKENS_VALUES.theme2
27
+ };
28
+ export const CSS_BACKGROUND_COLORS = {
29
+ danger: CSS_COLOR_TOKENS_VALUES.theme6
30
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { Text } from './text.js';
3
+ import { CSS_TEXT_COLORS } from './color_constants.js';
4
+ export const Command = ({ children }) => {
5
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.infoLight }, children);
6
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { Text } from './text.js';
3
+ import { CSS_TEXT_COLORS } from './color_constants.js';
4
+ export const FileName = ({ children }) => {
5
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.warningLight }, children);
6
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { Text } from './text.js';
3
+ import { CSS_TEXT_COLORS } from './color_constants.js';
4
+ export const Flag = ({ children }) => {
5
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.infoLight }, children);
6
+ };
@@ -0,0 +1,7 @@
1
+ import logSymbols from 'log-symbols';
2
+ import React from 'react';
3
+ import { Text } from '../text.js';
4
+ import { CSS_TEXT_COLORS } from '../color_constants.js';
5
+ export const ErrorIcon = () => {
6
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.danger }, logSymbols.error);
7
+ };
@@ -0,0 +1,7 @@
1
+ import logSymbols from 'log-symbols';
2
+ import React from 'react';
3
+ import { Text } from '../text.js';
4
+ import { CSS_TEXT_COLORS } from '../color_constants.js';
5
+ export const InfoIcon = () => {
6
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.infoLight }, logSymbols.info);
7
+ };
@@ -0,0 +1,7 @@
1
+ import logSymbols from 'log-symbols';
2
+ import React from 'react';
3
+ import { Text } from '../text.js';
4
+ import { CSS_TEXT_COLORS } from '../color_constants.js';
5
+ export const SuccessIcon = () => {
6
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.success }, logSymbols.success);
7
+ };
@@ -0,0 +1,7 @@
1
+ import logSymbols from 'log-symbols';
2
+ import React from 'react';
3
+ import { Text } from '../text.js';
4
+ import { CSS_TEXT_COLORS } from '../color_constants.js';
5
+ export const WarningIcon = () => {
6
+ return React.createElement(Text, { color: CSS_TEXT_COLORS.warning }, logSymbols.warning);
7
+ };
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import InkLink from 'ink-link';
3
+ import { CSS_TEXT_COLORS } from './color_constants.js';
4
+ import { Text } from './text.js';
5
+ export const Link = ({ url, children }) => {
6
+ return (React.createElement(InkLink, { url: url },
7
+ React.createElement(Text, { color: CSS_TEXT_COLORS.info }, children)));
8
+ };
@@ -0,0 +1,10 @@
1
+ import { LIST_TYPES } from './list_constants.js';
2
+ import { Box } from '../box.js';
3
+ import React from 'react';
4
+ import { ListItem } from './list_item.js';
5
+ export const List = ({ type = LIST_TYPES.unordered, items }) => {
6
+ return (React.createElement(Box, { flexDirection: "column", gap: 1, width: "100%", marginLeft: 2 }, items.map((item, index) => {
7
+ const itemContent = typeof item === 'string' ? item : item.content;
8
+ return (React.createElement(ListItem, { key: index, index: index, type: type }, itemContent));
9
+ })));
10
+ };
@@ -0,0 +1,4 @@
1
+ export const LIST_TYPES = {
2
+ ordered: 'ordered',
3
+ unordered: 'unordered'
4
+ };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { Box } from '../box.js';
3
+ import { Text } from '../text.js';
4
+ import { LIST_TYPES } from './list_constants.js';
5
+ export const ListItem = ({ children, index, type }) => {
6
+ const indicator = type === LIST_TYPES.ordered ? `${index + 1}. ` : '•';
7
+ return (React.createElement(Box, { key: index },
8
+ React.createElement(Text, null, indicator),
9
+ React.createElement(Box, { marginLeft: 1, flexGrow: 1 },
10
+ React.createElement(Text, null, children))));
11
+ };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { MessageBox } from './message_box.js';
3
+ import { MESSAGE_BOX_VARIANTS } from './message_box_constants.js';
4
+ export const Error = ({ children, ...props }) => (React.createElement(MessageBox, { type: MESSAGE_BOX_VARIANTS.error, ...props }, children));
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { MessageBox } from './message_box.js';
3
+ import { MESSAGE_BOX_VARIANTS } from './message_box_constants.js';
4
+ export const Info = ({ children, ...props }) => (React.createElement(MessageBox, { type: MESSAGE_BOX_VARIANTS.info, ...props }, children));
@@ -0,0 +1,11 @@
1
+ import { Box } from '../box.js';
2
+ import { Text } from '../text.js';
3
+ import React from 'react';
4
+ import { MESSAGE_BOX_TYPE_TO_BORDER_COLORS, MESSAGE_BOX_TYPE_TO_ICON, MESSAGE_BOX_VARIANTS } from './message_box_constants.js';
5
+ export const MessageBox = ({ header, type = MESSAGE_BOX_VARIANTS.info, children }) => {
6
+ return (React.createElement(Box, { paddingY: 1, paddingX: 2, gap: 1, alignItems: "flex-start", borderStyle: "round", display: "flex", flexWrap: "nowrap", borderColor: MESSAGE_BOX_TYPE_TO_BORDER_COLORS[type] },
7
+ React.createElement(Box, { width: "auto" }, MESSAGE_BOX_TYPE_TO_ICON[type]),
8
+ React.createElement(Box, { display: "flex", flexDirection: "column", gap: 1 },
9
+ header ? React.createElement(Text, { bold: true }, header) : null,
10
+ children)));
11
+ };
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { InfoIcon } from '../icons/info_icon.js';
3
+ import { WarningIcon } from '../icons/warning_icon.js';
4
+ import { SuccessIcon } from '../icons/success_icon.js';
5
+ import { ErrorIcon } from '../icons/error_icon.js';
6
+ import { CSS_BORDER_COLORS } from '../color_constants.js';
7
+ export const MESSAGE_BOX_VARIANTS = {
8
+ info: 'info',
9
+ warning: 'warning',
10
+ success: 'success',
11
+ error: 'error'
12
+ };
13
+ export const MESSAGE_BOX_TYPE_TO_ICON = {
14
+ [MESSAGE_BOX_VARIANTS.info]: React.createElement(InfoIcon, null),
15
+ [MESSAGE_BOX_VARIANTS.warning]: React.createElement(WarningIcon, null),
16
+ [MESSAGE_BOX_VARIANTS.success]: React.createElement(SuccessIcon, null),
17
+ [MESSAGE_BOX_VARIANTS.error]: React.createElement(ErrorIcon, null)
18
+ };
19
+ export const MESSAGE_BOX_TYPE_TO_BORDER_COLORS = {
20
+ [MESSAGE_BOX_VARIANTS.info]: CSS_BORDER_COLORS.info,
21
+ [MESSAGE_BOX_VARIANTS.warning]: CSS_BORDER_COLORS.warning,
22
+ [MESSAGE_BOX_VARIANTS.success]: CSS_BORDER_COLORS.success,
23
+ [MESSAGE_BOX_VARIANTS.error]: CSS_BORDER_COLORS.danger
24
+ };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { MessageBox } from './message_box.js';
3
+ import { MESSAGE_BOX_VARIANTS } from './message_box_constants.js';
4
+ export const Success = ({ children, ...props }) => (React.createElement(MessageBox, { type: MESSAGE_BOX_VARIANTS.success, ...props }, children));
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { MessageBox } from './message_box.js';
3
+ import { MESSAGE_BOX_VARIANTS } from './message_box_constants.js';
4
+ export const Warning = ({ children, ...props }) => (React.createElement(MessageBox, { type: MESSAGE_BOX_VARIANTS.warning, ...props }, children));
@@ -0,0 +1,11 @@
1
+ import inquirer from 'inquirer';
2
+ export const promptConfirmation = async (message) => {
3
+ return inquirer.prompt([
4
+ {
5
+ type: 'confirm',
6
+ name: 'proceed',
7
+ message,
8
+ default: true
9
+ }
10
+ ]);
11
+ };
@@ -0,0 +1,10 @@
1
+ import inquirer from 'inquirer';
2
+ export const promptInput = (message) => {
3
+ return inquirer.prompt([
4
+ {
5
+ type: 'input',
6
+ name: 'input',
7
+ message
8
+ }
9
+ ]);
10
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { Box } from '../box.js';
3
+ import { Text } from '../text.js';
4
+ export const TCell = ({ children, ...rest }) => {
5
+ return (React.createElement(Box, { ...rest },
6
+ React.createElement(Text, null, children)));
7
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { Box } from '../box.js';
3
+ import { CSS_BORDER_COLORS } from '../color_constants.js';
4
+ import { TCell } from './t_cell.js';
5
+ export const THeader = ({ data }) => {
6
+ return (React.createElement(Box, { borderStyle: "single", borderColor: CSS_BORDER_COLORS.info, borderBottom: true, borderLeft: false, borderRight: false, borderTop: false, display: "flex" }, data.map(({ width, content }, index) => {
7
+ return (React.createElement(TCell, { key: index, paddingLeft: 2, paddingTop: 1, paddingBottom: 1, width: width }, content));
8
+ })));
9
+ };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { Box } from '../box.js';
3
+ export const TRow = ({ children }) => {
4
+ return (React.createElement(Box, { width: "100%", display: "flex" }, children));
5
+ };
@@ -0,0 +1,18 @@
1
+ import { Box } from '../box.js';
2
+ import { THeader } from './t_header.js';
3
+ import React from 'react';
4
+ import { TRow } from './t_row.js';
5
+ import { TCell } from './t_cell.js';
6
+ export const Table = ({ data }) => {
7
+ const headersData = data?.headers || [];
8
+ const rowsData = data?.rows || [];
9
+ return (React.createElement(Box, { display: "flex", flexDirection: "column", gap: 1 },
10
+ headersData.length ? React.createElement(THeader, { data: headersData }) : null,
11
+ rowsData.length
12
+ ? rowsData.map((rows, index) => {
13
+ return (React.createElement(TRow, { key: index }, rows.map((cellContent, cellIndex) => {
14
+ return (React.createElement(TCell, { paddingLeft: 2, key: `${index}-${cellIndex}`, width: headersData[cellIndex]?.width }, cellContent));
15
+ })));
16
+ })
17
+ : null));
18
+ };
@@ -0,0 +1,2 @@
1
+ import { Text as InkText } from 'ink';
2
+ export const Text = InkText;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { Box } from './box.js';
3
+ import { Text } from './text.js';
4
+ export const Tip = ({ children }) => {
5
+ return (React.createElement(Box, null,
6
+ React.createElement(Text, null,
7
+ React.createElement(Text, { bold: true }, "Tip: "),
8
+ children)));
9
+ };
@@ -0,0 +1,9 @@
1
+ import { Box } from '../box.js';
2
+ import { Text } from '../text.js';
3
+ import React from 'react';
4
+ export const UiComponentBox = ({ children, name }) => {
5
+ return (React.createElement(Box, { flexDirection: "column", gap: 1 },
6
+ React.createElement(Box, null,
7
+ React.createElement(Text, { bold: true }, name)),
8
+ React.createElement(Box, null, children)));
9
+ };
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { Box } from '../box.js';
3
+ import { Command } from '../command.js';
4
+ import { UiComponentBox } from './ui_component_box.js';
5
+ import { FileName } from '../file_name.js';
6
+ import { ErrorIcon } from '../icons/error_icon.js';
7
+ import { WarningIcon } from '../icons/warning_icon.js';
8
+ import { InfoIcon } from '../icons/info_icon.js';
9
+ import { SuccessIcon } from '../icons/success_icon.js';
10
+ import { Flag } from '../flag.js';
11
+ import { Link } from '../link.js';
12
+ import { List } from '../list/list.js';
13
+ import { LIST_TYPES } from '../list/list_constants.js';
14
+ import { Tip } from '../tip.js';
15
+ import { MessageBox } from '../message_box/message_box.js';
16
+ import { MESSAGE_BOX_VARIANTS } from '../message_box/message_box_constants.js';
17
+ import { TABLE_COMPONENT_DATA } from './ui_dump_constants.js';
18
+ import { Table } from '../table/table.js';
19
+ export const UiDump = () => {
20
+ return (React.createElement(Box, { flexDirection: "column", gap: 1 },
21
+ React.createElement(UiComponentBox, { name: "Icons" },
22
+ React.createElement(ErrorIcon, null),
23
+ React.createElement(WarningIcon, null),
24
+ React.createElement(InfoIcon, null),
25
+ React.createElement(SuccessIcon, null)),
26
+ React.createElement(UiComponentBox, { name: "Command" },
27
+ React.createElement(Command, null, "shoper theme pull")),
28
+ React.createElement(UiComponentBox, { name: "Flag" },
29
+ React.createElement(Flag, null, "--pretty")),
30
+ React.createElement(UiComponentBox, { name: "FileName" },
31
+ React.createElement(FileName, null, "warning/toxic/unicorn.com")),
32
+ React.createElement(UiComponentBox, { name: "FileName" },
33
+ React.createElement(Link, { url: "https://shoper.pl" }, "Shoper")),
34
+ React.createElement(UiComponentBox, { name: "Unordered List" },
35
+ React.createElement(List, { items: [{ content: 'item' }, { content: 'item' }, { content: 'item' }, { content: 'item' }] })),
36
+ React.createElement(UiComponentBox, { name: "Unordered List" },
37
+ React.createElement(List, { type: LIST_TYPES.ordered, items: [{ content: 'item' }, { content: 'item' }, { content: 'item' }, { content: 'item' }] })),
38
+ React.createElement(UiComponentBox, { name: "FileName" },
39
+ React.createElement(Tip, null,
40
+ "To include Skinstore data in the future, add the `",
41
+ React.createElement(Flag, null, "--with-settings"),
42
+ "` flag.")),
43
+ React.createElement(UiComponentBox, { name: "Success Message Box" },
44
+ React.createElement(MessageBox, { header: "Theme created!", type: MESSAGE_BOX_VARIANTS.success }, "A copy of theme ID: 1 (\"Storefront\") has been created with the name \"Storefront Copy 2\" and ID: 5.")),
45
+ React.createElement(UiComponentBox, { name: "Info Message Box" },
46
+ React.createElement(MessageBox, { header: "Theme created!", type: MESSAGE_BOX_VARIANTS.info }, "A copy of theme ID: 1 (\"Storefront\") has been created with the name \"Storefront Copy 2\" and ID: 5.")),
47
+ React.createElement(UiComponentBox, { name: "Warnging Message Box" },
48
+ React.createElement(MessageBox, { header: "Theme created!", type: MESSAGE_BOX_VARIANTS.warning }, "A copy of theme ID: 1 (\"Storefront\") has been created with the name \"Storefront Copy 2\" and ID: 5.")),
49
+ React.createElement(UiComponentBox, { name: "Error Message Box" },
50
+ React.createElement(MessageBox, { header: "Theme created!", type: MESSAGE_BOX_VARIANTS.error }, "A copy of theme ID: 1 (\"Storefront\") has been created with the name \"Storefront Copy 2\" and ID: 5.")),
51
+ React.createElement(UiComponentBox, { name: "Table" },
52
+ React.createElement(Table, { data: TABLE_COMPONENT_DATA }))));
53
+ };
@@ -0,0 +1,21 @@
1
+ export const TABLE_COMPONENT_DATA = {
2
+ headers: [
3
+ {
4
+ content: 'Component',
5
+ width: 20
6
+ },
7
+ {
8
+ content: 'Description',
9
+ width: 20
10
+ },
11
+ {
12
+ content: 'Props',
13
+ width: 20
14
+ }
15
+ ],
16
+ rows: [
17
+ ['Box', 'A flexible', 'borderStyle'],
18
+ ['Box', 'A flexible', 'borderStyle'],
19
+ ['Box', 'A flexible', 'borderStyle']
20
+ ]
21
+ };
@@ -0,0 +1,11 @@
1
+ import { render as inkRender } from 'ink';
2
+ export const render = async (element, options) => {
3
+ const { waitUntilExit } = inkRender(element, options);
4
+ await waitUntilExit();
5
+ // We need to wait for other pending tasks -- unmounting of the ink component -- to complete
6
+ return new Promise((resolve) => setImmediate(resolve));
7
+ };
8
+ export const renderOnce = (element, options) => {
9
+ const instance = inkRender(element, options);
10
+ instance.unmount();
11
+ };
@@ -0,0 +1,19 @@
1
+ import { Text } from '../text.js';
2
+ import { List } from '../list/list.js';
3
+ import { ValidationErrorsUtils } from './validation_errors_utils.js';
4
+ import React from 'react';
5
+ export const ValidationErrorContent = ({ errors }) => {
6
+ if (typeof errors === 'string') {
7
+ return React.createElement(Text, null, errors);
8
+ }
9
+ if (Array.isArray(errors)) {
10
+ return (React.createElement(List, { items: errors.map((error) => ({
11
+ content: error
12
+ })) }));
13
+ }
14
+ return (React.createElement(List, { items: Object.entries(errors).map(([title, errorMessages]) => {
15
+ return {
16
+ content: `${title} - ${ValidationErrorsUtils.getErrorContent(errorMessages)}`
17
+ };
18
+ }) }));
19
+ };