@shoper/cli 0.1.0-30 → 0.1.0-32

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 (21) hide show
  1. package/build/theme/commands/delete/theme_delete_command.js +2 -2
  2. package/build/theme/commands/init/theme_init_command.js +1 -1
  3. package/build/theme/commands/list/theme_list_command_utils.js +2 -2
  4. package/build/theme/commands/push/theme_push_command.js +3 -2
  5. package/build/theme/features/theme/delete/service/theme_delete_service.js +6 -3
  6. package/build/theme/features/theme/push/service/theme_push_service.js +2 -1
  7. package/build/theme/features/theme/skinstore/api/theme_skinstore_api.js +17 -0
  8. package/build/theme/features/theme/skinstore/http/theme_skinstore_http_api.js +7 -0
  9. package/build/theme/features/theme/skinstore/service/theme_skinstore_service.js +3 -0
  10. package/build/theme/features/themes/list/services/themes_list_service.js +4 -5
  11. package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +1 -0
  12. package/build/ui/form/controls_mappers.js +39 -0
  13. package/build/ui/form/form.js +5 -0
  14. package/build/ui/form/form_constants.js +13 -0
  15. package/build/{cli/ui → ui}/validation_errors/validation_error_content.js +2 -2
  16. package/build/{cli/ui → ui}/validation_errors/validation_errors.js +3 -3
  17. package/build/utils/download_file/download_file_utils.js +2 -0
  18. package/package.json +3 -2
  19. /package/build/theme/features/theme/{publish → skinstore}/theme_publish_constants.js +0 -0
  20. /package/build/theme/features/theme/{publish → skinstore}/theme_publish_utils.js +0 -0
  21. /package/build/{cli/ui → ui}/validation_errors/validation_errors_utils.js +0 -0
@@ -78,7 +78,7 @@ export class ThemeDeleteCommand extends BaseThemeCommand {
78
78
  return;
79
79
  }
80
80
  const themeDeleteApi = this.getApi(THEME_DELETE_API_NAME);
81
- const { isSuccess } = await themeDeleteApi.deleteTheme({
81
+ const resp = await themeDeleteApi.deleteTheme({
82
82
  actionData: deleteAction.data,
83
83
  credentials
84
84
  });
@@ -86,7 +86,7 @@ export class ThemeDeleteCommand extends BaseThemeCommand {
86
86
  themeId: _themeId,
87
87
  credentials
88
88
  });
89
- if (!isSuccess)
89
+ if (!resp?.isSuccess)
90
90
  return;
91
91
  renderOnce(React.createElement(ThemeDeletedSuccessfully, null));
92
92
  return;
@@ -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 '../../../cli/ui/validation_errors/validation_errors.js';
17
+ import { ValidationErrors } from '../../../ui/validation_errors/validation_errors.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.';
@@ -17,8 +17,8 @@ export class ThemeListCommandUtils {
17
17
  width: 10
18
18
  }
19
19
  ],
