@shoper/cli 0.1.0-24 → 0.1.0-26

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 (24) hide show
  1. package/build/cli/core/cli_setup.js +3 -1
  2. package/build/cli/ui/error_item.js +7 -0
  3. package/build/cli/ui/errors_list.js +15 -0
  4. package/build/theme/commands/delete/theme_delete_command.js +99 -0
  5. package/build/theme/commands/init/theme_init_command.js +5 -3
  6. package/build/theme/commands/push/theme_push_command.js +9 -5
  7. package/build/theme/commands/theme_commands_constants.js +2 -1
  8. package/build/theme/features/theme/actions/theme_actions_constants.js +1 -2
  9. package/build/theme/features/theme/delete/api/theme_delete_api.js +13 -0
  10. package/build/theme/features/theme/delete/http/theme_delete_http_api.js +17 -0
  11. package/build/theme/features/theme/delete/service/theme_delete_service.js +34 -0
  12. package/build/theme/features/theme/delete/theme_delete_constants.js +2 -0
  13. package/build/theme/features/theme/delete/theme_delete_initalizer.js +20 -0
  14. package/build/theme/features/theme/merge/service/theme_merge_service.js +2 -2
  15. package/build/theme/features/theme/push/service/theme_push_service.js +18 -5
  16. package/build/theme/features/theme/push/theme_push_constants.js +1 -0
  17. package/build/theme/features/theme/push/theme_push_errors_factory.js +5 -3
  18. package/build/theme/features/theme/utils/checksums/theme_checksums_utils.js +0 -2
  19. package/build/theme/features/theme/utils/meta_data/theme_meta_data_utils.js +1 -1
  20. package/build/theme/index.js +3 -1
  21. package/build/utils/download_file/download_file_utils.js +1 -1
  22. package/package.json +1 -1
  23. package/build/theme/commands/push/ui/theme_validation_error.js +0 -6
  24. package/build/theme/commands/push/ui/theme_validation_errors.js +0 -5
@@ -14,6 +14,7 @@ import { ThemeFetchInitializer } from '../../theme/features/theme/fetch/theme_fe
14
14
  import { ThemeMergeInitializer } from '../../theme/features/theme/merge/theme_merge_initializer.js';
15
15
  import { ThemeActionsInitializer } from '../../theme/features/theme/actions/theme_actions_initializer.js';
16
16
  import { ThemePushInitializer } from '../../theme/features/theme/push/theme_push_initializer.js';
17
+ import { ThemeDeleteInitializer } from '../../theme/features/theme/delete/theme_delete_initalizer.js';
17
18
  tmp.setGracefulCleanup();
