@shoper/cli 0.2.0 → 0.2.1-1

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 (40) hide show
  1. package/build/cli/class/base_command.js +14 -0
  2. package/build/cli/commands/auth/cli_auth_remove_token_command.js +1 -3
  3. package/build/cli/commands/auth/cli_auth_switch_token_command.js +1 -2
  4. package/build/cli/commands/commands_constants.js +5 -4
  5. package/build/cli/core/cli_setup.js +33 -18
  6. package/build/cli/hooks/authorization/ensure_authorization_hook_constants.js +0 -1
  7. package/build/theme/class/archive/theme_archive.js +44 -0
  8. package/build/theme/class/archive/theme_archive_errors_factory.js +11 -0
  9. package/build/theme/class/checksums/theme_checksums.js +3 -7
  10. package/build/theme/class/files_upload/theme_files_upload.js +61 -0
  11. package/build/theme/class/files_upload/theme_files_upload_http_api.js +23 -0
  12. package/build/theme/commands/delete/theme_delete_command.js +4 -19
  13. package/build/theme/commands/info/theme_info_command.js +3 -18
  14. package/build/theme/commands/init/theme_init_command.js +4 -17
  15. package/build/theme/commands/publish/theme_publish_command.js +4 -20
  16. package/build/theme/commands/pull/theme_pull_command.js +6 -26
  17. package/build/theme/commands/push/theme_push_command.js +17 -39
  18. package/build/theme/commands/theme_commands_constants.js +9 -9
  19. package/build/theme/commands/theme_verify_command.js +57 -18
  20. package/build/theme/commands/ui/theme_error.js +29 -0
  21. package/build/theme/features/theme/actions/theme_actions_constants.js +2 -1
  22. package/build/theme/features/theme/actions/theme_actions_utils.js +41 -1
  23. package/build/theme/features/theme/init/theme_init_initializer.js +3 -3
  24. package/build/theme/features/theme/push/service/theme_push_service.js +42 -164
  25. package/build/theme/features/theme/push/theme_push_initializer.js +1 -4
  26. package/build/theme/features/theme/utils/files_structure/theme_file_structure_errors_factory.js +10 -0
  27. package/build/theme/features/theme/utils/files_structure/theme_files_structure_utils.js +38 -2
  28. package/build/theme/features/theme/utils/theme_images_utils.js +0 -18
  29. package/build/theme/features/theme/verify/api/theme_verify_api.js +13 -0
  30. package/build/theme/features/theme/verify/http/theme_verify_http_api.js +30 -0
  31. package/build/theme/features/theme/verify/theme_verify_constants.js +2 -0
  32. package/build/theme/features/theme/verify/theme_verify_initializer.js +19 -0
  33. package/build/theme/features/theme/verify/verify/theme_verify_service.js +55 -0
  34. package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_constants.js +0 -1
  35. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +1 -2
  36. package/build/theme/index.js +23 -3
  37. package/oclif.config.js +1 -1
  38. package/package.json +3 -3
  39. package/build/cli/commands/files_diff_command.js +0 -174
  40. package/build/theme/commands/theme_show_changes_command.js +0 -61
