@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.
- package/build/cli/auth/cli_auth_errors_factory.js +1 -1
- package/build/cli/auth/tokens/cli_auth_tokens_errors_factory.js +1 -1
- package/build/cli/auth/tokens/cli_auth_tokens_initalizer.js +1 -1
- package/build/cli/class/base_command.js +14 -0
- package/build/cli/class/errors/file_system_errors_factory.js +1 -1
- package/build/cli/class/errors/http/http_errors_constants.js +1 -0
- package/build/cli/class/errors/{http_errors_factory.js → http/http_errors_factory.js} +3 -2
- package/build/cli/commands/auth/cli_auth_add_token_command.js +22 -19
- package/build/cli/commands/auth/cli_auth_commands_constants.js +3 -0
- package/build/cli/commands/auth/cli_auth_commands_utils.js +46 -0
- package/build/cli/commands/auth/cli_auth_list_tokens_command.js +19 -6
- package/build/cli/commands/auth/cli_auth_remove_token_command.js +37 -13
- package/build/cli/commands/auth/cli_auth_switch_token_command.js +20 -11
- package/build/cli/commands/auth/ui/invalid_token_index_error.js +11 -0
- package/build/cli/commands/auth/ui/missing_credentials_error.js +9 -0
- package/build/cli/commands/auth/ui/missing_token_index_error.js +19 -0
- package/build/cli/commands/cli_ui_dump_command.js +11 -0
- package/build/cli/commands/cli_update_command.js +13 -4
- package/build/cli/commands/commands_constants.js +6 -4
- package/build/cli/core/cli_setup.js +33 -14
- package/build/cli/features/controls/controls_constants.js +12 -0
- package/build/cli/features/controls/controls_dto_mappers.js +55 -0
- package/build/cli/features/controls/ui/controls_mappers.js +62 -0
- package/build/cli/features/controls/ui/form.js +4 -0
- package/build/cli/features/controls/ui/form_constants.js +7 -0
- package/build/cli/features/controls/validators/greater_eq_than_validator.js +5 -0
- package/build/cli/features/controls/validators/length_validator.js +6 -0
- package/build/cli/features/controls/validators/required_validator.js +5 -0
- package/build/cli/features/controls/validators/validator_constants.js +13 -0
- package/build/cli/features/execution_context/execution_context_service.js +5 -5
- package/build/cli/features/http_requester/http_requester_initializer.js +1 -1
- package/build/cli/hooks/authorization/ensure_authorization_hook.js +2 -2
- package/build/cli/hooks/authorization/ensure_authorization_hook_constants.js +7 -8
- package/build/index.js +37 -19
- package/build/theme/class/archive/theme_archive.js +44 -0
- package/build/theme/class/archive/theme_archive_errors_factory.js +11 -0
- package/build/theme/class/checksums/theme_checksums.js +170 -0
- package/build/theme/{features/theme/utils → class}/checksums/theme_checksums_error_factory.js +1 -1
- package/build/theme/class/checksums/theme_checksums_utils.js +17 -0
- package/build/theme/class/fetch_resources/fetch_resources.js +1 -0
- package/build/theme/class/fetch_resources/fetch_resources_errors_factory.js +1 -1
- package/build/theme/class/fetch_resources/fetch_resources_utils.js +4 -1
- package/build/theme/class/files_upload/theme_files_upload.js +61 -0
- package/build/theme/class/files_upload/theme_files_upload_http_api.js +23 -0
- package/build/theme/commands/delete/theme_delete_command.js +97 -0
- package/build/theme/commands/delete/ui/theme_deleted_successfully.js +15 -0
- package/build/theme/commands/delete/ui/theme_deletion_warning.js +10 -0
- package/build/theme/commands/info/theme_info_command.js +79 -0
- package/build/theme/commands/info/theme_info_command_utils.js +39 -0
- package/build/theme/commands/init/theme_init_command.js +84 -0
- package/build/theme/commands/init/ui/theme_created_success.js +15 -0
- package/build/theme/commands/list/theme_list_command.js +25 -0
- package/build/theme/commands/list/theme_list_command_utils.js +27 -0
- package/build/theme/commands/publish/theme_publish_command.js +76 -0
- package/build/theme/commands/pull/theme_pull_command.js +174 -0
- package/build/theme/commands/pull/ui/theme_pull_id_mismatch_error.js +7 -0
- package/build/theme/commands/pull/ui/theme_pull_unpublished_changes_warning.js +10 -0
- package/build/theme/commands/pull/ui/theme_pulled_success.js +5 -0
- package/build/theme/commands/push/theme_push_command.js +112 -0
- package/build/theme/commands/push/ui/theme_push_skip_into.js +7 -0
- package/build/theme/commands/push/ui/theme_pushed_success.js +5 -0
- package/build/theme/commands/push/ui/theme_unpermitted_actions_error.js +12 -0
- package/build/theme/commands/theme_commands_constants.js +9 -6
- package/build/theme/commands/theme_verify_command.js +64 -22
- package/build/theme/commands/ui/invalid_theme_id.js +11 -0
- package/build/theme/commands/ui/missing_theme_files.js +15 -0
- package/build/theme/commands/ui/missing_theme_id_error.js +13 -0
- package/build/theme/commands/ui/ouside_of_theme_directory_context_error.js +7 -0
- package/build/theme/commands/ui/theme_directory_context_error.js +7 -0
- package/build/theme/commands/ui/theme_error.js +29 -0
- package/build/theme/commands/ui/theme_work_url_mismatch.js +17 -0
- package/build/theme/commands/ui/unpermitted_command_error.js +18 -0
- package/build/theme/features/theme/actions/api/theme_actions_api.js +3 -0
- package/build/theme/features/theme/actions/service/theme_actions_service.js +15 -3
- package/build/theme/features/theme/actions/service/theme_actions_service_constants.js +1 -0
- package/build/theme/features/theme/actions/theme_actions_constants.js +5 -2
- package/build/theme/features/theme/actions/theme_actions_initializer.js +1 -1
- package/build/theme/features/theme/actions/theme_actions_utils.js +60 -7
- package/build/theme/features/theme/delete/api/theme_delete_api.js +13 -0
- package/build/theme/features/theme/delete/http/theme_delete_http_api.js +17 -0
- package/build/theme/features/theme/delete/service/theme_delete_service.js +31 -0
- package/build/theme/features/theme/delete/theme_delete_constants.js +2 -0
- package/build/theme/features/theme/delete/theme_delete_initalizer.js +20 -0
- package/build/theme/features/theme/fetch/service/theme_fetch_service.js +30 -10
- package/build/theme/features/theme/info/theme_info_utils.js +9 -0
- package/build/theme/features/theme/init/service/theme_init_service.js +9 -4
- package/build/theme/features/theme/init/theme_init_initializer.js +3 -3
- package/build/theme/features/theme/merge/api/theme_merge_api.js +0 -12
- package/build/theme/features/theme/merge/service/theme_merge_service.js +20 -28
- package/build/theme/features/theme/push/service/theme_push_service.js +67 -166
- package/build/theme/features/theme/push/theme_push_constants.js +2 -0
- package/build/theme/features/theme/push/theme_push_errors_factory.js +7 -4
- package/build/theme/features/theme/push/theme_push_initializer.js +1 -7
- package/build/theme/features/theme/push/theme_push_utils.js +25 -0
- package/build/theme/features/theme/skinstore/api/theme_skinstore_api.js +19 -0
- package/build/theme/features/theme/skinstore/http/theme_skinstore_http_api.js +17 -0
- package/build/theme/features/theme/skinstore/service/theme_skinstore_service.js +32 -0
- package/build/theme/features/theme/skinstore/theme_publish_constants.js +4 -0
- package/build/theme/features/theme/skinstore/theme_skinstore_initialzier.js +20 -0
- package/build/theme/features/theme/utils/files_structure/theme_file_structure_errors_factory.js +10 -0
- package/build/theme/features/theme/utils/files_structure/theme_files_structure_utils.js +76 -0
- package/build/theme/features/theme/utils/hidden_directory/hidden_directory_utils.js +32 -0
- package/build/theme/features/theme/utils/meta_data/theme_meta_data_constants.js +1 -0
- package/build/theme/features/theme/utils/meta_data/theme_meta_data_error_factory.js +15 -0
- package/build/theme/features/theme/utils/meta_data/theme_meta_data_utils.js +39 -0
- package/build/theme/features/theme/utils/{directories → resources}/theme_resources_with_id_directory_utils.js +3 -14
- package/build/theme/features/theme/utils/theme_images_utils.js +1 -19
- package/build/theme/features/theme/verify/api/theme_verify_api.js +13 -0
- package/build/theme/features/theme/verify/http/theme_verify_http_api.js +30 -0
- package/build/theme/features/theme/verify/theme_verify_constants.js +2 -0
- package/build/theme/features/theme/verify/theme_verify_initializer.js +19 -0
- package/build/theme/features/theme/verify/verify/theme_verify_service.js +55 -0
- package/build/theme/features/themes/list/api/themes_list_api.js +3 -0
- package/build/theme/features/themes/list/services/themes_list_service.js +13 -7
- package/build/theme/hooks/{ensure_theme_meta_data_untouched.js → ensure_theme_meta_data_untouched_hook.js} +2 -2
- package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_constants.js +1 -2
- 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
- package/build/theme/hooks/themes_actions/ensure_themes_actions_hook.js +1 -0
- package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +1 -1
- package/build/theme/index.js +34 -8
- package/build/theme/utils/directory_validator/directory_validator_constants.js +2 -6
- package/build/theme/utils/directory_validator/directory_validator_utils.js +7 -25
- package/build/ui/box.js +2 -0
- package/build/ui/color_constants.js +30 -0
- package/build/ui/command.js +6 -0
- package/build/ui/file_name.js +6 -0
- package/build/ui/flag.js +6 -0
- package/build/ui/icons/error_icon.js +7 -0
- package/build/ui/icons/info_icon.js +7 -0
- package/build/ui/icons/success_icon.js +7 -0
- package/build/ui/icons/warning_icon.js +7 -0
- package/build/ui/link.js +8 -0
- package/build/ui/list/list.js +10 -0
- package/build/ui/list/list_constants.js +4 -0
- package/build/ui/list/list_item.js +11 -0
- package/build/ui/message_box/error.js +4 -0
- package/build/ui/message_box/info.js +4 -0
- package/build/ui/message_box/message_box.js +11 -0
- package/build/ui/message_box/message_box_constants.js +24 -0
- package/build/ui/message_box/success.js +4 -0
- package/build/ui/message_box/warning.js +4 -0
- package/build/ui/prompts/prompt_confirmation.js +11 -0
- package/build/ui/prompts/prompt_input.js +10 -0
- package/build/ui/table/t_cell.js +7 -0
- package/build/ui/table/t_header.js +9 -0
- package/build/ui/table/t_row.js +5 -0
- package/build/ui/table/table.js +18 -0
- package/build/ui/text.js +2 -0
- package/build/ui/tip.js +9 -0
- package/build/ui/ui_dump/ui_component_box.js +9 -0
- package/build/ui/ui_dump/ui_dump.js +53 -0
- package/build/ui/ui_dump/ui_dump_constants.js +21 -0
- package/build/ui/ui_utils.js +11 -0
- package/build/ui/validation_errors/validation_error_content.js +19 -0
- package/build/ui/validation_errors/validation_errors.js +21 -0
- package/build/ui/validation_errors/validation_errors_utils.js +17 -0
- package/build/utils/checksums/checksums_utils.js +9 -26
- package/build/utils/download_file/download_file_errors_factory.js +1 -1
- package/build/utils/download_file/download_file_utils.js +4 -2
- package/build/utils/fs/errors/stream_read_error.js +1 -1
- package/build/utils/fs/errors/stream_write_error.js +1 -1
- package/build/utils/fs/fs_utils.js +12 -1
- package/build/utils/path_utils.js +18 -2
- package/build/utils/platform_utils.js +3 -0
- package/build/utils/zip/create_zip_utils.js +1 -1
- package/build/utils/zip/errors/create_zip_error.js +1 -1
- package/build/utils/zip/errors/open_zip_error.js +1 -1
- package/oclif.config.js +3 -3
- package/package.json +14 -9
- package/build/cli/commands/files_diff_command.js +0 -174
- package/build/theme/commands/theme_init_command.js +0 -53
- package/build/theme/commands/theme_list_command.js +0 -16
- package/build/theme/commands/theme_pull_command.js +0 -126
- package/build/theme/commands/theme_push_command.js +0 -65
- package/build/theme/commands/theme_show_changes_command.js +0 -60
- package/build/theme/features/theme/directory/theme_directory_utils.js +0 -76
- package/build/theme/features/theme/publish/theme_publish_constants.js +0 -2
- package/build/theme/features/theme/utils/checksums/theme_checksums_utils.js +0 -94
- /package/build/cli/{features → class}/caches/cache_factory.js +0 -0
- /package/build/cli/{features → class}/caches/json_cache/json_cache.js +0 -0
- /package/build/cli/{features → class}/caches/memory_cache.js +0 -0
- /package/build/cli/class/errors/{app_error → app}/app_error.js +0 -0
- /package/build/cli/class/errors/{app_error → app}/app_error_constants.js +0 -0
- /package/build/theme/features/theme/{publish → skinstore}/theme_publish_utils.js +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Warning } from '../../../../ui/message_box/warning.js';
|
|
2
|
+
import { List } from '../../../../ui/list/list.js';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export const ThemePullUnpublishedChangesWarning = ({ changes }) => {
|
|
5
|
+
const items = changes.map(([action, path]) => ({
|
|
6
|
+
content: `${action} - ${path}`
|
|
7
|
+
}));
|
|
8
|
+
return (React.createElement(Warning, { header: "Warning: You have unpushed local changes in this theme directory. Pulling now may overwrite your local modifications." },
|
|
9
|
+
React.createElement(List, { items: items })));
|
|
10
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { BaseThemeCommand } from '../../class/base_theme_command.js';
|
|
2
|
+
import { CLI_AUTH_API_NAME } from '../../../cli/auth/cli_auth_constants.js';
|
|
3
|
+
import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../../cli/features/execution_context/execution_context_constants.js';
|
|
4
|
+
import { THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
|
|
5
|
+
import { THEME_PUSH_API_NAME } from '../../features/theme/push/theme_push_constants.js';
|
|
6
|
+
import { ThemeMetaDataUtils } from '../../features/theme/utils/meta_data/theme_meta_data_utils.js';
|
|
7
|
+
import { mapChecksumToTree } from '../../../utils/checksums/checksums_utils.js';
|
|
8
|
+
import { mapToPermissionsTree } from '../../utils/directory_validator/directory_validator_utils.js';
|
|
9
|
+
import { renderOnce } from '../../../ui/ui_utils.js';
|
|
10
|
+
import { UnpermittedCommandError } from '../ui/unpermitted_command_error.js';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { OutsideOfThemeDirectoryContextError } from '../ui/ouside_of_theme_directory_context_error.js';
|
|
13
|
+
import { MissingCredentialsError } from '../../../cli/commands/auth/ui/missing_credentials_error.js';
|
|
14
|
+
import { ThemePushedSuccess } from './ui/theme_pushed_success.js';
|
|
15
|
+
import ora from 'ora';
|
|
16
|
+
import { ThemePushSkipInfo } from './ui/theme_push_skip_into.js';
|
|
17
|
+
import { ThemeUnpermittedActionsError } from './ui/theme_unpermitted_actions_error.js';
|
|
18
|
+
import { ThemeFilesStructureUtils } from '../../features/theme/utils/files_structure/theme_files_structure_utils.js';
|
|
19
|
+
import { ThemeInfoUtils } from '../../features/theme/info/theme_info_utils.js';
|
|
20
|
+
import { ThemeChecksums } from '../../class/checksums/theme_checksums.js';
|
|
21
|
+
import { ThemeFilesUpload } from '../../class/files_upload/theme_files_upload.js';
|
|
22
|
+
import { ThemeFilesUploadHttpApi } from '../../class/files_upload/theme_files_upload_http_api.js';
|
|
23
|
+
import { HTTP_REQUESTER_API_NAME } from '@dreamcommerce/star_core';
|
|
24
|
+
import { MissingThemeFiles } from '../ui/missing_theme_files.js';
|
|
25
|
+
import { SHOPER_THEME_METADATA_DIR } from '../../constants/directory_contstants.js';
|
|
26
|
+
import { THEME_FILES_STRUCTURE_FILE_NAME } from '../../features/theme/theme_constants.js';
|
|
27
|
+
import { ThemeError } from '../ui/theme_error.js';
|
|
28
|
+
export class ThemePushCommand extends BaseThemeCommand {
|
|
29
|
+
static summary = 'Uploads your local theme files to the store and overwrites the current version of the theme in your store.';
|
|
30
|
+
static description = 'Check your local changes before pushing.\n\nYou must run this command from a specific theme directory (ID not needed).';
|
|
31
|
+
static examples = [
|
|
32
|
+
{
|
|
33
|
+
description: 'This will replace the store version with your local copy.',
|
|
34
|
+
command: '<%= config.bin %> <%= command.id %>'
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
async run() {
|
|
38
|
+
const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
|
|
39
|
+
const themePushApi = this.getApi(THEME_PUSH_API_NAME);
|
|
40
|
+
const themeActionsApi = this.getApi(THEME_ACTIONS_API_NAME);
|
|
41
|
+
const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
|
|
42
|
+
const credentials = cliAuthApi.getCredentials();
|
|
43
|
+
if (!credentials) {
|
|
44
|
+
renderOnce(React.createElement(MissingCredentialsError, null));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const executionContext = await executionContextApi.getExecutionContext();
|
|
48
|
+
if (executionContext.type !== EXECUTION_CONTEXTS.theme) {
|
|
49
|
+
renderOnce(React.createElement(OutsideOfThemeDirectoryContextError, null));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let spinner;
|
|
53
|
+
try {
|
|
54
|
+
const themeChecksums = new ThemeChecksums(executionContext.themeRootDir);
|
|
55
|
+
await ThemeMetaDataUtils.ensureThemeWorkUrlMatch(executionContext.themeRootDir, credentials.shopUrl);
|
|
56
|
+
const pushAction = themeActionsApi.getThemeAction({
|
|
57
|
+
actionType: THEME_ACTIONS_TYPES.push,
|
|
58
|
+
themeId: executionContext.themeId,
|
|
59
|
+
credentials
|
|
60
|
+
});
|
|
61
|
+
if (!pushAction) {
|
|
62
|
+
renderOnce(React.createElement(UnpermittedCommandError, { themeId: executionContext.themeId, commandName: "push" }));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const initialChecksums = await themeChecksums.getInitialChecksums();
|
|
66
|
+
const permissions = await ThemeFilesStructureUtils.getFilesPermissions(executionContext.themeRootDir);
|
|
67
|
+
const themeFilesUploadApi = new ThemeFilesUpload({
|
|
68
|
+
themeRootDir: executionContext.themeRootDir,
|
|
69
|
+
credentials,
|
|
70
|
+
themeFilesUploadHttpApi: new ThemeFilesUploadHttpApi(this.getApi(HTTP_REQUESTER_API_NAME))
|
|
71
|
+
});
|
|
72
|
+
if (!initialChecksums || !permissions)
|
|
73
|
+
this.error('Theme checksums or permissions not found. Please ensure you are in the correct theme directory.');
|
|
74
|
+
if (!(await themeChecksums.hasThemeBeenModified())) {
|
|
75
|
+
renderOnce(React.createElement(ThemePushSkipInfo, null));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const validationResult = await ThemeFilesStructureUtils.validateThemeDirectoryStructure({
|
|
79
|
+
//TDO przeniesc do theme checksums
|
|
80
|
+
checksums: mapChecksumToTree(initialChecksums),
|
|
81
|
+
permissions: mapToPermissionsTree(permissions),
|
|
82
|
+
rootDirectory: executionContext.themeRootDir
|
|
83
|
+
});
|
|
84
|
+
//TODO jak wysyla folder z nazwa posiadajaco \ na windows, wychodzimy
|
|
85
|
+
//TODO validacja folderów przed pushem
|
|
86
|
+
if (!validationResult.isValid) {
|
|
87
|
+
renderOnce(React.createElement(ThemeUnpermittedActionsError, { unpermittedActions: validationResult.unpermittedActions }));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const filesStructure = await ThemeFilesStructureUtils.getThemeFilesStructure(executionContext.themeRootDir);
|
|
91
|
+
if (!filesStructure) {
|
|
92
|
+
renderOnce(React.createElement(MissingThemeFiles, { files: `${SHOPER_THEME_METADATA_DIR}/${THEME_FILES_STRUCTURE_FILE_NAME}` }));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
spinner = ora('Pushing theme...').start();
|
|
96
|
+
await themePushApi.push({
|
|
97
|
+
credentials,
|
|
98
|
+
filesStructure,
|
|
99
|
+
pushAction,
|
|
100
|
+
themeChecksums,
|
|
101
|
+
executionContext,
|
|
102
|
+
themeFilesUploadApi
|
|
103
|
+
});
|
|
104
|
+
spinner.stop();
|
|
105
|
+
renderOnce(React.createElement(ThemePushedSuccess, { themeName: await ThemeInfoUtils.getThemeName(executionContext.themeRootDir) }));
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
spinner?.stop();
|
|
109
|
+
renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Info } from '../../../../ui/message_box/info.js';
|
|
3
|
+
import { Text } from '../../../../ui/text.js';
|
|
4
|
+
export const ThemePushSkipInfo = () => {
|
|
5
|
+
return (React.createElement(Info, null,
|
|
6
|
+
React.createElement(Text, null, "Nothing to push, skipped.")));
|
|
7
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { List } from '../../../../ui/list/list.js';
|
|
2
|
+
import { Error } from '../../../../ui/message_box/error.js';
|
|
3
|
+
import { Text } from '../../../../ui/text.js';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
export const ThemeUnpermittedActionsError = ({ unpermittedActions }) => {
|
|
6
|
+
const items = unpermittedActions.map((action) => ({
|
|
7
|
+
content: `${action.type} - ${action.relativePath}`
|
|
8
|
+
}));
|
|
9
|
+
return (React.createElement(Error, { header: "Theme validation error" },
|
|
10
|
+
React.createElement(Text, null, "Theme file structure is not valid. The following actions are not permitted:"),
|
|
11
|
+
React.createElement(List, { items: items })));
|
|
12
|
+
};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
export const THEME_TOPIC_NAME = 'theme';
|
|
1
2
|
export const THEME_COMMANDS_NAME = {
|
|
2
|
-
list:
|
|
3
|
-
pull:
|
|
4
|
-
init:
|
|
5
|
-
push:
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
list: `${THEME_TOPIC_NAME}:list`,
|
|
4
|
+
pull: `${THEME_TOPIC_NAME}:pull`,
|
|
5
|
+
init: `${THEME_TOPIC_NAME}:init`,
|
|
6
|
+
push: `${THEME_TOPIC_NAME}:push`,
|
|
7
|
+
verify: `${THEME_TOPIC_NAME}:verify`,
|
|
8
|
+
info: `${THEME_TOPIC_NAME}:info`,
|
|
9
|
+
delete: `${THEME_TOPIC_NAME}:delete`,
|
|
10
|
+
publish: `${THEME_TOPIC_NAME}:publish`
|
|
8
11
|
};
|
|
@@ -1,43 +1,85 @@
|
|
|
1
1
|
import { BaseThemeCommand } from '../class/base_theme_command.js';
|
|
2
2
|
import { CLI_AUTH_API_NAME } from '../../cli/auth/cli_auth_constants.js';
|
|
3
3
|
import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../cli/features/execution_context/execution_context_constants.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { ThemeFilesStructureUtils } from '../features/theme/utils/files_structure/theme_files_structure_utils.js';
|
|
5
|
+
import { ThemeChecksums } from '../class/checksums/theme_checksums.js';
|
|
6
|
+
import { THEME_VERIFY_API_NAME } from '../features/theme/verify/theme_verify_constants.js';
|
|
7
|
+
import { THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../features/theme/actions/theme_actions_constants.js';
|
|
8
|
+
import { ThemeFilesUpload } from '../class/files_upload/theme_files_upload.js';
|
|
9
|
+
import { ThemeFilesUploadHttpApi } from '../class/files_upload/theme_files_upload_http_api.js';
|
|
10
|
+
import { HTTP_REQUESTER_API_NAME } from '@dreamcommerce/star_core';
|
|
11
|
+
import { renderOnce } from '../../ui/ui_utils.js';
|
|
12
|
+
import { MissingThemeFiles } from './ui/missing_theme_files.js';
|
|
13
|
+
import { SHOPER_THEME_METADATA_DIR } from '../constants/directory_contstants.js';
|
|
14
|
+
import { THEME_FILES_STRUCTURE_FILE_NAME } from '../features/theme/theme_constants.js';
|
|
15
|
+
import React from 'react';
|
|
16
|
+
import { Success } from '../../ui/message_box/success.js';
|
|
17
|
+
import { MissingCredentialsError } from '../../cli/commands/auth/ui/missing_credentials_error.js';
|
|
18
|
+
import { OutsideOfThemeDirectoryContextError } from './ui/ouside_of_theme_directory_context_error.js';
|
|
19
|
+
import ora from 'ora';
|
|
20
|
+
import { ThemeError } from './ui/theme_error.js';
|
|
8
21
|
export class ThemeVerifyCommand extends BaseThemeCommand {
|
|
9
22
|
static description = 'Verify theme files structure';
|
|
10
23
|
async run() {
|
|
11
24
|
const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
|
|
12
25
|
const credentials = cliAuthApi.getCredentials();
|
|
13
26
|
const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
|
|
14
|
-
if (!credentials)
|
|
15
|
-
|
|
27
|
+
if (!credentials) {
|
|
28
|
+
renderOnce(React.createElement(MissingCredentialsError, null));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
16
31
|
const executionContext = await executionContextApi.getExecutionContext();
|
|
17
|
-
if (executionContext.type !== EXECUTION_CONTEXTS.theme)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
32
|
+
if (executionContext.type !== EXECUTION_CONTEXTS.theme) {
|
|
33
|
+
renderOnce(React.createElement(OutsideOfThemeDirectoryContextError, null));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const themeChecksums = new ThemeChecksums(executionContext.themeRootDir);
|
|
37
|
+
const permissions = await ThemeFilesStructureUtils.getFilesPermissions(executionContext.themeRootDir);
|
|
38
|
+
if (!themeChecksums || !permissions)
|
|
22
39
|
this.error('Theme checksums or permissions not found. Please ensure you are in the correct theme directory.');
|
|
40
|
+
let spinner;
|
|
23
41
|
try {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
const themeActionsApi = this.getApi(THEME_ACTIONS_API_NAME);
|
|
43
|
+
const themeVerifyApi = this.getApi(THEME_VERIFY_API_NAME);
|
|
44
|
+
const themeFilesUploadApi = new ThemeFilesUpload({
|
|
45
|
+
themeRootDir: executionContext.themeRootDir,
|
|
46
|
+
credentials,
|
|
47
|
+
themeFilesUploadHttpApi: new ThemeFilesUploadHttpApi(this.getApi(HTTP_REQUESTER_API_NAME))
|
|
48
|
+
});
|
|
49
|
+
const verifyAction = themeActionsApi.getThemeAction({
|
|
50
|
+
actionType: THEME_ACTIONS_TYPES.verify,
|
|
51
|
+
themeId: executionContext.themeId,
|
|
52
|
+
credentials
|
|
53
|
+
});
|
|
54
|
+
const filesStructure = await ThemeFilesStructureUtils.getThemeFilesStructure(executionContext.themeRootDir);
|
|
55
|
+
if (!filesStructure) {
|
|
56
|
+
renderOnce(React.createElement(MissingThemeFiles, { files: `${SHOPER_THEME_METADATA_DIR}/${THEME_FILES_STRUCTURE_FILE_NAME}` }));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
spinner = ora('Verifying theme...').start();
|
|
60
|
+
const { isSuccess, messages } = await themeVerifyApi.verifyTheme({
|
|
61
|
+
verifyAction,
|
|
62
|
+
filesStructure,
|
|
63
|
+
executionContext,
|
|
64
|
+
credentials,
|
|
65
|
+
themeChecksums,
|
|
66
|
+
themeFilesUploadApi
|
|
28
67
|
});
|
|
29
|
-
|
|
30
|
-
|
|
68
|
+
spinner.stop();
|
|
69
|
+
if (isSuccess) {
|
|
70
|
+
renderOnce(React.createElement(Success, { header: `Success: Theme verified!` }));
|
|
31
71
|
}
|
|
32
72
|
else {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
73
|
+
renderOnce(React.createElement(ThemeError, { err: {
|
|
74
|
+
massages: messages
|
|
75
|
+
}, executionContext: executionContext }));
|
|
37
76
|
}
|
|
77
|
+
// await promptConfirmation('jolo');
|
|
38
78
|
}
|
|
39
79
|
catch (err) {
|
|
40
|
-
|
|
80
|
+
spinner?.stop();
|
|
81
|
+
// await promptConfirmation('jolo');
|
|
82
|
+
renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
|
|
41
83
|
}
|
|
42
84
|
}
|
|
43
85
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
2
|
+
import { Tip } from '../../../ui/tip.js';
|
|
3
|
+
import { Command } from '../../../ui/command.js';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
export const InvalidThemeIdError = ({ themeId }) => {
|
|
6
|
+
return (React.createElement(Error, { header: `Error: Invalid theme ID: ${themeId}` },
|
|
7
|
+
React.createElement(Tip, null,
|
|
8
|
+
"Run ",
|
|
9
|
+
React.createElement(Command, null, "shoper theme list"),
|
|
10
|
+
" to see available theme IDs.")));
|
|
11
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
3
|
+
import { Text } from '../../../ui/text.js';
|
|
4
|
+
import { List } from '../../../ui/list/list.js';
|
|
5
|
+
import { Command } from '../../../ui/command.js';
|
|
6
|
+
export const MissingThemeFiles = ({ files }) => {
|
|
7
|
+
return (React.createElement(Error, { header: `Error: Detected local changes in: ${Array.isArray(files) ? '' : files}` },
|
|
8
|
+
Array.isArray(files) ? (React.createElement(List, { items: files.map((file) => ({
|
|
9
|
+
content: file
|
|
10
|
+
})) })) : null,
|
|
11
|
+
React.createElement(Text, null,
|
|
12
|
+
"This file is managed by the system and should not be modified locally. Please revert it to its original version manually or run",
|
|
13
|
+
React.createElement(Command, null, "shoper theme pull"),
|
|
14
|
+
" to download the correct version from the server.")));
|
|
15
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
3
|
+
import { Box } from '../../../ui/box.js';
|
|
4
|
+
import { Tip } from '../../../ui/tip.js';
|
|
5
|
+
import { Command } from '../../../ui/command.js';
|
|
6
|
+
export const MissingThemeIdError = ({ children }) => {
|
|
7
|
+
return (React.createElement(Error, { header: "Error: Missing theme ID." },
|
|
8
|
+
React.createElement(Box, null, children),
|
|
9
|
+
React.createElement(Tip, null,
|
|
10
|
+
"Run ",
|
|
11
|
+
React.createElement(Command, null, "shoper theme list"),
|
|
12
|
+
" to see available themes and their IDs.")));
|
|
13
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
2
|
+
import { Text } from '../../../ui/text.js';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export const OutsideOfThemeDirectoryContextError = () => {
|
|
5
|
+
return (React.createElement(Error, null,
|
|
6
|
+
React.createElement(Text, null, "Error: Cannot run this command outside of a theme directory. Please run it inside a theme directory.")));
|
|
7
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
3
|
+
import { Text } from '../../../ui/text.js';
|
|
4
|
+
export const ThemeDirectoryContextError = () => {
|
|
5
|
+
return (React.createElement(Error, null,
|
|
6
|
+
React.createElement(Text, null, "Error: Cannot run this command inside a theme directory. Please run it outside of a theme directory.")));
|
|
7
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { THEME_ACTION_NOT_FOUND_ERROR_CODE } from '../../features/theme/actions/theme_actions_constants.js';
|
|
2
|
+
import { UnpermittedCommandError } from './unpermitted_command_error.js';
|
|
3
|
+
import { THEME_ARCHIVE_UPLOAD_ERROR, THEME_FILES_UPLOAD_ERROR } from '../../features/theme/push/theme_push_constants.js';
|
|
4
|
+
import { ValidationErrors } from '../../../ui/validation_errors/validation_errors.js';
|
|
5
|
+
import { THEME_WORK_URL_MISMATCH_ERROR } from '../../features/theme/utils/meta_data/theme_meta_data_constants.js';
|
|
6
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
7
|
+
import { Text } from '../../../ui/text.js';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { ThemeWorkUrlMismatch } from './theme_work_url_mismatch.js';
|
|
10
|
+
import { EXECUTION_CONTEXTS } from '../../../cli/features/execution_context/execution_context_constants.js';
|
|
11
|
+
export const ThemeError = ({ err, executionContext }) => {
|
|
12
|
+
if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && executionContext.type === EXECUTION_CONTEXTS.theme) {
|
|
13
|
+
return (React.createElement(UnpermittedCommandError, { themeId: executionContext.themeId, commandName: "verify" }));
|
|
14
|
+
}
|
|
15
|
+
if (err?.code === THEME_ARCHIVE_UPLOAD_ERROR) {
|
|
16
|
+
return React.createElement(ValidationErrors, { errors: err?.details });
|
|
17
|
+
}
|
|
18
|
+
if (err?.code === THEME_WORK_URL_MISMATCH_ERROR) {
|
|
19
|
+
return React.createElement(ThemeWorkUrlMismatch, { command: "verify" });
|
|
20
|
+
}
|
|
21
|
+
if (err?.code === THEME_FILES_UPLOAD_ERROR) {
|
|
22
|
+
return (React.createElement(Error, { header: "Uploading theme files to the shop failed.\n" },
|
|
23
|
+
React.createElement(Text, null, "The rejected files have been removed locally. Please ensure that the files are not corrupted and that the file extensions are supported.")));
|
|
24
|
+
}
|
|
25
|
+
if (err?.message) {
|
|
26
|
+
return React.createElement(ValidationErrors, { errors: err.message });
|
|
27
|
+
}
|
|
28
|
+
return String(err);
|
|
29
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
3
|
+
import { Command } from '../../../ui/command.js';
|
|
4
|
+
import { Tip } from '../../../ui/tip.js';
|
|
5
|
+
import { Text } from '../../../ui/text.js';
|
|
6
|
+
export const ThemeWorkUrlMismatch = ({ command }) => {
|
|
7
|
+
return (React.createElement(Error, { header: `Error: This theme belongs to a different store.` },
|
|
8
|
+
React.createElement(Text, null,
|
|
9
|
+
"Switch to the correct token to ",
|
|
10
|
+
command,
|
|
11
|
+
" this theme."),
|
|
12
|
+
React.createElement(Tip, null,
|
|
13
|
+
React.createElement(Text, null,
|
|
14
|
+
"Run ",
|
|
15
|
+
React.createElement(Command, null, "shoper theme auth token switch"),
|
|
16
|
+
" to change your token"))));
|
|
17
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Text } from '../../../ui/text.js';
|
|
2
|
+
import { Tip } from '../../../ui/tip.js';
|
|
3
|
+
import { Command } from '../../../ui/command.js';
|
|
4
|
+
import { Error } from '../../../ui/message_box/error.js';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
export const UnpermittedCommandError = ({ commandName, themeId }) => {
|
|
7
|
+
return (React.createElement(Error, null,
|
|
8
|
+
React.createElement(Text, null,
|
|
9
|
+
"You cannot ",
|
|
10
|
+
commandName,
|
|
11
|
+
" theme with id ",
|
|
12
|
+
themeId,
|
|
13
|
+
". Please check if the theme exists or if you have the necessary permissions."),
|
|
14
|
+
React.createElement(Tip, null,
|
|
15
|
+
"Run ",
|
|
16
|
+
React.createElement(Command, null, "shoper auth list-tokens"),
|
|
17
|
+
" to see available token index values.")));
|
|
18
|
+
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { STORE_THEMES_ACTIONS_TTL } from './theme_actions_service_constants.js';
|
|
2
|
-
import { AppError } from '../../../../../cli/class/errors/
|
|
2
|
+
import { AppError } from '../../../../../cli/class/errors/app/app_error.js';
|
|
3
3
|
import { getNMinutesFromNow } from '../../../../../utils/date_utils.js';
|
|
4
4
|
import { computeChecksum } from '../../../../../utils/checksums/checksums_utils.js';
|
|
5
|
+
import { THEME_ACTION_NOT_FOUND_ERROR_CODE, THEME_ACTION_NOTS_FOUND_ERROR_CODE } from '../theme_actions_constants.js';
|
|
5
6
|
export class ThemeActionsService {
|
|
6
7
|
#themesListApi;
|
|
7
8
|
#themesActionsStore;
|
|
@@ -13,17 +14,28 @@ export class ThemeActionsService {
|
|
|
13
14
|
const storeActions = this.#themesActionsStore.get(this._getKey(credentials.shopUrl));
|
|
14
15
|
if (!storeActions)
|
|
15
16
|
throw new AppError({
|
|
16
|
-
code:
|
|
17
|
+
code: THEME_ACTION_NOTS_FOUND_ERROR_CODE,
|
|
17
18
|
message: `Theme actions for store ${credentials.shopUrl} not found.`
|
|
18
19
|
});
|
|
19
20
|
const actions = storeActions.actions[themeId];
|
|
20
21
|
if (!actions)
|
|
21
22
|
throw new AppError({
|
|
22
|
-
code:
|
|
23
|
+
code: THEME_ACTION_NOT_FOUND_ERROR_CODE,
|
|
23
24
|
message: `Theme action for theme ${themeId} not found.`
|
|
24
25
|
});
|
|
25
26
|
return actions[actionType];
|
|
26
27
|
}
|
|
28
|
+
removeThemeActions({ themeId, credentials }) {
|
|
29
|
+
const storeActions = this.#themesActionsStore.get(this._getKey(credentials.shopUrl));
|
|
30
|
+
if (!storeActions || !storeActions.actions[themeId]) {
|
|
31
|
+
throw new AppError({
|
|
32
|
+
code: THEME_ACTION_NOTS_FOUND_ERROR_CODE,
|
|
33
|
+
message: `Theme actions for store ${credentials.shopUrl} not found.`
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
delete storeActions.actions[themeId];
|
|
37
|
+
this.#themesActionsStore.set(this._getKey(credentials.shopUrl), storeActions);
|
|
38
|
+
}
|
|
27
39
|
async ensureThemesActions({ credentials, themeId }) {
|
|
28
40
|
if (!themeId)
|
|
29
41
|
return;
|
|
@@ -6,10 +6,13 @@ export const THEME_ACTIONS_TYPES = {
|
|
|
6
6
|
push: 'push',
|
|
7
7
|
pull: 'pull',
|
|
8
8
|
delete: 'delete',
|
|
9
|
-
|
|
10
|
-
publish: 'publish'
|
|
9
|
+
publishForm: 'publish_form',
|
|
10
|
+
publish: 'publish',
|
|
11
|
+
verify: 'verify'
|
|
11
12
|
};
|
|
12
13
|
export const THEME_ACTION_DATA_TYPE = {
|
|
13
14
|
file: 'file',
|
|
14
15
|
zip: 'zip'
|
|
15
16
|
};
|
|
17
|
+
export const THEME_ACTION_NOT_FOUND_ERROR_CODE = 'theme_action_not_found';
|
|
18
|
+
export const THEME_ACTION_NOTS_FOUND_ERROR_CODE = 'theme_actions_not_found';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncFeatureInitializer, FEATURE_CORES_TYPES } from '@dreamcommerce/star_core';
|
|
2
2
|
import { THEMES_LIST_API_NAME } from '../../themes/list/themes_list_constants.js';
|
|
3
|
-
import { JsonCache } from '../../../../cli/
|
|
3
|
+
import { JsonCache } from '../../../../cli/class/caches/json_cache/json_cache.js';
|
|
4
4
|
import { CLI_DATA_DIRECTORY_API_NAME } from '../../../../cli/features/data_directory/cli_data_directory_constants.js';
|
|
5
5
|
import { THEME_ACTIONS_FEATURE_NAME, THEMES_ACTIONS_FILE_NAME } from './theme_actions_constants.js';
|
|
6
6
|
import { ThemeActionsApi } from './api/theme_actions_api.js';
|
|
@@ -1,8 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { THEME_ALL_ACTIONS_NAME } from './service/theme_actions_service_constants.js';
|
|
2
|
+
import { basename, looksLikeDirectory, toUnixPath } from '../../../../utils/path_utils.js';
|
|
3
|
+
import { THEME_ACTION_DATA_TYPE } from './theme_actions_constants.js';
|
|
4
|
+
import globs from 'fast-glob';
|
|
5
|
+
import { THEME_PUSH_WILDCARD_GLOBS_FOR_FILES } from '../push/service/theme_push_service_constants.js';
|
|
6
|
+
export class ThemeActionsUtils {
|
|
7
|
+
static getFilesGlobsThatMatchesActionName({ filesStructure, actionValue, actionType }) {
|
|
8
|
+
return Object.entries(filesStructure).reduce((acc, [filePath, fileStructureItem]) => {
|
|
9
|
+
if (fileStructureItem._links?.[actionType] && this._doesActionValueMatch(fileStructureItem._links[actionType], actionValue)) {
|
|
10
|
+
return [...acc, toUnixPath(filePath)];
|
|
11
|
+
}
|
|
12
|
+
return acc;
|
|
13
|
+
}, []);
|
|
14
|
+
}
|
|
15
|
+
static async getFilesRecordsFromActionData({ themeRootDir, themeAction, filesStructure }) {
|
|
16
|
+
const filesRecords = [];
|
|
17
|
+
for (const [actionKey, actionData] of Object.entries(themeAction.data)) {
|
|
18
|
+
if (actionData.type === THEME_ACTION_DATA_TYPE.file) {
|
|
19
|
+
const filesGlobs = ThemeActionsUtils.getFilesGlobsThatMatchesActionName({
|
|
20
|
+
//TODO remove when backend fixed
|
|
21
|
+
actionType: 'push',
|
|
22
|
+
// actionType: themeAction.actionType,
|
|
23
|
+
actionValue: actionKey,
|
|
24
|
+
filesStructure
|
|
25
|
+
});
|
|
26
|
+
for (const fileGlob of filesGlobs) {
|
|
27
|
+
const files = await globs(fileGlob, {
|
|
28
|
+
suppressErrors: true,
|
|
29
|
+
onlyFiles: true,
|
|
30
|
+
cwd: themeRootDir
|
|
31
|
+
});
|
|
32
|
+
let processedFileGlob = fileGlob;
|
|
33
|
+
if (looksLikeDirectory(fileGlob)) {
|
|
34
|
+
processedFileGlob = fileGlob.endsWith(THEME_PUSH_WILDCARD_GLOBS_FOR_FILES)
|
|
35
|
+
? fileGlob.slice(0, fileGlob.length - 2)
|
|
36
|
+
: fileGlob;
|
|
37
|
+
}
|
|
38
|
+
for (const filePath of files) {
|
|
39
|
+
filesRecords.push({
|
|
40
|
+
actionData,
|
|
41
|
+
actionKey,
|
|
42
|
+
path: filePath,
|
|
43
|
+
fileName: basename(filePath),
|
|
44
|
+
fileGlob: processedFileGlob
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
5
49
|
}
|
|
6
|
-
return
|
|
7
|
-
}
|
|
8
|
-
|
|
50
|
+
return filesRecords;
|
|
51
|
+
}
|
|
52
|
+
static _doesActionValueMatch(currentActionValue, valuesToMatch) {
|
|
53
|
+
if (typeof valuesToMatch === 'string') {
|
|
54
|
+
return currentActionValue === valuesToMatch || valuesToMatch === THEME_ALL_ACTIONS_NAME;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(valuesToMatch)) {
|
|
57
|
+
return valuesToMatch.includes(currentActionValue) || valuesToMatch.includes(THEME_ALL_ACTIONS_NAME);
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FeatureApi } from '@dreamcommerce/star_core';
|
|
2
|
+
import { THEME_DELETE_API_NAME } from '../theme_delete_constants.js';
|
|
3
|
+
export class ThemeDeleteApi extends FeatureApi {
|
|
4
|
+
moduleName = THEME_DELETE_API_NAME;
|
|
5
|
+
#service;
|
|
6
|
+
constructor(service) {
|
|
7
|
+
super();
|
|
8
|
+
this.#service = service;
|
|
9
|
+
}
|
|
10
|
+
async deleteTheme(props) {
|
|
11
|
+
return this.#service.deleteTheme(props);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class ThemeDeleteHttpApi {
|
|
2
|
+
#httpApi;
|
|
3
|
+
constructor(httpApi) {
|
|
4
|
+
this.#httpApi = httpApi;
|
|
5
|
+
}
|
|
6
|
+
deleteTheme({ shopUrl, actionData }) {
|
|
7
|
+
const { method, url } = actionData;
|
|
8
|
+
return this.#httpApi.fetch({
|
|
9
|
+
url: `${shopUrl}${url}`,
|
|
10
|
+
method,
|
|
11
|
+
sanitizeOptions: {
|
|
12
|
+
disable: true
|
|
13
|
+
},
|
|
14
|
+
isPrivate: true
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { HttpErrorsFactory } from '../../../../../cli/class/errors/http/http_errors_factory.js';
|
|
2
|
+
import { DownloadFileErrorsFactory } from '../../../../../utils/download_file/download_file_errors_factory.js';
|
|
3
|
+
import { STATUS_CODES } from '@dreamcommerce/star_core';
|
|
4
|
+
export class ThemeDeleteService {
|
|
5
|
+
#httpApi;
|
|
6
|
+
constructor(httpApi) {
|
|
7
|
+
this.#httpApi = httpApi;
|
|
8
|
+
}
|
|
9
|
+
async deleteTheme({ actionData, credentials }) {
|
|
10
|
+
try {
|
|
11
|
+
const { response: request } = this.#httpApi.deleteTheme({ actionData, shopUrl: credentials.shopUrl });
|
|
12
|
+
const response = await request;
|
|
13
|
+
if (response?.status !== STATUS_CODES.ok)
|
|
14
|
+
return;
|
|
15
|
+
return response?.data;
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
//TODO to basic class
|
|
19
|
+
switch (err.response?.status) {
|
|
20
|
+
case 403:
|
|
21
|
+
throw HttpErrorsFactory.createForbiddenError();
|
|
22
|
+
case 401:
|
|
23
|
+
throw HttpErrorsFactory.createUnauthorizedError();
|
|
24
|
+
case 404:
|
|
25
|
+
throw HttpErrorsFactory.createNotFoundError();
|
|
26
|
+
default:
|
|
27
|
+
throw DownloadFileErrorsFactory.downloadError(err.response.status);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|