18
19
  export const cliSetup = async () => {
19
20
  //TODO jakis ładny komuniakt błedu
@@ -34,7 +35,8 @@ export const cliSetup = async () => {
34
35
  ThemeInitInitializer,
35
36
  ThemeMergeInitializer,
36
37
  ThemeFetchInitializer,
37
- ThemePushInitializer
38
+ ThemePushInitializer,
39
+ ThemeDeleteInitializer
38
40
  ],
39
41
  options: {
40
42
  featuresTracking: false,
@@ -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 ErrorItem = ({ error, title }) => {
5
+ return (React.createElement(Error, { header: title },
6
+ React.createElement(Text, null, error)));
7
+ };
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { ErrorItem } from './error_item.js';
3
+ import { Error } from '../../ui/message_box/error.js';
4
+ import { Text } from '../../ui/text.js';
5
+ import { Box } from '../../ui/box.js';
6
+ export const ErrorsList = ({ errors }) => {
7
+ if (typeof errors === 'string') {
8
+ return React.createElement(ErrorItem, { error: errors });
9
+ }
10
+ if (Array.isArray(errors)) {
11
+ return errors.map((error, index) => (React.createElement(ErrorItem, { key: index, error: error })));
12
+ }
13
+ return (React.createElement(React.Fragment, null, Object.entries(errors).map(([title, errorMessages], index) => (React.createElement(Error, { key: index, header: title },
14
+ React.createElement(Box, { flexDirection: "column" }, errorMessages.map((message, index) => (React.createElement(Text, { key: index }, message)))))))));
15
+ };
@@ -0,0 +1,99 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseThemeCommand } from '../../class/base_theme_command.js';
3
+ import { CLI_AUTH_API_NAME } from '../../../cli/auth/cli_auth_constants.js';
4
+ import { THEME_ACTION_NOT_FOUND_ERROR_CODE, THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
5
+ import { EXECUTION_CONTEXT_API_NAME } from '../../../cli/features/execution_context/execution_context_constants.js';
6
+ import { renderOnce } from '../../../ui/ui_utils.js';
7
+ import { MissingCredentialsError } from '../../../cli/commands/auth/ui/missing_credentials_error.js';
8
+ import React from 'react';
9
+ import { THEME_DELETE_API_NAME } from '../../features/theme/delete/theme_delete_constants.js';
10
+ import { UnpermittedCommandError } from '../ui/unpermitted_command_error.js';
11
+ import { Error } from '../../../ui/message_box/error.js';
12
+ import { Text } from '../../../ui/text.js';
13
+ import { promptInput } from '../../../ui/prompts/prompt_input.js';
14
+ import { Warning } from '../../../ui/message_box/warning.js';
15
+ import { Info } from '../../../ui/message_box/info.js';
16
+ export class ThemeDeleteCommand extends BaseThemeCommand {
17
+ static summary = 'Permanently deletes the specified theme from your store.';
18
+ static description = 'This action cannot be undone, so make sure you really want to remove this theme.\n\nYou can run this command from a specific theme directory (ID not needed) or outside any theme directory (theme ID required).';
19
+ static examples = [
20
+ {
21
+ description: 'This will delete the theme with ID 123 permanently from your store. Make sure you have a backup if needed.',
22
+ command: '<%= config.bin %> <%= command.id %> 123'
23
+ }
24
+ ];
25
+ static hidden = true;
26
+ static args = {
27
+ id: Args.string({
28
+ description: 'Theme id',
29
+ name: 'id',
30
+ required: false,
31
+ type: 'string'
32
+ })
33
+ };
34
+ async run() {
35
+ const data = await this.parse(ThemeDeleteCommand);
36
+ const { args } = data;
37
+ const themeId = args.id;
38
+ const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
39
+ const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
40
+ const credentials = cliAuthApi.getCredentials();
41
+ if (!credentials) {
42
+ renderOnce(React.createElement(MissingCredentialsError, null));
43
+ return;
44
+ }
45
+ //
46
+ // if (!themeId) {
47
+ // renderOnce(<MissingThemeIdError />);
48
+ //
49
+ // return;
50
+ // }
51
+ // const executionContext = await executionContextApi.getExecutionContext();
52
+ //
53
+ // if (executionContext.type === EXECUTION_CONTEXTS.theme) {
54
+ // renderOnce(<ThemeDirectoryContextError />);
55
+ //
56
+ // return;
57
+ // }
58
+ renderOnce(React.createElement(Warning, { header: `Warning: This will permanently delete the theme {Theme_name} (ID: {theme_ID}) and cannot be undone.` }));
59
+ const { input: procced } = await promptInput('Proceed?');
60
+ if (!procced) {
61
+ renderOnce(React.createElement(Info, { header: "Theme deletion was cancelled." }));
62
+ return;
63
+ }
64
+ if (!themeId)
65
+ return;
66
+ const themeActionsApi = this.getApi(THEME_ACTIONS_API_NAME);
67
+ const deleteAction = themeActionsApi.getThemeAction({
68
+ actionType: THEME_ACTIONS_TYPES.delete,
69
+ themeId,
70
+ credentials
71
+ });
72
+ if (!deleteAction) {
73
+ renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "delete" }));
74
+ return;
75
+ }
76
+ const themeDeleteApi = this.getApi(THEME_DELETE_API_NAME);
77
+ try {
78
+ await themeDeleteApi.deleteTheme({
79
+ actionData: deleteAction.data,
80
+ credentials
81
+ });
82
+ }
83
+ catch (err) {
84
+ this._handleError(err, themeId);
85
+ return;
86
+ }
87
+ }
88
+ _handleError(err, themeId) {
89
+ if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && themeId) {
90
+ renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "init" }));
91
+ }
92
+ if (err?.message) {
93
+ renderOnce(React.createElement(Error, null,
94
+ React.createElement(Text, null, err.message)));
95
+ return;
96
+ }
97
+ this.error(String(err));
98
+ }
99
+ }
@@ -12,9 +12,9 @@ import { UnpermittedCommandError } from '../ui/unpermitted_command_error.js';
12
12
  import { MissingCredentialsError } from '../../../cli/commands/auth/ui/missing_credentials_error.js';