@@ -5,6 +5,8 @@ export class BaseCommand extends Command {
5
5
  commandBus;
6
6
  eventBus;
7
7
  globalCoresContainersRegistry;
8
+ flags;
9
+ args;
8
10
  constructor(argv, config) {
9
11
  super(argv, config);
10
12
  const { queryBus, commandBus, eventBus, globalCoresContainersRegistry } = getStarCoreEnvironment();
@@ -22,4 +24,16 @@ export class BaseCommand extends Command {
22
24
  _createApiDuplicationError(apiName) {
23
25
  return new AppError(`${apiName} hasn't been registered`);
24
26
  }
27
+ async init() {
28
+ await super.init();
29
+ const { args, flags } = await this.parse({
30
+ flags: this.ctor.flags,
31
+ baseFlags: super.ctor.baseFlags,
32
+ enableJsonFlag: this.ctor.enableJsonFlag,
33
+ args: this.ctor.args,
34
+ strict: this.ctor.strict
35
+ });
36
+ this.flags = flags;
37
+ this.args = args;
38
+ }
25
39
  }
@@ -30,9 +30,7 @@ export class CliAuthRemoveTokenCommand extends BaseCliCommand {
30
30
  };
31
31
  async run() {
32
32
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
33
- const data = await this.parse(CliAuthRemoveTokenCommand);
34
- const { args } = data;
35
- const { index } = args;
33
+ const { index } = this.args;
36
34
  if (!index || !cliAuthTokensApi.hasToken(index)) {
37
35
  renderOnce(React.createElement(MissingTokenIndexError, { command: React.createElement(Command, null, "shoper auth remove-token [TOKEN_INDEX]") }));
38
36
  return;
@@ -26,8 +26,7 @@ export class CliAuthSwitchTokenCommand extends BaseCliCommand {
26
26
  };
27
27
  async run() {
28
28
  const cliAuthTokensApi = this.getApi(CLI_AUTH_TOKENS_API_NAME);
29
- const { args } = await this.parse(CliAuthSwitchTokenCommand);
30
- const { index } = args;
29
+ const { index } = this.args;
31
30
  if (!index || !cliAuthTokensApi.hasToken(index)) {
32
31
  renderOnce(React.createElement(MissingTokenIndexError, { command: React.createElement(Command, null, "shoper auth switch-token [TOKEN_INDEX]") }));
33
32
  return;
@@ -1,10 +1,11 @@
1
+ export const CLI_AUTH_TOPIC_NAME = 'auth';
1
2
  export const CLI_COMMANDS_NAMES = {
2
3
  help: 'help',
3
4
  version: 'version',
4
5
  update: 'update',
5
- authListTokens: 'auth:list-tokens',
6
- authAddToken: 'auth:add-token',
7
- authRemoveToken: 'auth:remove-token',
8
- switchToken: 'auth:switch-token',
6
+ authListTokens: `${CLI_AUTH_TOPIC_NAME}:list-tokens`,
7
+ authAddToken: `${CLI_AUTH_TOPIC_NAME}:add-token`,
8
+ authRemoveToken: `${CLI_AUTH_TOPIC_NAME}:remove-token`,
9
+ switchToken: `${CLI_AUTH_TOPIC_NAME}:switch-token`,
9
10
  uiDump: 'ui-dump'
10
11
  };
@@ -8,14 +8,9 @@ import { ExecutionContextInitializer } from '../features/execution_context/execu
8
8
  import { CliVersionInitializer } from '../features/version/cli_version_initializer.js';
9
9
  import { CliAuthTokensInitializer } from '../auth/tokens/cli_auth_tokens_initalizer.js';
10
10
  import { CliAuthInitializer } from '../auth/cli_auth_initializer.js';
11
- import { ThemesListInitializer } from '../../theme/features/themes/list/themes_list_initializer.js';
12
- import { ThemeInitInitializer } from '../../theme/features/theme/init/theme_init_initializer.js';
13
- import { ThemeFetchInitializer } from '../../theme/features/theme/fetch/theme_fetch_initializer.js';
14
- import { ThemeMergeInitializer } from '../../theme/features/theme/merge/theme_merge_initializer.js';
15
- import { ThemeActionsInitializer } from '../../theme/features/theme/actions/theme_actions_initializer.js';
16
- import { ThemePushInitializer } from '../../theme/features/theme/push/theme_push_initializer.js';
17
- import { ThemeDeleteInitializer } from '../../theme/features/theme/delete/theme_delete_initalizer.js';
18
- import { ThemeSkinstoreInitializer } from '../../theme/features/theme/skinstore/theme_skinstore_initialzier.js';
11
+ import { THEME_TOPIC_NAME } from '../../theme/commands/theme_commands_constants.js';
12
+ import { getThemeInitializersForCommand } from '../../theme/index.js';
13
+ import { CLI_AUTH_TOPIC_NAME, CLI_COMMANDS_NAMES } from '../commands/commands_constants.js';
19
14
  tmp.setGracefulCleanup();
20
15
  export const cliSetup = async () => {
21
16
  //TODO jakis ładny komuniakt błedu
@@ -27,18 +22,9 @@ export const cliSetup = async () => {
27
22
  HTTPRequesterInitializer,
28
23
  CliDataDirectoryInitializer,
29
24
  ExecutionContextInitializer,
30
- CliVersionInitializer,
31
25
  CliAuthTokensInitializer,
32
26
  CliAuthInitializer,
33
- ThemesListInitializer,
34
- ThemeActionsInitializer,
35
- //TODO dnamicznie inicjalizowanie ficzurów wykorzystywanych w poszczególnych komendach
36
- ThemeInitInitializer,
37
- ThemeMergeInitializer,
38
- ThemeFetchInitializer,
39
- ThemePushInitializer,
40
- ThemeDeleteInitializer,
41
- ThemeSkinstoreInitializer
27
+ ...getCommandBaseInitializers()
42
28
  ],
43
29
  options: {
44
30
  featuresTracking: false,
@@ -46,3 +32,32 @@ export const cliSetup = async () => {
46
32
  }
47
33
  });
48
34
  };
35
+ const getCommandBaseInitializers = () => {
36
+ // console.log('process.argv', process.argv);
37
+ if (isCommandsTopic(process.argv[2]))
38
+ return getCommandWithTopicBaseInitializers();
39
+ return getCommandWithoutTopicBaseInitializers();
40
+ };
41
+ const isCommandsTopic = (arg) => {
42
+ return arg === THEME_TOPIC_NAME || arg === CLI_AUTH_TOPIC_NAME;
43
+ };
44
+ const getCommandWithTopicBaseInitializers = () => {
45
+ const topic = process.argv[2];
46
+ const command = process.argv[3];
47
+ switch (topic) {
48
+ case THEME_TOPIC_NAME: {
49
+ return getThemeInitializersForCommand(command);
50
+ }
51
+ }
52
+ return [];
53
+ };
54
+ const getCommandWithoutTopicBaseInitializers = () => {
55
+ const command = process.argv[3];
56
+ switch (command) {
57
+ case CLI_COMMANDS_NAMES.version:
58
+ case CLI_COMMANDS_NAMES.update: {
59
+ return [CliVersionInitializer];
60
+ }
61
+ }
62
+ return [];
63
+ };
@@ -4,6 +4,5 @@ export const COMMANDS_THAT_REQUIRE_AUTHORIZATION = [
4
4
  THEME_COMMANDS_NAME.pull,
5
5
  THEME_COMMANDS_NAME.list,
6
6
  THEME_COMMANDS_NAME.init,
7
- THEME_COMMANDS_NAME.showChanges,
8
7
  THEME_COMMANDS_NAME.verify
9
8
  ];
@@ -0,0 +1,44 @@
1
+ import globs from 'fast-glob';
2
+ import { createZip } from '../../../utils/zip/create_zip_utils.js';
3
+ import { ThemeFilesStructureUtils } from '../../features/theme/utils/files_structure/theme_files_structure_utils.js';
4
+ import { extname, join } from '../../../utils/path_utils.js';
5
+ import { formatJSONFile } from '../../../utils/fs/fs_utils.js';
6
+ import { ThemeArchiveErrorsFactory } from './theme_archive_errors_factory.js';
7
+ import { ThemeFileStructureErrorsFactory } from '../../features/theme/utils/files_structure/theme_file_structure_errors_factory.js';
8
+ import { ThemeActionsUtils } from '../../features/theme/actions/theme_actions_utils.js';
9
+ export class ThemeArchive {
10
+ #themeRootDir;
11
+ constructor(themeRootDir) {
12
+ this.#themeRootDir = themeRootDir;
13
+ }
14
+ async createFullArchive({ dist, actionValue, actionType }) {
15
+ const filesStructure = await ThemeFilesStructureUtils.getThemeFilesStructure(this.#themeRootDir);
16
+ if (!filesStructure)
17
+ throw ThemeFileStructureErrorsFactory.createNoFilesStructureError();
18
+ try {
19
+ const filesInThemeDirectory = await globs(ThemeActionsUtils.getFilesGlobsThatMatchesActionName({
20
+ actionType,
21
+ actionValue,
22
+ filesStructure
23
+ }), {
24
+ suppressErrors: true,
25
+ onlyFiles: true,
26
+ cwd: this.#themeRootDir
27
+ });
28
+ await this._formatJsonFiles(this.#themeRootDir, filesInThemeDirectory);
29
+ return createZip({
30
+ files: filesInThemeDirectory,
31
+ baseDir: this.#themeRootDir,
32
+ dist
33
+ });
34
+ }
35
+ catch (err) {
36
+ throw ThemeArchiveErrorsFactory.createErrorWhileCreatingThemeArchive(err);
37
+ }
38
+ }
39
+ async _formatJsonFiles(themeRootDir, filesToUpload) {
40
+ await Promise.all(filesToUpload
41
+ .filter((path) => extname(path).toLowerCase() === '.json')
42
+ .map((jsonFile) => formatJSONFile(join(themeRootDir, jsonFile))));
43
+ }
44
+ }
@@ -0,0 +1,11 @@
1
+ import { AppError } from '../../../cli/class/errors/app/app_error.js';
2
+ export class ThemeArchiveErrorsFactory {
3
+ static createErrorWhileCreatingThemeArchive(error) {
4
+ return new AppError({
5
+ code: 'theme_archive.error_creating_archive',
6
+ message: `Error while creating theme archive`,
7
+ level: 'error',
8
+ stack: error.stack
9
+ });
10
+ }
11
+ }
@@ -7,9 +7,9 @@ import { JSON_FILE_INDENT } from '../../../cli/cli_constants.js';
7
7
  import { ThemeChecksumsErrorFactory } from './theme_checksums_error_factory.js';
8
8
  import { computeChecksumsFromFilesStructure, computeDirectoriesChecksums, computeFileChecksum } from '../../../utils/checksums/checksums_utils.js';
9
9
  import { normalize } from 'node:path';
10
- import { ThemePushUtils } from '../../../theme/features/theme/push/theme_push_utils.js';
11
- import { SHOPER_THEME_METADATA_DIR } from '../../../theme/constants/directory_contstants.js';
12
- import { THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME, THEME_CURRENT_CHECKSUMS_FILE_NAME, THEME_INITIAL_CHECKSUMS_FILE_NAME } from '../../../theme/features/theme/theme_constants.js';
10
+ import { ThemePushUtils } from '../../features/theme/push/theme_push_utils.js';
11
+ import { SHOPER_THEME_METADATA_DIR } from '../../constants/directory_contstants.js';
12
+ import { THEME_CURRENT_CHECKSUMS_FILE_NAME, THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME, THEME_INITIAL_CHECKSUMS_FILE_NAME, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME } from '../../features/theme/theme_constants.js';
13
13
  export class ThemeChecksums {
14
14
  #themeDir;
15
15
  #currentChecksumsFilePath;
@@ -61,10 +61,6 @@ export class ThemeChecksums {
61
61
  const checksums = await this.getInitialChecksums();
62
62
  return checksums[toCurrentPlatformPath(path)];
63
63
  }
64
- getInitialChecksumFromPathSync(path) {
65
- const checksums = this.getInitialChecksumsSync();
66
- return checksums[toCurrentPlatformPath(path)];
67
- }
68
64
  async hasThemeBeenModified() {
69
65
  const initialChecksums = await this._getInitialChecksumsVerification();
70
66
  const currentChecksums = await this._getCurrentChecksumsVerification();
@@ -0,0 +1,61 @@
1
+ import { basename, dirname } from '../../../utils/path_utils.js';
2
+ import { createReadStream } from 'node:fs';
3
+ import { THEME_WILDCARD_ACTION_NAME } from '../../features/theme/actions/service/theme_actions_service_constants.js';
4
+ import { ThemePushErrorsFactory } from '../../features/theme/push/theme_push_errors_factory.js';
5
+ export class ThemeFilesUpload {
6
+ #credentials;
7
+ #themeFilesUploadHttpApi;
8
+ constructor({ credentials, themeFilesUploadHttpApi }) {
9
+ this.#themeFilesUploadHttpApi = themeFilesUploadHttpApi;
10
+ this.#credentials = credentials;
11
+ }
12
+ async uploadArchive({ action, themeArchivePath, credentials }) {
13
+ try {
14
+ const request = this.#themeFilesUploadHttpApi.uploadFiles({
15
+ actionData: action.data[THEME_WILDCARD_ACTION_NAME],
16
+ stream: createReadStream(themeArchivePath),
17
+ shopUrl: credentials.shopUrl
18
+ });
19
+ const response = await request.response;
20
+ if (response.status !== 200 || !response.data.isSuccess)
21
+ throw response;
22
+ return response.data;
23
+ }
24
+ catch (err) {
25
+ throw ThemePushErrorsFactory.createErrorWhileUploadingTheme(credentials.shopUrl, err.response.data.messages);
26
+ }
27
+ }
28
+ async uploadFiles(uploadData) {
29
+ const uploadedImageData = [];
30
+ const rejectedImageData = [];
31
+ await Promise.all(uploadData.map(({ actionData, path }) => this.#themeFilesUploadHttpApi
32
+ //TODO tajpings
33
+ .uploadFiles({
34
+ actionData,
35
+ stream: createReadStream(path),
36
+ shopUrl: this.#credentials.shopUrl
37
+ })
38
+ .response.then((response) => {
39
+ const { imageId, messages, isSuccess } = response.data;
40
+ uploadedImageData.push({
41
+ isSuccess,
42
+ messages,
43
+ location: dirname(path),
44
+ originalFilename: basename(path),
45
+ uploadedFilename: imageId
46
+ });
47
+ })
48
+ .catch((err) => {
49
+ rejectedImageData.push({
50
+ isSuccess: err?.response?.data?.isSuccess ?? false,
51
+ messages: err?.response?.data?.messages ?? [],
52
+ location: dirname(path),
53
+ originalFilename: basename(path)
54
+ });
55
+ })));
56
+ return {
57
+ uploadedImageData,
58
+ rejectedImageData
59
+ };
60
+ }
61
+ }
@@ -0,0 +1,23 @@
1
+ export class ThemeFilesUploadHttpApi {
2
+ #httpApi;
3
+ constructor(httpApi) {
4
+ this.#httpApi = httpApi;
5
+ }
6
+ uploadFiles({ actionData, shopUrl, stream }) {
7
+ const { method, url } = actionData;
8
+ return this.#httpApi.fetch({
9
+ url: `${shopUrl}${url}`,
10
+ method,
11
+ //TODO Remove after fix
12
+ // method: 'POST',
13
+ data: stream,
14
+ sanitizeOptions: {
15
+ disable: true
16
+ },
17
+ headers: {
18
+ 'Content-Type': 'application/octet-stream'
19
+ },
20
+ isPrivate: true
21
+ });
22
+ }
23
+ }
@@ -1,14 +1,13 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { BaseThemeCommand } from '../../class/base_theme_command.js';
3
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';
4
+ import { THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
5
5
  import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../../cli/features/execution_context/execution_context_constants.js';
6
6
  import { renderOnce } from '../../../ui/ui_utils.js';
7
7
  import { MissingCredentialsError } from '../../../cli/commands/auth/ui/missing_credentials_error.js';
8
8
  import React from 'react';
9
9
  import { THEME_DELETE_API_NAME } from '../../features/theme/delete/theme_delete_constants.js';
10
10
  import { UnpermittedCommandError } from '../ui/unpermitted_command_error.js';
11
- import { Error } from '../../../ui/message_box/error.js';
12
11
  import { Text } from '../../../ui/text.js';
13
12
  import { Info } from '../../../ui/message_box/info.js';
14
13
  import { MissingThemeIdError } from '../ui/missing_theme_id_error.js';
@@ -16,6 +15,7 @@ import { Box } from '../../../ui/box.js';
16
15
  import { ThemeDeletedSuccessfully } from './ui/theme_deleted_successfully.js';
17
16
  import { ThemeDeletionWarning } from './ui/theme_deletion_warning.js';
18
17
  import { promptConfirmation } from '../../../ui/prompts/prompt_confirmation.js';
18
+ import { ThemeError } from '../ui/theme_error.js';
19
19
  export class ThemeDeleteCommand extends BaseThemeCommand {
20
20
  static summary = 'Permanently deletes the specified theme from your store.';
21
21
  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).';
@@ -25,7 +25,6 @@ export class ThemeDeleteCommand extends BaseThemeCommand {
25
25
  command: '<%= config.bin %> <%= command.id %> 123'
26
26
  }
27
27
  ];
28
- static hidden = true;
29
28
  static args = {
30
29
  id: Args.string({
31
30
  description: 'Theme id',
@@ -35,9 +34,7 @@ export class ThemeDeleteCommand extends BaseThemeCommand {
35
34
  })
36
35
  };
37
36
  async run() {
38
- const data = await this.parse(ThemeDeleteCommand);
39
- const { args } = data;
40
- const themeId = args.id;
37
+ const themeId = this.args.id;
41
38
  const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
42
39
  const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
43
40
  const credentials = cliAuthApi.getCredentials();
@@ -92,20 +89,8 @@ export class ThemeDeleteCommand extends BaseThemeCommand {
92
89
  return;
93
90
  }
94
91
  catch (err) {
95
- this._handleError(err, themeId);
92
+ renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
96
93
  return;
97
94
  }
98
95
  }
99
- _handleError(err, themeId) {
100
- if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && themeId) {
101
- renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "delete" }));
102
- return;
103
- }
104
- if (err?.message) {
105
- renderOnce(React.createElement(Error, null,
106
- React.createElement(Text, null, err.message)));
107
- return;
108
- }
109
- this.error(String(err));
110
- }
111
96
  }
@@ -9,13 +9,12 @@ import { Args } from '@oclif/core';
9
9
  import { ThemeMetaDataUtils } from '../../features/theme/utils/meta_data/theme_meta_data_utils.js';
10
10
  import { MissingThemeIdError } from '../ui/missing_theme_id_error.js';
11
11
  import { Text } from '../../../ui/text.js';
12
- import { THEME_WORK_URL_MISMATCH_ERROR } from '../../features/theme/utils/meta_data/theme_meta_data_constants.js';
13
12
  import { Error } from '../../../ui/message_box/error.js';
14
- import { ThemeWorkUrlMismatch } from '../ui/theme_work_url_mismatch.js';
15
13
  import { Table } from '../../../ui/table/table.js';
16
14
  import { ThemeInfoCommandUtils } from './theme_info_command_utils.js';
17
15
  import { InvalidThemeIdError } from '../ui/invalid_theme_id.js';
18
16
  import { Box } from '../../../ui/box.js';
17
+ import { ThemeError } from '../ui/theme_error.js';
19
18
  export class ThemeInfoCommand extends BaseThemeCommand {
20
19
  static summary = 'View details about the current theme.';
21
20
  static description = 'Displays key information about the theme you’re working on — including its ID, name, description (if provided), and status.\n\nYou can run this command from a specific theme directory (ID not needed) or outside any theme directory (theme ID required).';
@@ -33,9 +32,7 @@ export class ThemeInfoCommand extends BaseThemeCommand {
33
32
  })
34
33
  };