20
- rows: themes.map((theme, index) => [
21
- React.createElement(Text, null, index),
20
+ rows: themes.map((theme) => [
21
+ React.createElement(Text, null, theme.skinId),
22
22
  React.createElement(Text, null, theme.title),
23
23
  React.createElement(Text, null, theme.isActive ? 'active' : 'inactive')
24
24
  ])
@@ -24,7 +24,7 @@ import { ThemeWorkUrlMismatch } from '../ui/theme_work_url_mismatch.js';
24
24
  import { THEME_WORK_URL_MISMATCH_ERROR } from '../../features/theme/utils/meta_data/theme_meta_data_constants.js';
25
25
  import { ThemeFilesStructureUtils } from '../../features/theme/utils/files_structure/theme_files_structure_utils.js';
26
26
  import { ThemeInfoUtils } from '../../features/theme/info/theme_info_utils.js';
27
- import { ValidationErrors } from '../../../cli/ui/validation_errors/validation_errors.js';
27
+ import { ValidationErrors } from '../../../ui/validation_errors/validation_errors.js';
28
28
  import { ThemeChecksums } from '../../class/checksums/theme_checksums.js';
29
29
  export class ThemePushCommand extends BaseThemeCommand {
30
30
  static summary = 'Uploads your local theme files to the store and overwrites the current version of the theme in your store.';
@@ -118,8 +118,9 @@ export class ThemePushCommand extends BaseThemeCommand {
118
118
  return;
119
119
  }
120
120
  if (err?.code === THEME_FILES_UPLOAD_ERROR) {
121
- return renderOnce(React.createElement(Error, { header: "Uploading theme files to the shop failed.\n" },
121
+ renderOnce(React.createElement(Error, { header: "Uploading theme files to the shop failed.\n" },
122
122
  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.")));
123
+ return;
123
124
  }
124
125
  if (err?.message) {
125
126
  renderOnce(React.createElement(ValidationErrors, { errors: err.message }));
@@ -1,5 +1,6 @@
1
1
  import { HttpErrorsFactory } from '../../../../../cli/class/errors/http/http_errors_factory.js';
2
2
  import { DownloadFileErrorsFactory } from '../../../../../utils/download_file/download_file_errors_factory.js';
3
+ import { STATUS_CODES } from '@dreamcommerce/star_core';
3
4
  export class ThemeDeleteService {
4
5
  #httpApi;
5
6
  constructor(httpApi) {
@@ -7,9 +8,11 @@ export class ThemeDeleteService {
7
8
  }
8
9
  async deleteTheme({ actionData, credentials }) {
9
10
  try {
10
- const { response } = this.#httpApi.deleteTheme({ actionData, shopUrl: credentials.shopUrl });
11
- const { data } = await response;
12
- return data;
11
+ const { response: request } = this.#httpApi.deleteTheme({ actionData, shopUrl: credentials.shopUrl });
12
+ const response = await request;
13
+ if (response?.status !== STATUS_CODES.ok)
14
+ return;
15
+ return response?.data;
13
16
  }
14
17
  catch (err) {
15
18
  //TODO to basic class
@@ -11,7 +11,7 @@ import { THEME_FILES_LIST_FILE_NAME, THEME_MODULE_SETTINGS_FILE_NAME } from '../
11
11
  import { THEME_PUSH_WILDCARD_GLOBS_FOR_FILES } from './theme_push_service_constants.js';
12
12
  import { ThemePushErrorsFactory } from '../theme_push_errors_factory.js';
13
13
  import { ThemeImagesUtils } from '../../utils/theme_images_utils.js';
14
- import { ThemePublishUtils } from '../../publish/theme_publish_utils.js';
14
+ import { ThemePublishUtils } from '../../skinstore/theme_publish_utils.js';
15
15
  import { formatJSONFile, removeFile, writeJSONFile } from '../../../../../utils/fs/fs_utils.js';
16
16
  import { MODULES_DIRECTORY_NAME } from '../../theme_constants.js';
17
17
  import path from 'node:path';
@@ -100,6 +100,7 @@ export class ThemePushService {
100
100
  .filter((path) => extname(path).toLowerCase() === '.json')
101
101
  .map((jsonFile) => formatJSONFile(join(themeRootDir, jsonFile))));
102
102
  }
103
+ //TODO osobna klasa do uploadu
103
104
  async _uploadThemeFiles({ filesToUpload, themeRootDir, localFiles, credentials }) {
104
105
  try {
105
106
  const { uploadedImageData, rejectedImageData } = await this._uploadFiles(filesToUpload, credentials);
@@ -0,0 +1,17 @@
1
+ import { FeatureApi } from '@dreamcommerce/star_core';
2
+ export class ThemeSkinstoreApi extends FeatureApi {
3
+ #service;
4
+ constructor(service) {
5
+ super();
6
+ this.#service = service;
7
+ }
8
+ async getPublishFormData() {
9
+ return this.#service.getPublishFormData();
10
+ }
11
+ async publish(themeId) {
12
+ // return this.#service.publish(themeId);
13
+ }
14
+ async update() {
15
+ // return this.#service.update();
16
+ }
17
+ }
@@ -0,0 +1,7 @@
1
+ export class ThemeSkinstoreHttpApi {
2
+ #httpApi;
3
+ constructor(httpApi) {
4
+ this.#httpApi = httpApi;
5
+ }
6
+ async getPublishFormData() { }
7
+ }
@@ -0,0 +1,3 @@
1
+ export class ThemeSkinstoreService {
2
+ async getPublishFormData() { }
3
+ }
@@ -9,18 +9,17 @@ export class ThemesListService {
9
9
  }
10
10
  async getThemes({ shopUrl }) {
11
11
  try {
12
- const { response } = this.#httpApi.getThemes(shopUrl);
13
- const { data, status } = await response;
14
- if (status !== STATUS_CODES.ok)
12
+ const { response: request } = this.#httpApi.getThemes(shopUrl);
13
+ const response = await request;
14
+ if (response?.status !== STATUS_CODES.ok)
15
15
  return;
16
16
  //TODO baseHttpApi + model mapper
17
- return data.map(({ _links, ...rest }) => new ThemeMetaData({
17
+ return response?.data.map(({ _links, ...rest }) => new ThemeMetaData({
18
18
  ...rest,
19
19
  links: _links
20
20
  }));
21
21
  }
22
22
  catch (err) {
23
- //TODO to basic class
24
23
  switch (err.response?.status) {
25
24
  case 403:
26
25
  throw HttpErrorsFactory.createForbiddenError();
@@ -3,5 +3,6 @@ export const THEME_COMMANDS_THAT_REQUIRED_ACTIONS_LIST = [
3
3
  THEME_COMMANDS_NAME.pull,
4
4
  THEME_COMMANDS_NAME.init,
5
5
  THEME_COMMANDS_NAME.push,
6
+ THEME_COMMANDS_NAME.delete,
6
7
  THEME_COMMANDS_NAME.showChanges
7
8
  ];
@@ -0,0 +1,39 @@
1
+ export const toTextControl = ({ type, validate, label, isRequired, defaultValue, name }) => {
2
+ return {
3
+ type: 'input',
4
+ name,
5
+ message: isRequired ? `${label} (required)` : label,
6
+ default: defaultValue,
7
+ validate
8
+ };
9
+ };
10
+ export const toNumberControl = ({ type, validate, label, isRequired, defaultValue, name }) => {
11
+ return {
12
+ type: 'number',
13
+ name,
14
+ message: isRequired ? `${label} (required)` : label,
15
+ default: defaultValue,
16
+ validate
17
+ };
18
+ };
19
+ export const toSelectControl = ({ type, validate, label, isRequired, defaultValue, name, choices }) => {
20
+ return {
21
+ type: 'list',
22
+ name,
23
+ message: isRequired ? `${label} (required)` : label,
24
+ choices,
25
+ default: defaultValue,
26
+ validate
27
+ };
28
+ };
29
+ export const toMultiSelectControl = ({ type, validate, label, isRequired, defaultValue, name, choices }) => {
30
+ //TODO multiple checkboxes
31
+ return {
32
+ type: 'checkbox',
33
+ name,
34
+ message: isRequired ? `${label} (required)` : label,
35
+ choices,
36
+ default: defaultValue,
37
+ validate
38
+ };
39
+ };
@@ -0,0 +1,5 @@
1
+ import inquirer from 'inquirer';
2
+ import { CONTROL_TYPE_TO_MAPPERS } from './form_constants.js';
3
+ export const Form = ({ controls, onSubmit }) => {
4
+ inquirer.prompt(controls.map((control) => CONTROL_TYPE_TO_MAPPERS[control.type]?.(control))).then(onSubmit);
5
+ };
@@ -0,0 +1,13 @@
1
+ import { toMultiSelectControl, toNumberControl, toSelectControl, toTextControl } from './controls_mappers.js';
2
+ export const CONTROLS_TYPES = {
3
+ text: 'text',
4
+ number: 'number',
5
+ select: 'select',
6
+ multiSelect: 'multiSelect'
7
+ };
8
+ export const CONTROL_TYPE_TO_MAPPERS = {
9
+ [CONTROLS_TYPES.text]: toTextControl,
10
+ [CONTROLS_TYPES.number]: toNumberControl,
11
+ [CONTROLS_TYPES.select]: toSelectControl,
12
+ [CONTROLS_TYPES.multiSelect]: toMultiSelectControl
13
+ };
@@ -1,5 +1,5 @@
1
- import { Text } from '../../../ui/text.js';
2
- import { List } from '../../../ui/list/list.js';
1
+ import { Text } from '../text.js';
2
+ import { List } from '../list/list.js';
3
3
  import { ValidationErrorsUtils } from './validation_errors_utils.js';
4
4
  import React from 'react';
5
5
  export const ValidationErrorContent = ({ errors }) => {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { Error } from '../../../ui/message_box/error.js';
3
- import { Text } from '../../../ui/text.js';
4
- import { List } from '../../../ui/list/list.js';
2
+ import { Error } from '../message_box/error.js';
3
+ import { Text } from '../text.js';
4
+ import { List } from '../list/list.js';
5
5
  import { ValidationErrorContent } from './validation_error_content.js';
6
6
  export const ValidationErrors = ({ errors }) => {
7
7
  if (typeof errors === 'string') {
@@ -8,6 +8,8 @@ import { DownloadFileErrorsFactory } from './download_file_errors_factory.js';
8
8
  export const downloadFile = async ({ dist, request }) => {
9
9
  try {
10
10
  const resp = (await request);
11
+ if (!resp)
12
+ throw resp;
11
13
  const headers = resp.headers;
12
14
  const url = new URL(resp.config.url);
13
15
  const filename = getFileNameFromHeaders(headers) ?? basename(url.pathname);
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-30",
5
+ "version": "0.1.0-32",
6
6
  "description": "CLI tool for Shoper",
7
7
  "author": "Joanna Firek",
8
8
  "license": "MIT",
@@ -63,7 +63,8 @@
63
63
  "ink-link": "4.1.0",
64
64
  "log-symbols": "7.0.1",
65
65
  "figures": "6.1.0",
66
- "strip-ansi": "7.1.0"
66
+ "strip-ansi": "7.1.0",
67
+ "inquirer-select-line": "1.1.3"
67
68
  },
68
69
  "devDependencies": {
69
70
  "@babel/core": "7.27.1",