13
13
  import { ThemeCreatedSuccess } from './ui/theme_created_success.js';
14
14
  import { Text } from '../../../ui/text.js';
15
- import { Error } from '../../../ui/message_box/error.js';
16
15
  import { MissingThemeIdError } from '../ui/missing_theme_id_error.js';
17
16
  import { Box } from '../../../ui/box.js';
17
+ import { ErrorsList } from '../../../cli/ui/errors_list.js';
18
18
  export class ThemeInitCommand extends BaseThemeCommand {
19
19
  static summary = 'Creates a copy of an existing theme by duplicating it.';
20
20
  static description = 'The new theme will be named after the source theme with a "Copy" suffix and an incremental number.\n\nYou must run this command from the root directory (not inside any theme folder) and provide the ID of the theme you want to duplicate.';
@@ -73,15 +73,17 @@ export class ThemeInitCommand extends BaseThemeCommand {
73
73
  catch (err) {
74
74
  spinner?.stop();
75
75
  this._handleError(err, themeId);
76
+ //TODO analyze why on nodejs v22 this command does not exit properly, even all promises are resolved
77
+ this.exit();
76
78
  }
77
79
  }
78
80
  _handleError(err, themeId) {
79
81
  if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && themeId) {
80
82
  renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "init" }));
83
+ return;
81
84
  }
82
85
  if (err?.message) {
83
- renderOnce(React.createElement(Error, null,
84
- React.createElement(Text, null, err.message)));
86
+ renderOnce(React.createElement(ErrorsList, { errors: err.message }));
85
87
  return;
86
88
  }
87
89
  this.error(String(err));