35
34
  async run() {
36
- const data = await this.parse(ThemeInfoCommand);
37
- const { args } = data;
38
- const themeId = args.id;
35
+ const themeId = this.args.id;
39
36
  const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
40
37
  const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
41
38
  const themesListApi = this.getApi(THEMES_LIST_API_NAME);
@@ -73,21 +70,9 @@ export class ThemeInfoCommand extends BaseThemeCommand {
73
70
  this._displayThemeInfo(theme);
74
71
  }
75
72
  catch (err) {
76
- this._handleError(err);
73
+ renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
77
74
  }
78
75
  }
79
- _handleError(err) {
80
- if (err?.code === THEME_WORK_URL_MISMATCH_ERROR) {
81
- renderOnce(React.createElement(ThemeWorkUrlMismatch, { command: "info" }));
82
- return;
83
- }
84
- if (err?.message) {
85
- renderOnce(React.createElement(Error, null,
86
- React.createElement(Text, null, err.message)));
87
- return;
88
- }
89
- this.error(String(err));
90
- }
91
76
  _displayThemeInfo(theme) {
92
77
  renderOnce(React.createElement(Table, { data: ThemeInfoCommandUtils.mapThemeMetaDataToTableData(theme) }));
93
78
  }
@@ -4,7 +4,7 @@ import { THEME_INIT_API_NAME } from '../../features/theme/init/theme_init_consta
4
4
  import { CLI_AUTH_API_NAME } from '../../../cli/auth/cli_auth_constants.js';
