@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.
- package/build/cli/class/base_command.js +14 -0
- package/build/cli/commands/auth/cli_auth_remove_token_command.js +1 -3
- package/build/cli/commands/auth/cli_auth_switch_token_command.js +1 -2
- package/build/cli/commands/commands_constants.js +5 -4
- package/build/cli/core/cli_setup.js +33 -18
- package/build/cli/hooks/authorization/ensure_authorization_hook_constants.js +0 -1
- 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 +3 -7
- 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 +4 -19
- package/build/theme/commands/info/theme_info_command.js +3 -18
- package/build/theme/commands/init/theme_init_command.js +4 -17
- package/build/theme/commands/publish/theme_publish_command.js +4 -20
- package/build/theme/commands/pull/theme_pull_command.js +6 -26
- package/build/theme/commands/push/theme_push_command.js +17 -39
- package/build/theme/commands/theme_commands_constants.js +9 -9
- package/build/theme/commands/theme_verify_command.js +57 -18
- package/build/theme/commands/ui/theme_error.js +29 -0
- package/build/theme/features/theme/actions/theme_actions_constants.js +2 -1
- package/build/theme/features/theme/actions/theme_actions_utils.js +41 -1
- package/build/theme/features/theme/init/theme_init_initializer.js +3 -3
- package/build/theme/features/theme/push/service/theme_push_service.js +42 -164
- package/build/theme/features/theme/push/theme_push_initializer.js +1 -4
- 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 +38 -2
- package/build/theme/features/theme/utils/theme_images_utils.js +0 -18
- 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/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_constants.js +0 -1
- package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +1 -2
- package/build/theme/index.js +23 -3
- package/oclif.config.js +1 -1
- package/package.json +3 -3
- package/build/cli/commands/files_diff_command.js +0 -174
- 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
|
|
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 {
|
|
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:
|
|
6
|
-
authAddToken:
|
|
7
|
-
authRemoveToken:
|
|
8
|
-
switchToken:
|
|
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 {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
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
|
-
|
|
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
|
+
};
|
|
@@ -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 '
|
|
11
|
-
import { SHOPER_THEME_METADATA_DIR } from '
|
|
12
|
-
import {
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
}
|