@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,20 @@
|
|
|
1
|
+
import { FEATURE_CORES_TYPES, HTTP_REQUESTER_API_NAME, SyncFeatureInitializer } from '@dreamcommerce/star_core';
|
|
2
|
+
import { ThemeDeleteApi } from './api/theme_delete_api.js';
|
|
3
|
+
import { ThemeDeleteService } from './service/theme_delete_service.js';
|
|
4
|
+
import { ThemeDeleteHttpApi } from './http/theme_delete_http_api.js';
|
|
5
|
+
import { THEME_DELETE_FEATURE_NAME } from './theme_delete_constants.js';
|
|
6
|
+
export class ThemeDeleteInitializer extends SyncFeatureInitializer {
|
|
7
|
+
static featureName = THEME_DELETE_FEATURE_NAME;
|
|
8
|
+
init() {
|
|
9
|
+
const httpApi = this.getApiSync(HTTP_REQUESTER_API_NAME);
|
|
10
|
+
const service = new ThemeDeleteService(new ThemeDeleteHttpApi(httpApi));
|
|
11
|
+
return {
|
|
12
|
+
cores: [
|
|
13
|
+
{
|
|
14
|
+
type: FEATURE_CORES_TYPES.api,
|
|
15
|
+
instance: new ThemeDeleteApi(service)
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -4,17 +4,18 @@ import { downloadFile } from '../../../../../utils/download_file/download_file_u
|
|
|
4
4
|
import { extractZip } from '../../../../../utils/zip/extract_zip_utils.js';
|
|
5
5
|
import { join } from '../../../../../utils/path_utils.js';
|
|
6
6
|
import { SHOPER_THEME_METADATA_DIR } from '../../../../constants/directory_contstants.js';
|
|
7
|
-
import { getResources, mapResourcesToTree } from '../../../../class/fetch_resources/fetch_resources_utils.js';
|
|
7
|
+
import { getResources, mapResourcesToTree, removeOldResources } from '../../../../class/fetch_resources/fetch_resources_utils.js';
|
|
8
8
|
import { FetchResources } from '../../../../class/fetch_resources/fetch_resources.js';
|
|
9
9
|
import { jsonIndentTransform } from '../../../../../utils/stream_transforms/json_indent_transform.js';
|
|
10
|
-
import { ThemeDirectoryUtils } from '../../directory/theme_directory_utils.js';
|
|
11
10
|
import { THEME_CURRENT_CHECKSUMS_FILE_NAME, THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME, THEME_INITIAL_CHECKSUMS_FILE_NAME, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME } from '../../theme_constants.js';
|
|
12
11
|
import { THEME_FILES_LIST_FILE_NAME } from '../../push/theme_push_constants.js';
|
|
13
12
|
import { JSON_FILE_INDENT } from '../../../../../cli/cli_constants.js';
|
|
14
|
-
import { computeChecksumsFromSource } from '../../../../../utils/checksums/checksums_utils.js';
|
|
15
|
-
import { ThemeChecksumsUtils } from '../../utils/checksums/theme_checksums_utils.js';
|
|
16
13
|
import { createWriteStream } from 'node:fs';
|
|
17
|
-
import { AppError } from '../../../../../cli/class/errors/
|
|
14
|
+
import { AppError } from '../../../../../cli/class/errors/app/app_error.js';
|
|
15
|
+
import { THEME_ACTIONS_TYPES } from '../../actions/theme_actions_constants.js';
|
|
16
|
+
import { ThemeFilesStructureUtils } from '../../utils/files_structure/theme_files_structure_utils.js';
|
|
17
|
+
import { ThemeMetaDataUtils } from '../../utils/meta_data/theme_meta_data_utils.js';
|
|
18
|
+
import { ThemeChecksums } from '../../../../class/checksums/theme_checksums.js';
|
|
18
19
|
export class ThemeFetchService {
|
|
19
20
|
#themeHttpApi;
|
|
20
21
|
#httpApi;
|
|
@@ -53,14 +54,17 @@ export class ThemeFetchService {
|
|
|
53
54
|
});
|
|
54
55
|
}
|
|
55
56
|
await this._createGitIgnoreFile(themeDir);
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
await this._updateMetadataFileWithWorkUrl(themeDir, credentials.shopUrl);
|
|
58
|
+
/**
|
|
59
|
+
* moze to nie powinno lezec tutaj :?
|
|
60
|
+
*/
|
|
61
|
+
await new ThemeChecksums(themeDir).updateAllChecksums();
|
|
58
62
|
return {
|
|
59
63
|
name: basename
|
|
60
64
|
};
|
|
61
65
|
}
|
|
62
66
|
async _updateFilesStructure(themeDir) {
|
|
63
|
-
const fileStructure = await
|
|
67
|
+
const fileStructure = await ThemeFilesStructureUtils.getThemeFilesStructure(themeDir);
|
|
64
68
|
const checksumsFiles = [
|
|
65
69
|
`${SHOPER_THEME_METADATA_DIR}/${THEME_INITIAL_CHECKSUMS_FILE_NAME}`,
|
|
66
70
|
`${SHOPER_THEME_METADATA_DIR}/${THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME}`,
|
|
@@ -76,7 +80,15 @@ export class ThemeFetchService {
|
|
|
76
80
|
}
|
|
77
81
|
};
|
|
78
82
|
});
|
|
79
|
-
[THEME_FILES_LIST_FILE_NAME
|
|
83
|
+
fileStructure[THEME_FILES_LIST_FILE_NAME] = {
|
|
84
|
+
permissions: {
|
|
85
|
+
canAdd: true,
|
|
86
|
+
canEdit: true,
|
|
87
|
+
canDelete: true
|
|
88
|
+
},
|
|
89
|
+
_links: { [THEME_ACTIONS_TYPES.push]: '*' }
|
|
90
|
+
};
|
|
91
|
+
['.gitignore'].forEach((fileName) => {
|
|
80
92
|
fileStructure[fileName] = {
|
|
81
93
|
permissions: {
|
|
82
94
|
canAdd: true,
|
|
@@ -85,9 +97,17 @@ export class ThemeFetchService {
|
|
|
85
97
|
}
|
|
86
98
|
};
|
|
87
99
|
});
|
|
88
|
-
await
|
|
100
|
+
await ThemeFilesStructureUtils.writeThemeFilesStructure(themeDir, fileStructure);
|
|
101
|
+
}
|
|
102
|
+
async _updateMetadataFileWithWorkUrl(themeDir, workUrl) {
|
|
103
|
+
const shopMetadata = await ThemeMetaDataUtils.getThemeMetadata(themeDir);
|
|
104
|
+
await ThemeMetaDataUtils.updateThemeMetadata(themeDir, {
|
|
105
|
+
...shopMetadata,
|
|
106
|
+
workUrl
|
|
107
|
+
});
|
|
89
108
|
}
|
|
90
109
|
async fetchResources(shopUrl, dist, resources) {
|
|
110
|
+
await removeOldResources(dist, resources);
|
|
91
111
|
const resourcesTree = mapResourcesToTree(resources);
|
|
92
112
|
await Promise.all(Object.keys(resourcesTree).map((resource) => new FetchResources(this.#httpApi).fetchResources({
|
|
93
113
|
resourcesPart: resourcesTree[resource],
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { readJSONFile } from '../../../../utils/fs/fs_utils.js';
|
|
2
|
+
import { join } from '../../../../utils/path_utils.js';
|
|
3
|
+
export class ThemeInfoUtils {
|
|
4
|
+
static async getThemeName(themeDir) {
|
|
5
|
+
//TODO - wziasc z themeList a to wywalic
|
|
6
|
+
const themeDetails = await readJSONFile(join(themeDir, 'settings', 'details.json'));
|
|
7
|
+
return themeDetails.name ?? 'Storefront';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -3,8 +3,9 @@ import process from 'process';
|
|
|
3
3
|
import tmp from 'tmp-promise';
|
|
4
4
|
import { downloadFile } from '../../../../../utils/download_file/download_file_utils.js';
|
|
5
5
|
import { extractZip } from '../../../../../utils/zip/extract_zip_utils.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { ThemeMetaDataUtils } from '../../utils/meta_data/theme_meta_data_utils.js';
|
|
7
|
+
import { ThemeInfoUtils } from '../../info/theme_info_utils.js';
|
|
8
|
+
import { ThemeChecksums } from '../../../../../theme/class/checksums/theme_checksums.js';
|
|
8
9
|
export class ThemeInitService {
|
|
9
10
|
#httpApi;
|
|
10
11
|
constructor({ httpApi }) {
|
|
@@ -22,7 +23,11 @@ export class ThemeInitService {
|
|
|
22
23
|
source: join(tmpDir, filename),
|
|
23
24
|
dist: distDir
|
|
24
25
|
});
|
|
25
|
-
|
|
26
|
-
await
|
|
26
|
+
new ThemeChecksums(distDir).updateAllChecksums();
|
|
27
|
+
const themeMetaData = await ThemeMetaDataUtils.getThemeMetadata(distDir);
|
|
28
|
+
return {
|
|
29
|
+
themeId: themeMetaData.themeId,
|
|
30
|
+
themeName: await ThemeInfoUtils.getThemeName(distDir)
|
|
31
|
+
};
|
|
27
32
|
}
|
|
28
33
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FEATURE_CORES_TYPES, HTTP_REQUESTER_API_NAME, SyncFeatureInitializer } from '@dreamcommerce/star_core';
|
|
2
2
|
import { ThemeInitHttpApi } from './http/theme_init_http_api.js';
|
|
3
3
|
import { ThemeInitApi } from './api/theme_init_api.js';
|
|
4
4
|
import { ThemeInitService } from './service/theme_init_service.js';
|
|
5
5
|
import { THEME_INIT_FEATURE_NAME } from './theme_init_constants.js';
|
|
6
|
-
export class ThemeInitInitializer extends
|
|
6
|
+
export class ThemeInitInitializer extends SyncFeatureInitializer {
|
|
7
7
|
static featureName = THEME_INIT_FEATURE_NAME;
|
|
8
|
-
|
|
8
|
+
init() {
|
|
9
9
|
const httpApi = this.getApiSync(HTTP_REQUESTER_API_NAME);
|
|
10
10
|
const service = new ThemeInitService({
|
|
11
11
|
httpApi: new ThemeInitHttpApi(httpApi)
|
|
@@ -7,22 +7,10 @@ export class ThemeMergeApi extends FeatureApi {
|
|
|
7
7
|
super();
|
|
8
8
|
this.#service = service;
|
|
9
9
|
}
|
|
10
|
-
hasThemeBeenModified(themeRootDir) {
|
|
11
|
-
return this.#service.hasThemeBeenModified(themeRootDir);
|
|
12
|
-
}
|
|
13
10
|
getChangesBetweenThemes(theme1, theme2) {
|
|
14
11
|
return this.#service.getChangesBetweenThemes(theme1, theme2);
|
|
15
12
|
}
|
|
16
13
|
applyChanges(fromTheme, toTheme, changes) {
|
|
17
14
|
return this.#service.applyChanges(fromTheme, toTheme, changes);
|
|
18
15
|
}
|
|
19
|
-
hasFileBeenCreated(path, executionContext) {
|
|
20
|
-
return this.#service.hasFileBeenCreated(path, executionContext);
|
|
21
|
-
}
|
|
22
|
-
hasFileBeenRemoved(path, executionContext) {
|
|
23
|
-
return this.#service.hasFileBeenRemoved(path, executionContext);
|
|
24
|
-
}
|
|
25
|
-
hasFileBeenModified(path, executionContext) {
|
|
26
|
-
return this.#service.hasFileBeenModified(path, executionContext);
|
|
27
|
-
}
|
|
28
16
|
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import FSTree from 'fs-tree-diff';
|
|
2
|
-
import {
|
|
3
|
-
import { computeChecksumsFromSource, computeFileChecksum } from '../../../../../utils/checksums/checksums_utils.js';
|
|
4
|
-
import { copyFile, copyFileSync, fileExists } from '../../../../../utils/fs/fs_utils.js';
|
|
5
|
-
import { ThemeChecksumsUtils } from '../../utils/checksums/theme_checksums_utils.js';
|
|
2
|
+
import { copyFileSync, getAllDirectoriesNamesInside } from '../../../../../utils/fs/fs_utils.js';
|
|
6
3
|
import walkSync from 'walk-sync';
|
|
4
|
+
import { ThemeChecksums } from '../../../../class/checksums/theme_checksums.js';
|
|
5
|
+
import { ThemeFilesStructureUtils } from '../../utils/files_structure/theme_files_structure_utils.js';
|
|
7
6
|
import { SHOPER_THEME_METADATA_DIR } from '../../../../constants/directory_contstants.js';
|
|
7
|
+
import { join, platformSeparator } from '../../../../../utils/path_utils.js';
|
|
8
8
|
export class ThemeMergeService {
|
|
9
9
|
async applyChanges(fromTheme, toTheme, changes) {
|
|
10
10
|
FSTree.applyPatch(fromTheme, toTheme, changes, {
|
|
11
11
|
create(inputPath, outputPath) {
|
|
12
|
-
|
|
12
|
+
copyFileSync(inputPath, outputPath);
|
|
13
13
|
},
|
|
14
14
|
change(inputPath, outputPath) {
|
|
15
15
|
copyFileSync(inputPath, outputPath);
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
-
|
|
19
|
-
await ThemeChecksumsUtils.createThemeChecksumsFiles(toTheme, checksums);
|
|
18
|
+
new ThemeChecksums(toTheme).updateAllChecksums();
|
|
20
19
|
}
|
|
21
20
|
async getChangesBetweenThemes(theme1, theme2) {
|
|
22
21
|
const theme1Tree = new FSTree({
|
|
@@ -25,32 +24,25 @@ export class ThemeMergeService {
|
|
|
25
24
|
const theme2Tree = new FSTree({
|
|
26
25
|
entries: walkSync.entries(theme2)
|
|
27
26
|
});
|
|
28
|
-
const theme1Checksums =
|
|
29
|
-
const theme2Checksums =
|
|
27
|
+
const theme1Checksums = new ThemeChecksums(theme1);
|
|
28
|
+
const theme2Checksums = new ThemeChecksums(theme2);
|
|
29
|
+
const userDirectories = await this._getUserRootDirectories(theme2);
|
|
30
30
|
return theme2Tree
|
|
31
31
|
.calculatePatch(theme1Tree, (entryA, entryB) => {
|
|
32
32
|
if (entryA.isDirectory() && entryB.isDirectory())
|
|
33
33
|
return true;
|
|
34
|
-
return theme1Checksums
|
|
34
|
+
return (theme1Checksums.getCurrentChecksumFromPathSync(entryA.relativePath) ===
|
|
35
|
+
theme2Checksums.getCurrentChecksumFromPathSync(entryB.relativePath));
|
|
35
36
|
})
|
|
36
|
-
.filter(([, name]) =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const initialChecksums = await ThemeChecksumsUtils.getInitialChecksumsVerification(themeRootDir);
|
|
40
|
-
const currentChecksums = await ThemeChecksumsUtils.getThemeCurrentChecksumsVerification(themeRootDir);
|
|
41
|
-
return initialChecksums !== currentChecksums;
|
|
42
|
-
}
|
|
43
|
-
async hasFileBeenCreated(path, executionContext) {
|
|
44
|
-
const checksums = await ThemeChecksumsUtils.getThemeCurrentChecksums(executionContext.themeRootDir);
|
|
45
|
-
return checksums[path] === undefined && (await fileExists(join(executionContext.themeRootDir, path)));
|
|
46
|
-
}
|
|
47
|
-
async hasFileBeenRemoved(path, executionContext) {
|
|
48
|
-
const checksums = await ThemeChecksumsUtils.getThemeCurrentChecksums(executionContext.themeRootDir);
|
|
49
|
-
return !(await fileExists(join(executionContext.themeRootDir, path))) && !!checksums[path];
|
|
37
|
+
.filter(([_, name]) => {
|
|
38
|
+
return !name.startsWith(SHOPER_THEME_METADATA_DIR) && !userDirectories.some((userDir) => name.startsWith(userDir));
|
|
39
|
+
});
|
|
50
40
|
}
|
|
51
|
-
async
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
async _getUserRootDirectories(themeDir) {
|
|
42
|
+
const filesStructure = await ThemeFilesStructureUtils.getThemeRootDirectories(themeDir);
|
|
43
|
+
return (await getAllDirectoriesNamesInside(themeDir, {
|
|
44
|
+
recursive: false,
|
|
45
|
+
hidden: true
|
|
46
|
+
})).filter((directory) => !filesStructure.includes(join(directory, platformSeparator)));
|
|
55
47
|
}
|
|
56
48
|
}
|
|
@@ -1,200 +1,101 @@
|
|
|
1
1
|
import tmp from 'tmp-promise';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { basename, dirname, extname, join, looksLikeDirectory, toUnixPath } from '../../../../../utils/path_utils.js';
|
|
5
|
-
import { createReadStream } from 'node:fs';
|
|
2
|
+
import { THEME_ACTIONS_TYPES } from '../../actions/theme_actions_constants.js';
|
|
3
|
+
import { join } from '../../../../../utils/path_utils.js';
|
|
6
4
|
import { v4 as uuid } from 'uuid';
|
|
7
|
-
import globs from 'fast-glob';
|
|
8
5
|
import { THEME_WILDCARD_ACTION_NAME } from '../../actions/service/theme_actions_service_constants.js';
|
|
9
|
-
import {
|
|
10
|
-
import { THEME_FILES_LIST_FILE_NAME, THEME_MODULE_SETTINGS_FILE_NAME } from '../theme_push_constants.js';
|
|
11
|
-
import { THEME_PUSH_WILDCARD_GLOBS_FOR_FILES } from './theme_push_service_constants.js';
|
|
6
|
+
import { THEME_MODULE_SETTINGS_FILE_NAME } from '../theme_push_constants.js';
|
|
12
7
|
import { ThemePushErrorsFactory } from '../theme_push_errors_factory.js';
|
|
13
8
|
import { ThemeImagesUtils } from '../../utils/theme_images_utils.js';
|
|
14
|
-
import { ThemePublishUtils } from '../../
|
|
15
|
-
import {
|
|
16
|
-
import { computeChecksumsFromSource } from '../../../../../utils/checksums/checksums_utils.js';
|
|
17
|
-
import { ThemeChecksumsUtils } from '../../utils/checksums/theme_checksums_utils.js';
|
|
9
|
+
import { ThemePublishUtils } from '../../skinstore/theme_publish_utils.js';
|
|
10
|
+
import { removeFile, writeJSONFile } from '../../../../../utils/fs/fs_utils.js';
|
|
18
11
|
import { MODULES_DIRECTORY_NAME } from '../../theme_constants.js';
|
|
12
|
+
import { removeOldResources } from '../../../../class/fetch_resources/fetch_resources_utils.js';
|
|
13
|
+
import { ThemeArchive } from '../../../../class/archive/theme_archive.js';
|
|
14
|
+
import { ThemeFilesStructureUtils } from '../../utils/files_structure/theme_files_structure_utils.js';
|
|
15
|
+
import { ThemeActionsUtils } from '../../actions/theme_actions_utils.js';
|
|
16
|
+
import { ArrayUtils } from '@dreamcommerce/utilities';
|
|
19
17
|
export class ThemePushService {
|
|
20
|
-
#themePushHttpApi;
|
|
21
|
-
#themeMergeApi;
|
|
22
18
|
#themeFetchApi;
|
|
23
|
-
constructor({
|
|
24
|
-
this.#themePushHttpApi = themePushHttpApi;
|
|
25
|
-
this.#themeMergeApi = themeMergeApi;
|
|
19
|
+
constructor({ themeFetchApi }) {
|
|
26
20
|
this.#themeFetchApi = themeFetchApi;
|
|
27
21
|
}
|
|
28
|
-
async push({ pushAction,
|
|
22
|
+
async push({ pushAction, credentials, filesStructure, executionContext, themeChecksums, themeFilesUploadApi }) {
|
|
29
23
|
const { path: tmpDir } = await tmp.dir({ unsafeCleanup: true });
|
|
30
|
-
|
|
24
|
+
const themeRootDir = executionContext.themeRootDir;
|
|
25
|
+
if (await themeChecksums.hasThemeFileBeenCreated(ThemePublishUtils.getSkinStoreSettingsFilePath(themeRootDir)))
|
|
31
26
|
throw ThemePushErrorsFactory.createErrorWhilePushingUnpublishedThemeWithSkinstoreData(credentials.shopUrl);
|
|
32
|
-
const { uploadData, localFiles } = await this._getActionDataForFilesToUpload({
|
|
33
|
-
pushAction,
|
|
34
|
-
filesStructure,
|
|
35
|
-
executionContext
|
|
36
|
-
});
|
|
37
|
-
if (uploadData.length) {
|
|
38
|
-
await this._uploadThemeFiles({
|
|
39
|
-
filesToUpload: uploadData,
|
|
40
|
-
actionData: pushAction.data[THEME_WILDCARD_ACTION_NAME],
|
|
41
|
-
credentials,
|
|
42
|
-
localFiles,
|
|
43
|
-
themeRootDir: executionContext.themeRootDir
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
await this._createAFilesListFile(executionContext.themeRootDir, localFiles);
|
|
48
|
-
}
|
|
49
|
-
const themeArchivePath = join(tmpDir, `${uuid()}.zip`);
|
|
50
27
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
],
|
|
57
|
-
dist: themeArchivePath
|
|
28
|
+
//TODO to do api?
|
|
29
|
+
const filesRecords = await ThemeActionsUtils.getFilesRecordsFromActionData({
|
|
30
|
+
themeRootDir,
|
|
31
|
+
themeAction: pushAction,
|
|
32
|
+
filesStructure
|
|
58
33
|
});
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
await this._formatJsonFiles(themeRootDir, filesInThemeDirectory);
|
|
84
|
-
return createZip({
|
|
85
|
-
files: filesInThemeDirectory,
|
|
86
|
-
baseDir: themeRootDir,
|
|
87
|
-
dist
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
async _uploadThemeArchive({ themeArchivePath, credentials, pushAction }) {
|
|
91
|
-
try {
|
|
92
|
-
const request = this.#themePushHttpApi.pushThemeData({
|
|
93
|
-
actionData: pushAction.data[THEME_WILDCARD_ACTION_NAME],
|
|
94
|
-
stream: createReadStream(themeArchivePath),
|
|
95
|
-
shopUrl: credentials.shopUrl
|
|
34
|
+
const filesToUpload = await ArrayUtils.asyncFilter(filesRecords, async ({ path }) => (await themeChecksums.hasThemeFileBeenCreated(path)) || (await themeChecksums.hasThemeFileBeenModified(path)));
|
|
35
|
+
if (filesToUpload.length) {
|
|
36
|
+
const { localFileNameToUploaded } = await this._uploadThemeFiles({
|
|
37
|
+
filesToUpload,
|
|
38
|
+
credentials,
|
|
39
|
+
themeRootDir,
|
|
40
|
+
themeFilesUploadApi
|
|
41
|
+
});
|
|
42
|
+
await this._createFilesList(themeRootDir, filesRecords, localFileNameToUploaded);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
await this._createFilesList(themeRootDir, filesRecords);
|
|
46
|
+
}
|
|
47
|
+
const themeArchivePath = join(tmpDir, `${uuid()}.zip`);
|
|
48
|
+
await new ThemeArchive(themeRootDir).createFullArchive({
|
|
49
|
+
dist: themeArchivePath,
|
|
50
|
+
actionValue: THEME_WILDCARD_ACTION_NAME,
|
|
51
|
+
actionType: THEME_ACTIONS_TYPES.push
|
|
52
|
+
});
|
|
53
|
+
const { resources, modules } = await themeFilesUploadApi.uploadArchive({
|
|
54
|
+
action: pushAction,
|
|
55
|
+
themeArchivePath,
|
|
56
|
+
credentials
|
|
96
57
|
});
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
58
|
+
if (modules)
|
|
59
|
+
await this._updateDataForNewCreatedModules({ modules, themeRootDir });
|
|
60
|
+
if (resources) {
|
|
61
|
+
await removeOldResources(themeRootDir, resources);
|
|
62
|
+
await this.#themeFetchApi.fetchResources(credentials.shopUrl, themeRootDir, resources);
|
|
63
|
+
}
|
|
64
|
+
await themeChecksums.updateAllChecksums();
|
|
101
65
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
throw ThemePushErrorsFactory.createErrorWhileUploadingTheme(credentials.shopUrl, err.response.data.messages);
|
|
66
|
+
finally {
|
|
67
|
+
await ThemeFilesStructureUtils.removeAFilesListFile(themeRootDir);
|
|
105
68
|
}
|
|
106
69
|
}
|
|
107
|
-
async
|
|
108
|
-
await Promise.all(filesToUpload
|
|
109
|
-
.filter((path) => extname(path).toLowerCase() === '.json')
|
|
110
|
-
.map((jsonFile) => formatJSONFile(join(themeRootDir, jsonFile))));
|
|
111
|
-
}
|
|
112
|
-
async _uploadThemeFiles({ filesToUpload, themeRootDir, localFiles, credentials }) {
|
|
70
|
+
async _uploadThemeFiles({ filesToUpload, themeRootDir, credentials, themeFilesUploadApi }) {
|
|
113
71
|
try {
|
|
114
|
-
const uploadedImageData = await
|
|
115
|
-
const newFilesList = ThemeImagesUtils.updateOriginalFilenameToUploadedFilename(localFiles, uploadedImageData);
|
|
72
|
+
const { uploadedImageData, rejectedImageData } = await themeFilesUploadApi.uploadFiles(filesToUpload);
|
|
116
73
|
if (uploadedImageData.length)
|
|
117
74
|
await ThemeImagesUtils.removeUploadedOriginalFiles(themeRootDir, uploadedImageData);
|
|
118
|
-
|
|
75
|
+
if (rejectedImageData.length)
|
|
76
|
+
await this._removeUploadedThemeFiles(rejectedImageData, themeRootDir);
|
|
77
|
+
return {
|
|
78
|
+
localFileNameToUploaded: uploadedImageData.reduce((acc, { originalFilename, uploadedFilename }) => {
|
|
79
|
+
return {
|
|
80
|
+
...acc,
|
|
81
|
+
[originalFilename]: uploadedFilename ?? originalFilename
|
|
82
|
+
};
|
|
83
|
+
}, {})
|
|
84
|
+
};
|
|
119
85
|
}
|
|
120
86
|
catch (err) {
|
|
121
87
|
throw ThemePushErrorsFactory.createErrorWhileUploadingThemeFiles(credentials.shopUrl, err);
|
|
122
88
|
}
|
|
123
89
|
}
|
|
124
|
-
async
|
|
125
|
-
|
|
126
|
-
await Promise.all(uploadData.map(({ actionData, path }) => this.#themePushHttpApi
|
|
127
|
-
.pushThemeData({
|
|
128
|
-
actionData,
|
|
129
|
-
stream: createReadStream(path),
|
|
130
|
-
shopUrl: credentials.shopUrl
|
|
131
|
-
})
|
|
132
|
-
.response.then((response) => {
|
|
133
|
-
if (response.status !== 200 || !response.data.isSuccess)
|
|
134
|
-
throw ThemePushErrorsFactory.createErrorWhileUploadingThemeFiles(credentials.shopUrl, response.data?.messages ?? []);
|
|
135
|
-
uploadedImageData.push({
|
|
136
|
-
location: dirname(path),
|
|
137
|
-
originalFilename: basename(path),
|
|
138
|
-
uploadedFilename: response.data.imageId
|
|
139
|
-
});
|
|
140
|
-
})));
|
|
141
|
-
return uploadedImageData;
|
|
142
|
-
}
|
|
143
|
-
async _getActionDataForFilesToUpload({ pushAction, filesStructure, executionContext }) {
|
|
144
|
-
const uploadData = [];
|
|
145
|
-
const localFiles = {};
|
|
146
|
-
for (const [actionKey, actionData] of Object.entries(pushAction.data)) {
|
|
147
|
-
if (actionData.type === THEME_ACTION_DATA_TYPE.file) {
|
|
148
|
-
const filesGlobs = getFilesGlobsThatMatchesActionName(THEME_ACTIONS_TYPES.push, actionKey, filesStructure);
|
|
149
|
-
for (const fileGlob of filesGlobs) {
|
|
150
|
-
const files = await globs(fileGlob, {
|
|
151
|
-
suppressErrors: true,
|
|
152
|
-
onlyFiles: true,
|
|
153
|
-
cwd: executionContext.themeRootDir
|
|
154
|
-
});
|
|
155
|
-
if (looksLikeDirectory(fileGlob)) {
|
|
156
|
-
const processedFileGlob = fileGlob.endsWith(THEME_PUSH_WILDCARD_GLOBS_FOR_FILES)
|
|
157
|
-
? fileGlob.slice(0, fileGlob.length - 2)
|
|
158
|
-
: fileGlob;
|
|
159
|
-
localFiles[processedFileGlob] = files.length ? files.map((filePath) => basename(filePath)) : [];
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
localFiles[fileGlob] = files.length ? basename(files[0]) : null;
|
|
163
|
-
}
|
|
164
|
-
for (const filePath of files) {
|
|
165
|
-
if ((await this.#themeMergeApi.hasFileBeenCreated(filePath, executionContext)) ||
|
|
166
|
-
(await this.#themeMergeApi.hasFileBeenModified(filePath, executionContext))) {
|
|
167
|
-
uploadData.push({
|
|
168
|
-
actionData,
|
|
169
|
-
actionKey,
|
|
170
|
-
path: filePath
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
uploadData,
|
|
179
|
-
localFiles
|
|
180
|
-
};
|
|
90
|
+
async _removeUploadedThemeFiles(uploadedImageData, themeRootDir) {
|
|
91
|
+
await Promise.all(uploadedImageData.map(({ location, originalFilename }) => removeFile(join(themeRootDir, location, originalFilename))));
|
|
181
92
|
}
|
|
182
93
|
async _updateDataForNewCreatedModules({ modules, themeRootDir }) {
|
|
183
94
|
for (const [moduleDirectoryName, metaData] of Object.entries(modules)) {
|
|
184
95
|
await writeJSONFile(join(themeRootDir, MODULES_DIRECTORY_NAME, moduleDirectoryName, THEME_MODULE_SETTINGS_FILE_NAME), JSON.parse(metaData[THEME_MODULE_SETTINGS_FILE_NAME]));
|
|
185
96
|
}
|
|
186
97
|
}
|
|
187
|
-
async
|
|
188
|
-
|
|
189
|
-
return;
|
|
190
|
-
const toUnixStyleFilesList = Object.entries(filesList).reduce((acc, [path, value]) => {
|
|
191
|
-
const unixPath = toUnixPath(path);
|
|
192
|
-
const finalPath = looksLikeDirectory(path) ? `${unixPath}/` : unixPath;
|
|
193
|
-
return {
|
|
194
|
-
...acc,
|
|
195
|
-
[finalPath]: value
|
|
196
|
-
};
|
|
197
|
-
}, {});
|
|
198
|
-
await writeJSONFile(join(themeRootDir, THEME_FILES_LIST_FILE_NAME), toUnixStyleFilesList);
|
|
98
|
+
async _createFilesList(themeRootDir, filesRecords, localFileNameToUploaded = {}) {
|
|
99
|
+
await ThemeFilesStructureUtils.createAFilesListFile(themeRootDir, ThemeFilesStructureUtils.mapFilesRecordsToFilesList(filesRecords, localFileNameToUploaded));
|
|
199
100
|
}
|
|
200
101
|
}
|
|
@@ -2,3 +2,5 @@ export const THEME_PUSH_FEATURE_NAME = 'ThemePush';
|
|
|
2
2
|
export const THEME_PUSH_API_NAME = 'ThemePushApi';
|
|
3
3
|
export const THEME_FILES_LIST_FILE_NAME = 'filesList.json';
|
|
4
4
|
export const THEME_MODULE_SETTINGS_FILE_NAME = 'settings.json';
|
|
5
|
+
export const THEME_ARCHIVE_UPLOAD_ERROR = 'theme.push.error_uploading_theme_archive';
|
|
6
|
+
export const THEME_FILES_UPLOAD_ERROR = 'theme.push.error_uploading_theme_files';
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { AppError } from '../../../../cli/class/errors/
|
|
1
|
+
import { AppError } from '../../../../cli/class/errors/app/app_error.js';
|
|
2
|
+
import { THEME_ARCHIVE_UPLOAD_ERROR, THEME_FILES_UPLOAD_ERROR } from './theme_push_constants.js';
|
|
2
3
|
export class ThemePushErrorsFactory {
|
|
3
4
|
static createErrorWhileUploadingThemeFiles(shopUrl, messages) {
|
|
4
5
|
return new AppError({
|
|
5
|
-
code:
|
|
6
|
+
code: THEME_FILES_UPLOAD_ERROR,
|
|
6
7
|
message: `Error while uploading theme files to shop "${shopUrl}"`,
|
|
7
8
|
level: 'error',
|
|
8
|
-
details:
|
|
9
|
+
details: {
|
|
10
|
+
messages
|
|
11
|
+
}
|
|
9
12
|
});
|
|
10
13
|
}
|
|
11
14
|
static createErrorWhileCreatingThemeArchive(shopUrl, error) {
|
|
@@ -32,7 +35,7 @@ export class ThemePushErrorsFactory {
|
|
|
32
35
|
}
|
|
33
36
|
static createErrorWhileUploadingTheme(shopUrl, messages) {
|
|
34
37
|
return new AppError({
|
|
35
|
-
code:
|
|
38
|
+
code: THEME_ARCHIVE_UPLOAD_ERROR,
|
|
36
39
|
message: `Error while uploading theme to shop "${shopUrl}"`,
|
|
37
40
|
level: 'error',
|
|
38
41
|
details: messages
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { FEATURE_CORES_TYPES,
|
|
1
|
+
import { FEATURE_CORES_TYPES, SyncFeatureInitializer } from '@dreamcommerce/star_core';
|
|
2
2
|
import { ThemePushService } from './service/theme_push_service.js';
|
|
3
3
|
import { THEME_PUSH_FEATURE_NAME } from './theme_push_constants.js';
|
|
4
4
|
import { ThemePushApi } from './api/theme_push_api.js';
|
|
5
|
-
import { ThemePushHttpApi } from './http_api/theme_push_http_api.js';
|
|
6
|
-
import { THEME_MERGE_API_NAME } from '../merge/theme_merge_constants.js';
|
|
7
5
|
import { THEME_FETCH_API_NAME } from '../fetch/theme_fetch_constants.js';
|
|
8
6
|
export class ThemePushInitializer extends SyncFeatureInitializer {
|
|
9
7
|
static featureName = THEME_PUSH_FEATURE_NAME;
|
|
10
8
|
init() {
|
|
11
|
-
const httpApi = this.getApiSync(HTTP_REQUESTER_API_NAME);
|
|
12
|
-
const themeMergeApi = this.getApiSync(THEME_MERGE_API_NAME);
|
|
13
9
|
const service = new ThemePushService({
|
|
14
|
-
themePushHttpApi: new ThemePushHttpApi(httpApi),
|
|
15
|
-
themeMergeApi,
|
|
16
10
|
themeFetchApi: this.getApiSync(THEME_FETCH_API_NAME)
|
|
17
11
|
});
|
|
18
12
|
return {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import globs from 'fast-glob';
|
|
2
|
+
import { AppError } from '../../../../cli/class/errors/app/app_error.js';
|
|
3
|
+
import { toUnixPath } from '../../../../utils/path_utils.js';
|
|
4
|
+
import { ThemeFilesStructureUtils } from '../utils/files_structure/theme_files_structure_utils.js';
|
|
5
|
+
export class ThemePushUtils {
|
|
6
|
+
static async getAllFilesThatAreSendToRemote(themeDir) {
|
|
7
|
+
const filesStructure = await ThemeFilesStructureUtils.getThemeFilesStructure(themeDir);
|
|
8
|
+
if (!filesStructure)
|
|
9
|
+
throw new AppError({
|
|
10
|
+
message: `Files structure not found in theme directory: ${themeDir}`,
|
|
11
|
+
code: 'theme_files_structure_not_found'
|
|
12
|
+
});
|
|
13
|
+
//need unix styles globs
|
|
14
|
+
const filesToArchive = Object.keys(filesStructure)
|
|
15
|
+
.map((path) => toUnixPath(path))
|
|
16
|
+
.filter((path) => path !== '*');
|
|
17
|
+
//need unix styles globs
|
|
18
|
+
filesToArchive.push('styles/src/**/*');
|
|
19
|
+
return await globs(filesToArchive, {
|
|
20
|
+
suppressErrors: true,
|
|
21
|
+
onlyFiles: true,
|
|
22
|
+
cwd: themeDir
|
|
23
|
+
}).then((files) => files.sort());
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FeatureApi } from '@dreamcommerce/star_core';
|
|
2
|
+
import { THEME_SKINSTORE_API_NAME } from '../theme_publish_constants.js';
|
|
3
|
+
export class ThemeSkinstoreApi extends FeatureApi {
|
|
4
|
+
moduleName = THEME_SKINSTORE_API_NAME;
|
|
5
|
+
#service;
|
|
6
|
+
constructor(service) {
|
|
7
|
+
super();
|
|
8
|
+
this.#service = service;
|
|
9
|
+
}
|
|
10
|
+
async getPublishFormData(props) {
|
|
11
|
+
return this.#service.getPublishFormData(props);
|
|
12
|
+
}
|
|
13
|
+
async publish(themeId) {
|
|
14
|
+
// return this.#service.publish(themeId);
|
|
15
|
+
}
|
|
16
|
+
async update() {
|
|
17
|
+
// return this.#service.update();
|
|
18
|
+
}
|
|
19
|
+
}
|