5
5
  import ora from 'ora';
6
6
  import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../../cli/features/execution_context/execution_context_constants.js';
7
- import { THEME_ACTION_NOT_FOUND_ERROR_CODE, THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
7
+ import { THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
8
8
  import { renderOnce } from '../../../ui/ui_utils.js';
9
9
  import { ThemeDirectoryContextError } from '../ui/theme_directory_context_error.js';
10
10
  import React from 'react';
@@ -14,7 +14,7 @@ import { ThemeCreatedSuccess } from './ui/theme_created_success.js';
14
14
  import { Text } from '../../../ui/text.js';
15
15
  import { MissingThemeIdError } from '../ui/missing_theme_id_error.js';
16
16
  import { Box } from '../../../ui/box.js';
17
- import { ValidationErrors } from '../../../ui/validation_errors/validation_errors.js';
17
+ import { ThemeError } from '../ui/theme_error.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.';
@@ -33,9 +33,7 @@ export class ThemeInitCommand extends BaseThemeCommand {
33
33
  })
34
34
  };
35
35
  async run() {
36
- const data = await this.parse(ThemeInitCommand);
37
- const { args } = data;
38
- const themeId = args.id;
36
+ const themeId = this.args.id;
39
37
  const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
40
38
  const themeInitApi = this.getApi(THEME_INIT_API_NAME);
41
39
  const themeActionsApi = this.getApi(THEME_ACTIONS_API_NAME);
@@ -72,22 +70,11 @@ export class ThemeInitCommand extends BaseThemeCommand {
72
70
  }
73
71
  catch (err) {
74
72
  spinner?.stop();
75
- this._handleError(err, themeId);
73
+ renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
76
74
  //TODO analyze why on nodejs v22 this command does not exit properly, even all promises are resolved
77
75
  this.exit();
78
76
  }
79
77
  }