@@ -2,7 +2,7 @@ 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
4
  import { THEME_ACTION_NOT_FOUND_ERROR_CODE, THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
5
- import { THEME_ARCHIVE_UPLOAD_ERROR, THEME_PUSH_API_NAME } from '../../features/theme/push/theme_push_constants.js';
5
+ import { THEME_ARCHIVE_UPLOAD_ERROR, THEME_FILES_UPLOAD_ERROR, THEME_PUSH_API_NAME } from '../../features/theme/push/theme_push_constants.js';
6
6
  import { ThemeMetaDataUtils } from '../../features/theme/utils/meta_data/theme_meta_data_utils.js';
7
7
  import { mapChecksumToTree } from '../../../utils/checksums/checksums_utils.js';
8
8
  import { mapToPermissionsTree } from '../../utils/directory_validator/directory_validator_utils.js';
@@ -20,13 +20,13 @@ import { THEME_FILES_STRUCTURE_FILE_NAME } from '../../features/theme/theme_cons
20
20
  import { THEME_MERGE_API_NAME } from '../../features/theme/merge/theme_merge_constants.js';
21
21
  import { ThemePushSkipInfo } from './ui/theme_push_skip_into.js';
22
22
  import { ThemeUnpermittedActionsError } from './ui/theme_unpermitted_actions_error.js';
23
- import { ThemeValidationErrors } from './ui/theme_validation_errors.js';
24
23
  import { Error } from '../../../ui/message_box/error.js';
25
24
  import { Text } from '../../../ui/text.js';
26
25
  import { ThemeWorkUrlMismatch } from '../ui/theme_work_url_mismatch.js';
27
26
  import { THEME_WORK_URL_MISMATCH_ERROR } from '../../features/theme/utils/meta_data/theme_meta_data_constants.js';
28
27
  import { ThemeFilesStructureUtils } from '../../features/theme/utils/files_structure/theme_files_structure_utils.js';
29
28
  import { ThemeInfoUtils } from '../../features/theme/info/theme_info_utils.js';
29
+ import { ErrorsList } from '../../../cli/ui/errors_list.js';
30
30
  export class ThemePushCommand extends BaseThemeCommand {
31
31
  static summary = 'Uploads your local theme files to the store and overwrites the current version of the theme in your store.';
32
32
  static description = 'Check your local changes before pushing.\n\nYou must run this command from a specific theme directory (ID not needed).';
@@ -111,16 +111,20 @@ export class ThemePushCommand extends BaseThemeCommand {
111
111
  return;
112
112
  }
113
113
  if (err?.code === THEME_ARCHIVE_UPLOAD_ERROR) {
114
- renderOnce(React.createElement(ThemeValidationErrors, { errors: err?.details }));
114
+ renderOnce(React.createElement(ErrorsList, { errors: err?.details }));
115
115
  return;
116
116
  }
117
117
  if (err?.code === THEME_WORK_URL_MISMATCH_ERROR) {
118
118
  this._renderUrlMismatchError();
119
119
  return;
120
120
  }
121
+ if (err?.code === THEME_FILES_UPLOAD_ERROR) {
122
+ return renderOnce(React.createElement(Error, { header: "Uploading theme files to the shop failed.\n" },
123
+ 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.")));
124
+ }
121
125
  if (err?.message) {
122
- renderOnce(React.createElement(Error, null,
123
- React.createElement(Text, null, err.message)));
126
+ console.log('error message', err.message);
127
+ renderOnce(React.createElement(ErrorsList, { errors: err.message }));
124
128
  return;
125
129
  }
126
130
  this.error(String(err));
@@ -5,5 +5,6 @@ export const THEME_COMMANDS_NAME = {
5
5
  push: 'theme:push',
6
6
  showChanges: 'theme:show-changes',
7
7
  verify: 'theme:verify',
8
- info: 'theme:info'
8
+ info: 'theme:info',
9
+ delete: 'theme:delete'
9
10
  };
@@ -7,8 +7,7 @@ export const THEME_ACTIONS_TYPES = {
7
7
  pull: 'pull',
8
8
  delete: 'delete',
9
9
  publish_form: 'publish_form',
10
- publish: 'publish',
11
- info: 'info'
10
+ publish: 'publish'
12
11
  };
13
12
  export const THEME_ACTION_DATA_TYPE = {
14
13
  file: 'file',
@@ -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,34 @@
1
+ import { STATUS_CODES } from '@dreamcommerce/star_core';
2
+ import { HttpErrorsFactory } from '../../../../../cli/class/errors/http/http_errors_factory.js';
3
+ import { DownloadFileErrorsFactory } from '../../../../../utils/download_file/download_file_errors_factory.js';
4
+ export class ThemeDeleteService {
5
+ #httpApi;
6
+ constructor(httpApi) {
7
+ this.#httpApi = httpApi;
8
+ }
9
+ async deleteTheme({ actionData, credentials }) {
10
+ try {
11
+ const { response } = this.#httpApi.deleteTheme({ actionData, shopUrl: credentials.shopUrl });
12
+ const { data, status } = await response;
13
+ if (status !== STATUS_CODES.ok)
14
+ return;
15
+ //TODO if is success remove theme directory
16
+ return data;
17
+ }
18
+ catch (err) {
19
+ //TODO to basic class
20
+ switch (err.response?.status) {
21
+ case 403:
22
+ throw HttpErrorsFactory.createForbiddenError();
23
+ case 401:
24
+ throw HttpErrorsFactory.createUnauthorizedError();
25
+ case 404:
26
+ throw HttpErrorsFactory.createNotFoundError();
27
+ default:
28
+ if (err.response?.status !== 200) {
29
+ throw DownloadFileErrorsFactory.downloadError(err.response.status);
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,2 @@
1
+ export const THEME_DELETE_FEATURE_NAME = 'ThemeDelete';
2
+ export const THEME_DELETE_API_NAME = 'ThemeDeleteApi';
@@ -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
+ }
@@ -1,7 +1,7 @@
1
1
  import FSTree from 'fs-tree-diff';
2
2
  import { join } from '../../../../../utils/path_utils.js';
3
3
  import { computeFileChecksum } from '../../../../../utils/checksums/checksums_utils.js';
4
- import { copyFile, copyFileSync, fileExists, getAllDirectoriesNamesInside } from '../../../../../utils/fs/fs_utils.js';
4
+ import { copyFileSync, fileExists, getAllDirectoriesNamesInside } from '../../../../../utils/fs/fs_utils.js';
5
5
  import { ThemeChecksumsUtils } from '../../utils/checksums/theme_checksums_utils.js';
6
6
  import walkSync from 'walk-sync';
7
7
  import { SHOPER_THEME_METADATA_DIR } from '../../../../constants/directory_contstants.js';
@@ -9,7 +9,7 @@ export class ThemeMergeService {
9
9
  async applyChanges(fromTheme, toTheme, changes) {
10
10
  FSTree.applyPatch(fromTheme, toTheme, changes, {
11
11
  create(inputPath, outputPath) {
12
- copyFile(inputPath, outputPath);
12
+ copyFileSync(inputPath, outputPath);
13
13
  },
14
14
  change(inputPath, outputPath) {
15
15
  copyFileSync(inputPath, outputPath);
@@ -105,18 +105,24 @@ export class ThemePushService {
105
105
  }
106
106
  async _uploadThemeFiles({ filesToUpload, themeRootDir, localFiles, credentials }) {
107
107
  try {
108
- const uploadedImageData = await this._uploadFiles(filesToUpload, credentials);
108
+ const { uploadedImageData, rejectedImageData } = await this._uploadFiles(filesToUpload, credentials);
109
109
  const newFilesList = ThemeImagesUtils.updateOriginalFilenameToUploadedFilename(localFiles, uploadedImageData);
110
110
  if (uploadedImageData.length)
111
111
  await ThemeImagesUtils.removeUploadedOriginalFiles(themeRootDir, uploadedImageData);
112
+ if (rejectedImageData.length)
113
+ await this._removeUploadedThemeFiles(rejectedImageData, themeRootDir);
112
114
  await this._createAFilesListFile(themeRootDir, newFilesList);
113
115
  }
114
116
  catch (err) {
115
117
  throw ThemePushErrorsFactory.createErrorWhileUploadingThemeFiles(credentials.shopUrl, err);
116
118
  }
117
119
  }
120
+ async _removeUploadedThemeFiles(uploadedImageData, themeRootDir) {
121
+ await Promise.all(uploadedImageData.map(({ location, originalFilename }) => removeFile(join(themeRootDir, location, originalFilename))));
122
+ }
118
123
  async _uploadFiles(uploadData, credentials) {
119
124
  const uploadedImageData = [];
125
+ const rejectedImageData = [];
120
126
  await Promise.all(uploadData.map(({ actionData, path }) => this.#themePushHttpApi
121
127
  .pushThemeData({
122
128
  actionData,
@@ -124,15 +130,22 @@ export class ThemePushService {
124
130
  shopUrl: credentials.shopUrl
125
131
  })
126
132
  .response.then((response) => {
127
- if (response.status !== 200 || !response.data.isSuccess)
128
- throw ThemePushErrorsFactory.createErrorWhileUploadingThemeFiles(credentials.shopUrl, response.data?.messages ?? []);
129
133
  uploadedImageData.push({
130
134
  location: dirname(path),
131
135
  originalFilename: basename(path),
132
136
  uploadedFilename: response.data.imageId
133
137
  });
138
+ })
139
+ .catch(() => {
140
+ rejectedImageData.push({
141
+ location: dirname(path),
142
+ originalFilename: basename(path)
143
+ });
134
144
  })));
135
- return uploadedImageData;
145
+ return {
146
+ uploadedImageData,
147
+ rejectedImageData
148
+ };
136
149
  }
137
150
  async _getActionDataForFilesToUpload({ pushAction, filesStructure, executionContext }) {
138
151
  const uploadData = [];
@@ -183,7 +196,7 @@ export class ThemePushService {
183
196
  return;
184
197
  const toUnixStyleFilesList = Object.entries(filesList).reduce((acc, [filePath, value]) => {
185
198
  const unixPath = toUnixPath(filePath);
186
- const finalPath = looksLikeDirectory(unixPath) ? join(unixPath, path.posix.sep) : unixPath;
199
+ const finalPath = looksLikeDirectory(unixPath) ? `${unixPath}${path.posix.sep}` : unixPath;
187
200
  return {
188
201
  ...acc,
189
202
  [finalPath]: value
@@ -3,3 +3,4 @@ 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
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,12 +1,14 @@
1
1
  import { AppError } from '../../../../cli/class/errors/app/app_error.js';
2
- import { THEME_ARCHIVE_UPLOAD_ERROR } from './theme_push_constants.js';
2
+ import { THEME_ARCHIVE_UPLOAD_ERROR, THEME_FILES_UPLOAD_ERROR } from './theme_push_constants.js';
3
3
  export class ThemePushErrorsFactory {
4
4
  static createErrorWhileUploadingThemeFiles(shopUrl, messages) {
5
5
  return new AppError({
6
- code: 'theme.push.error_uploading_theme_files',
6
+ code: THEME_FILES_UPLOAD_ERROR,
7
7
  message: `Error while uploading theme files to shop "${shopUrl}"`,
8
8
  level: 'error',
9
- details: messages
9
+ details: {
10
+ messages
11
+ }
10
12
  });
11
13
  }
12
14
  static createErrorWhileCreatingThemeArchive(shopUrl, error) {
@@ -25,7 +25,6 @@ export class ThemeChecksumsUtils {
25
25
  }
26
26
  static async createThemeChecksumsFiles(themeDir, checksums) {
27
27
  return new Promise((resolve, reject) => {
28
- // const sortedChecksums = _.pick(checksums, Object.keys(checksums).sort());
29
28
  const currentChecksumFilePath = this.getCurrentThemeChecksumsFilePath(themeDir);
30
29
  const initialChecksumFilePath = this.getInitialThemeChecksumsFilePath(themeDir);
31
30
  const checksumStream = createWriteStream(initialChecksumFilePath);
@@ -48,7 +47,6 @@ export class ThemeChecksumsUtils {
48
47
  }
49
48
  static async createThemeCurrentChecksumsFile(themeDir, checksums) {
50
49
  return new Promise((resolve, reject) => {
51
- // const sortedChecksums = _.pick(checksums, Object.keys(checksums).sort());
52
50
  const currentChecksumFilePath = this.getCurrentThemeChecksumsFilePath(themeDir);
53
51
  const checksumStream = createWriteStream(currentChecksumFilePath);
54
52
  checksumStream.write(JSON.stringify(checksums, null, JSON_FILE_INDENT));
@@ -23,7 +23,7 @@ export class ThemeMetaDataUtils {
23
23
  ...data,
24
24
  skin_id: data.themeId
25
25
  };
26
- delete data.themeId;
26
+ delete newData.themeId;
27
27
  await writeJSONFile(filePath, newData);
28
28
  }
29
29
  static async getThemeWorkUrl(themeDirectory) {
@@ -6,6 +6,7 @@ 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
8
  import { ThemeInfoCommand } from './commands/info/theme_info_command.js';
9
+ import { ThemeDeleteCommand } from './commands/delete/theme_delete_command.js';
9
10
  export const COMMANDS = {
10
11
  [THEME_COMMANDS_NAME.list]: ThemeListCommand,
11
12
  [THEME_COMMANDS_NAME.pull]: ThemePullCommand,
@@ -13,5 +14,6 @@ export const COMMANDS = {
13
14
  [THEME_COMMANDS_NAME.push]: ThemePushCommand,
14
15
  [THEME_COMMANDS_NAME.showChanges]: ThemeShowChangesCommand,
15
16
  [THEME_COMMANDS_NAME.verify]: ThemeVerifyCommand,
16
- [THEME_COMMANDS_NAME.info]: ThemeInfoCommand
17
+ [THEME_COMMANDS_NAME.info]: ThemeInfoCommand,
18
+ [THEME_COMMANDS_NAME.delete]: ThemeDeleteCommand
17
19
  };
@@ -41,6 +41,6 @@ export const downloadFile = async ({ dist, request }) => {
41
41
  throw DownloadFileErrorsFactory.downloadError(err.response.status);
42
42
  }
43
43
  }
44
+ throw DownloadFileErrorsFactory.downloadError('Unknown error');
44
45
  }
45
- throw DownloadFileErrorsFactory.downloadError('Unknown error');
46
46
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@shoper/cli",
3
3
  "packageManager": "yarn@3.2.0",
4
4
  "sideEffects": false,
5
- "version": "0.1.0-24",
5
+ "version": "0.1.0-26",
6
6
  "description": "CLI tool for Shoper",
7
7
  "author": "Joanna Firek",
8
8
  "license": "MIT",
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- import { Error } from '../../../../ui/message_box/error.js';
3
- import { Text } from '../../../../ui/text.js';
4
- export const ThemeValidationError = ({ messages, name }) => {
5
- return (React.createElement(Error, { header: name }, messages.map((message, index) => (React.createElement(Text, { key: index }, message)))));
6
- };
@@ -1,5 +0,0 @@
1
- import React from 'react';
2
- import { ThemeValidationError } from './theme_validation_error.js';
3
- export const ThemeValidationErrors = ({ errors }) => {
4
- return (React.createElement(React.Fragment, null, Object.entries(errors).map(([name, messages]) => (React.createElement(ThemeValidationError, { key: name, name: name, messages: messages })))));
5
- };