80
- _handleError(err, themeId) {
81
- if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && themeId) {
82
- renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "init" }));
83
- return;
84
- }
85
- if (err?.message) {
86
- renderOnce(React.createElement(ValidationErrors, { errors: err.message }));
87
- return;
88
- }
89
- this.error(String(err));
90
- }
91
78
  _renderMissingThemeIdError() {
92
79
  renderOnce(React.createElement(MissingThemeIdError, null,
93
80
  React.createElement(Box, { flexDirection: "column", gap: 1 },
@@ -1,17 +1,15 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { BaseThemeCommand } from '../../class/base_theme_command.js';
3
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';
4
+ import { THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
5
5
  import { EXECUTION_CONTEXT_API_NAME, EXECUTION_CONTEXTS } from '../../../cli/features/execution_context/execution_context_constants.js';
6
6
  import { renderOnce } from '../../../ui/ui_utils.js';
7
7
  import { MissingCredentialsError } from '../../../cli/commands/auth/ui/missing_credentials_error.js';
8
8
  import React from 'react';
9
- import { UnpermittedCommandError } from '../ui/unpermitted_command_error.js';
10
- import { Error } from '../../../ui/message_box/error.js';
11
- import { Text } from '../../../ui/text.js';
12
9
  import { MissingThemeIdError } from '../ui/missing_theme_id_error.js';
13
10
  import { THEME_SKINSTORE_API_NAME } from '../../features/theme/skinstore/theme_publish_constants.js';
14
11
  import { Form } from '../../../cli/features/controls/ui/form.js';
12
+ import { ThemeError } from '../ui/theme_error.js';
15
13
  export class ThemePublishCommand extends BaseThemeCommand {
16
14
  static summary = 'Permanently deletes the specified theme from your store.';
17
15
  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).';
@@ -31,9 +29,7 @@ export class ThemePublishCommand extends BaseThemeCommand {
31
29
  })
32
30
  };
33
31
  async run() {
34
- const data = await this.parse(ThemePublishCommand);
35
- const { args } = data;
36
- const themeId = args.id;
32
+ const themeId = this.args.id;
37
33
  const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
38
34
  const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
39
35
  const credentials = cliAuthApi.getCredentials();
@@ -73,20 +69,8 @@ export class ThemePublishCommand extends BaseThemeCommand {
73
69
  });
74
70
  }
75
71
  catch (err) {
76
- this._handleError(err, themeId);
72
+ renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
77
73
  return;
78
74
  }
79
75
  }
80
- _handleError(err, themeId) {
81
- if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && themeId) {
82
- renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "delete" }));
83
- return;
84
- }
85
- if (err?.message) {
86
- renderOnce(React.createElement(Error, null,
87
- React.createElement(Text, null, err.message)));
88
- return;
89
- }
90
- this.error(String(err));
91
- }
92
76
  }
@@ -7,7 +7,7 @@ import ora from 'ora';
7
7
  import { THEME_MERGE_API_NAME } from '../../features/theme/merge/theme_merge_constants.js';
8
8
  import tmp from 'tmp-promise';
9
9
  import { join } from '../../../utils/path_utils.js';
10
- import { THEME_ACTION_NOT_FOUND_ERROR_CODE, THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
10
+ import { THEME_ACTIONS_API_NAME, THEME_ACTIONS_TYPES } from '../../features/theme/actions/theme_actions_constants.js';
11
11
  import process from 'node:process';
12
12
  import { ThemeResourcesWithIdDirectoryUtils } from '../../features/theme/utils/resources/theme_resources_with_id_directory_utils.js';
13
13
  import { renderOnce } from '../../../ui/ui_utils.js';
@@ -22,11 +22,9 @@ import { promptConfirmation } from '../../../ui/prompts/prompt_confirmation.js';
22
22
  import { ThemePulledSuccess } from './ui/theme_pulled_success.js';
23
23
  import { Info } from '../../../ui/message_box/info.js';
24
24
  import { directoryExists } from '../../../utils/fs/fs_utils.js';
25
- import { THEME_WORK_URL_MISMATCH_ERROR } from '../../features/theme/utils/meta_data/theme_meta_data_constants.js';
26
- import { ThemeWorkUrlMismatch } from '../ui/theme_work_url_mismatch.js';
27
- import { Error } from '../../../ui/message_box/error.js';
28
25
  import { ThemeMetaDataUtils } from '../../features/theme/utils/meta_data/theme_meta_data_utils.js';
29
26
  import { ThemeChecksums } from '../../class/checksums/theme_checksums.js';
27
+ import { ThemeError } from '../ui/theme_error.js'; //TODO jak jest error w pullu wowczas usuwamy docelowo pociagniety skin
30
28
  //TODO jak jest error w pullu wowczas usuwamy docelowo pociagniety skin
31
29
  export class ThemePullCommand extends BaseThemeCommand {
32
30
  static summary = 'Downloads the current version of your theme from the store and overwrites your local theme files.';
@@ -57,9 +55,7 @@ export class ThemePullCommand extends BaseThemeCommand {
57
55
  };
58
56
  #spinner;
59
57
  async run() {
60
- const data = await this.parse(ThemePullCommand);
61
- const { args, flags } = data;
62
- const themeId = args.id;
58
+ const themeId = this.args.id;
63
59
  const cliAuthApi = this.getApi(CLI_AUTH_API_NAME);
64
60
  const themeFetchApi = this.getApi(THEME_FETCH_API_NAME);
65
61
  const executionContextApi = this.getApi(EXECUTION_CONTEXT_API_NAME);
@@ -78,7 +74,7 @@ export class ThemePullCommand extends BaseThemeCommand {
78
74
  themeFetchApi,
79
75
  themeActionsApi,
80
76
  credentials,
81
- fetchType: flags.type
77
+ fetchType: this.flags.type
82
78
  });
83
79
  }
84
80
  if (executionContext.type === EXECUTION_CONTEXTS.theme) {
@@ -87,7 +83,7 @@ export class ThemePullCommand extends BaseThemeCommand {
87
83
  themeId: _themeId,
88
84
  themeFetchApi,
89
85
  themeActionsApi,
90
- fetchType: flags.type,
86
+ fetchType: this.flags.type,
91
87
  executionContext,
92
88
  credentials
93
89
  });
@@ -95,25 +91,9 @@ export class ThemePullCommand extends BaseThemeCommand {
95
91
  }
96
92
  catch (err) {
97
93
  this.#spinner?.stop();
98
- this._handleError(err, _themeId);
94
+ renderOnce(React.createElement(ThemeError, { err: err, executionContext: executionContext }));
99
95
  }
100
96
  }
101
- _handleError(err, _themeId) {
102
- if (err?.code === THEME_ACTION_NOT_FOUND_ERROR_CODE && _themeId) {
103
- this._renderUnpermittedCommandError(_themeId);
104
- return;
105
- }
106
- if (err?.code === THEME_WORK_URL_MISMATCH_ERROR) {
107
- renderOnce(React.createElement(ThemeWorkUrlMismatch, { command: "pull" }));
108
- return;
109
- }
110
- if (err?.message) {
111
- renderOnce(React.createElement(Error, null,
112
- React.createElement(Text, null, err.message)));
113
- return;
114
- }
115
- this.error(String(err));
116
- }
117
97
  _renderUnpermittedCommandError(themeId) {
118
98
  renderOnce(React.createElement(UnpermittedCommandError, { themeId: themeId, commandName: "pull" }));
119
99
  }