@shoper/cli 0.1.0-32 → 0.1.0-33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cli/auth/tokens/cli_auth_tokens_initalizer.js +1 -1
- package/build/cli/features/controls/controls_dto_to_ui_mappers.js +39 -0
- package/build/cli/features/controls/ui/controls_mappers.js +44 -0
- package/build/cli/features/controls/validators/greater_eq_than_validator.js +5 -0
- package/build/cli/features/controls/validators/length_validator.js +6 -0
- package/build/cli/features/controls/validators/required_validator.js +5 -0
- package/build/cli/features/controls/validators/validator_constants.js +13 -0
- package/build/cli/features/http_requester/http_requester_initializer.js +1 -1
- package/build/theme/class/fetch_resources/fetch_resources.js +1 -0
- package/build/theme/class/fetch_resources/fetch_resources_utils.js +4 -1
- package/build/theme/features/theme/actions/theme_actions_initializer.js +1 -1
- package/build/theme/features/theme/actions/theme_actions_utils.js +18 -8
- package/build/theme/features/theme/fetch/service/theme_fetch_service.js +3 -2
- package/build/theme/features/theme/push/service/theme_push_service.js +15 -4
- package/build/theme/features/theme/skinstore/api/theme_skinstore_api.js +1 -1
- package/build/theme/features/theme/skinstore/http/theme_skinstore_http_api.js +11 -1
- package/build/theme/features/theme/skinstore/service/theme_skinstore_service.js +29 -1
- package/build/theme/features/theme/utils/theme_images_utils.js +1 -1
- package/package.json +1 -1
- package/build/ui/form/controls_mappers.js +0 -39
- /package/build/cli/{features → class}/caches/cache_factory.js +0 -0
- /package/build/cli/{features → class}/caches/json_cache/json_cache.js +0 -0
- /package/build/cli/{features → class}/caches/memory_cache.js +0 -0
- /package/build/{ui/form → cli/features/controls/ui}/form.js +0 -0
- /package/build/{ui/form → cli/features/controls/ui}/form_constants.js +0 -0
|
@@ -3,7 +3,7 @@ import { CliAuthTokensApi } from './api/cli_auth_tokens_api.js';
|
|
|
3
3
|
import { CLiAuthTokensService } from './service/cli_auth_tokens_service.js';
|
|
4
4
|
import { CLI_AUTH_TOKENS_FEATURE_NAME, CLI_AUTH_TOKENS_FILE_NAME } from './cli_auth_tokens_constants.js';
|
|
5
5
|
import { CLI_DATA_DIRECTORY_API_NAME } from '../../features/data_directory/cli_data_directory_constants.js';
|
|
6
|
-
import { JsonCache } from '../../
|
|
6
|
+
import { JsonCache } from '../../class/caches/json_cache/json_cache.js';
|
|
7
7
|
// schema
|
|
8
8
|
// {
|
|
9
9
|
// default: string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CONTROLS_TYPES } from './ui/form_constants.js';
|
|
2
|
+
export const toTextControl = ({ validators, label, isRequired, defaultValue, name }) => {
|
|
3
|
+
return {
|
|
4
|
+
type: CONTROLS_TYPES.text,
|
|
5
|
+
name,
|
|
6
|
+
label,
|
|
7
|
+
isRequired,
|
|
8
|
+
defaultValue,
|
|
9
|
+
validators
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export const toNumberControl = ({ validators, label, isRequired, name }) => {
|
|
13
|
+
return {
|
|
14
|
+
type: 'number',
|
|
15
|
+
name,
|
|
16
|
+
label,
|
|
17
|
+
isRequired,
|
|
18
|
+
validators
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export const toSelectControl = ({ label, isRequired, name, options }) => {
|
|
22
|
+
return {
|
|
23
|
+
type: 'list',
|
|
24
|
+
name,
|
|
25
|
+
label,
|
|
26
|
+
isRequired,
|
|
27
|
+
options: options.selectOptions.map(({ label, key }) => ({ label, value: key }))
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export const toMultiSelectControl = ({ label, isRequired, name, options }) => {
|
|
31
|
+
//TODO multiple checkboxes
|
|
32
|
+
return {
|
|
33
|
+
type: 'checkbox',
|
|
34
|
+
name,
|
|
35
|
+
label,
|
|
36
|
+
isRequired,
|
|
37
|
+
options: options.selectOptions.map(({ label, key }) => ({ label, value: key }))
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const toTextControl = ({ validators, label, isRequired, defaultValue, name }) => {
|
|
2
|
+
return {
|
|
3
|
+
type: 'input',
|
|
4
|
+
name,
|
|
5
|
+
message: isRequired ? `${label} (required)` : label,
|
|
6
|
+
default: defaultValue,
|
|
7
|
+
validate: toInquirerValidate(validators)
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export const toNumberControl = ({ validators, label, isRequired, defaultValue, name }) => {
|
|
11
|
+
return {
|
|
12
|
+
type: 'number',
|
|
13
|
+
name,
|
|
14
|
+
message: isRequired ? `${label} (required)` : label,
|
|
15
|
+
default: defaultValue,
|
|
16
|
+
validate: toInquirerValidate(validators)
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export const toSelectControl = ({ validators, label, isRequired, defaultValue, name, options }) => {
|
|
20
|
+
return {
|
|
21
|
+
type: 'list',
|
|
22
|
+
name,
|
|
23
|
+
message: isRequired ? `${label} (required)` : label,
|
|
24
|
+
choices: options,
|
|
25
|
+
default: defaultValue,
|
|
26
|
+
validate: toInquirerValidate(validators)
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export const toMultiSelectControl = ({ validators, label, isRequired, defaultValue, name, options }) => {
|
|
30
|
+
//TODO multiple checkboxes
|
|
31
|
+
return {
|
|
32
|
+
type: 'checkbox',
|
|
33
|
+
name,
|
|
34
|
+
message: isRequired ? `${label} (required)` : label,
|
|
35
|
+
choices: options,
|
|
36
|
+
default: defaultValue,
|
|
37
|
+
validate: toInquirerValidate(validators)
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export const toInquirerValidate = (validators) => {
|
|
41
|
+
return (value) => {
|
|
42
|
+
return validators?.find((v) => !v.isValid(value))?.getErrorMessage() ?? true;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RequiredValidator } from './required_validator.js';
|
|
2
|
+
import { GreaterEqThanValidator } from './greater_eq_than_validator.js';
|
|
3
|
+
import { LengthValidator } from './length_validator.js';
|
|
4
|
+
export const VALIDATORS_TYPES = {
|
|
5
|
+
required: 'required',
|
|
6
|
+
greaterEqThan: 'greaterEqThan',
|
|
7
|
+
length: 'length'
|
|
8
|
+
};
|
|
9
|
+
export const VALIDATOR_TYPE_TO_VALIDATOR = {
|
|
10
|
+
[VALIDATORS_TYPES.required]: new RequiredValidator(),
|
|
11
|
+
[VALIDATORS_TYPES.greaterEqThan]: new GreaterEqThanValidator(),
|
|
12
|
+
[VALIDATORS_TYPES.length]: new LengthValidator()
|
|
13
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CACHE_TYPES, CacheService, DEFAULT_REQUESTER_CACHE_NAMESPACE, FEATURE_CORES_TYPES, HTTP_REQUESTER_FEATURE_NAME, HTTPRequesterApi, HTTPRequesterBalancer, REQUEST_SOURCE, Requester, RequesterCacheServiceKeySerializer, SANITIZER_API_NAME, StrategiesContainer, SyncFeatureInitializer } from '@dreamcommerce/star_core';
|
|
2
2
|
import { HttpClient } from './http_client.js';
|
|
3
|
-
import { CacheFactory } from '
|
|
3
|
+
import { CacheFactory } from '../../class/caches/cache_factory.js';
|
|
4
4
|
export class HTTPRequesterInitializer extends SyncFeatureInitializer {
|
|
5
5
|
static featureName = HTTP_REQUESTER_FEATURE_NAME;
|
|
6
6
|
init() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from '../../../utils/path_utils.js';
|
|
2
2
|
import { RESOURCES_FILE_NAME } from './fetch_resources_constants.js';
|
|
3
3
|
import { SHOPER_THEME_METADATA_DIR } from '../../constants/directory_contstants.js';
|
|
4
|
-
import { fileExists, readJSONFile } from '../../../utils/fs/fs_utils.js';
|
|
4
|
+
import { fileExists, readJSONFile, removeFiles } from '../../../utils/fs/fs_utils.js';
|
|
5
5
|
export const isResourceObject = (resource) => {
|
|
6
6
|
return typeof resource === 'object' && resource !== null && 'url' in resource && typeof resource.url === 'string';
|
|
7
7
|
};
|
|
@@ -15,6 +15,9 @@ export const getResources = async (root) => {
|
|
|
15
15
|
}
|
|
16
16
|
return await readJSONFile(resourcesPath);
|
|
17
17
|
};
|
|
18
|
+
export const removeOldResources = async (rootDir, resources) => {
|
|
19
|
+
await removeFiles(Object.keys(resources).map((path) => join(rootDir, path)));
|
|
20
|
+
};
|
|
18
21
|
export const mapResourcesToTree = (resources, separator = '/') => {
|
|
19
22
|
const tree = {};
|
|
20
23
|
Object.entries(resources).forEach(([path, value]) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncFeatureInitializer, FEATURE_CORES_TYPES } from '@dreamcommerce/star_core';
|
|
2
2
|
import { THEMES_LIST_API_NAME } from '../../themes/list/themes_list_constants.js';
|
|
3
|
-
import { JsonCache } from '../../../../cli/
|
|
3
|
+
import { JsonCache } from '../../../../cli/class/caches/json_cache/json_cache.js';
|
|
4
4
|
import { CLI_DATA_DIRECTORY_API_NAME } from '../../../../cli/features/data_directory/cli_data_directory_constants.js';
|
|
5
5
|
import { THEME_ACTIONS_FEATURE_NAME, THEMES_ACTIONS_FILE_NAME } from './theme_actions_constants.js';
|
|
6
6
|
import { ThemeActionsApi } from './api/theme_actions_api.js';
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { THEME_ALL_ACTIONS_NAME } from './service/theme_actions_service_constants.js';
|
|
2
2
|
import { toUnixPath } from '../../../../utils/path_utils.js';
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
(fileStructureItem._links[actionType]
|
|
7
|
-
|
|
3
|
+
export class ThemeActionsUtils {
|
|
4
|
+
static getFilesGlobsThatMatchesActionName({ filesStructure, actionValue, actionType }) {
|
|
5
|
+
return Object.entries(filesStructure).reduce((acc, [filePath, fileStructureItem]) => {
|
|
6
|
+
if (fileStructureItem._links?.[actionType] && this._doesActionValueMatch(fileStructureItem._links[actionType], actionValue)) {
|
|
7
|
+
return [...acc, toUnixPath(filePath)];
|
|
8
|
+
}
|
|
9
|
+
return acc;
|
|
10
|
+
}, []);
|
|
11
|
+
}
|
|
12
|
+
static _doesActionValueMatch(currentActionValue, valuesToMatch) {
|
|
13
|
+
if (typeof valuesToMatch === 'string') {
|
|
14
|
+
return currentActionValue === valuesToMatch || valuesToMatch === THEME_ALL_ACTIONS_NAME;
|
|
8
15
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
16
|
+
if (Array.isArray(valuesToMatch)) {
|
|
17
|
+
return valuesToMatch.includes(currentActionValue) || valuesToMatch.includes(THEME_ALL_ACTIONS_NAME);
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -4,7 +4,7 @@ import { downloadFile } from '../../../../../utils/download_file/download_file_u
|
|
|
4
4
|
import { extractZip } from '../../../../../utils/zip/extract_zip_utils.js';
|
|
5
5
|
import { join } from '../../../../../utils/path_utils.js';
|
|
6
6
|
import { SHOPER_THEME_METADATA_DIR } from '../../../../constants/directory_contstants.js';
|
|
7
|
-
import { getResources, mapResourcesToTree } from '../../../../class/fetch_resources/fetch_resources_utils.js';
|
|
7
|
+
import { getResources, mapResourcesToTree, removeOldResources } from '../../../../class/fetch_resources/fetch_resources_utils.js';
|
|
8
8
|
import { FetchResources } from '../../../../class/fetch_resources/fetch_resources.js';
|
|
9
9
|
import { jsonIndentTransform } from '../../../../../utils/stream_transforms/json_indent_transform.js';
|
|
10
10
|
import { THEME_CURRENT_CHECKSUMS_FILE_NAME, THEME_CURRENT_CHECKSUMS_VERITY_FILE_NAME, THEME_INITIAL_CHECKSUMS_FILE_NAME, THEME_INITIAL_CHECKSUMS_VERITY_FILE_NAME } from '../../theme_constants.js';
|
|
@@ -15,7 +15,7 @@ import { AppError } from '../../../../../cli/class/errors/app/app_error.js';
|
|
|
15
15
|
import { THEME_ACTIONS_TYPES } from '../../actions/theme_actions_constants.js';
|
|
16
16
|
import { ThemeFilesStructureUtils } from '../../utils/files_structure/theme_files_structure_utils.js';
|
|
17
17
|
import { ThemeMetaDataUtils } from '../../utils/meta_data/theme_meta_data_utils.js';
|
|
18
|
-
import { ThemeChecksums } from '
|
|
18
|
+
import { ThemeChecksums } from '../../../../class/checksums/theme_checksums.js';
|
|
19
19
|
export class ThemeFetchService {
|
|
20
20
|
#themeHttpApi;
|
|
21
21
|
#httpApi;
|
|
@@ -107,6 +107,7 @@ export class ThemeFetchService {
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
async fetchResources(shopUrl, dist, resources) {
|
|
110
|
+
await removeOldResources(dist, resources);
|
|
110
111
|
const resourcesTree = mapResourcesToTree(resources);
|
|
111
112
|
await Promise.all(Object.keys(resourcesTree).map((resource) => new FetchResources(this.#httpApi).fetchResources({
|
|
112
113
|
resourcesPart: resourcesTree[resource],
|
|
@@ -6,7 +6,7 @@ import { createReadStream } from 'node:fs';
|
|
|
6
6
|
import { v4 as uuid } from 'uuid';
|
|
7
7
|
import globs from 'fast-glob';
|
|
8
8
|
import { THEME_WILDCARD_ACTION_NAME } from '../../actions/service/theme_actions_service_constants.js';
|
|
9
|
-
import {
|
|
9
|
+
import { ThemeActionsUtils } from '../../actions/theme_actions_utils.js';
|
|
10
10
|
import { THEME_FILES_LIST_FILE_NAME, THEME_MODULE_SETTINGS_FILE_NAME } from '../theme_push_constants.js';
|
|
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';
|
|
@@ -15,6 +15,7 @@ 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';
|
|
18
|
+
import { removeOldResources } from '../../../../class/fetch_resources/fetch_resources_utils.js';
|
|
18
19
|
export class ThemePushService {
|
|
19
20
|
#themePushHttpApi;
|
|
20
21
|
#themeFetchApi;
|
|
@@ -47,7 +48,11 @@ export class ThemePushService {
|
|
|
47
48
|
try {
|
|
48
49
|
await this._createThemeArchive({
|
|
49
50
|
themeRootDir: executionContext.themeRootDir,
|
|
50
|
-
filesToArchive: getFilesGlobsThatMatchesActionName(
|
|
51
|
+
filesToArchive: ThemeActionsUtils.getFilesGlobsThatMatchesActionName({
|
|
52
|
+
actionType: THEME_ACTIONS_TYPES.push,
|
|
53
|
+
actionValue: THEME_WILDCARD_ACTION_NAME,
|
|
54
|
+
filesStructure
|
|
55
|
+
}),
|
|
51
56
|
dist: themeArchivePath
|
|
52
57
|
});
|
|
53
58
|
}
|
|
@@ -61,8 +66,10 @@ export class ThemePushService {
|
|
|
61
66
|
});
|
|
62
67
|
if (modules)
|
|
63
68
|
await this._updateDataForNewCreatedModules({ modules, themeRootDir: executionContext.themeRootDir });
|
|
64
|
-
if (resources)
|
|
69
|
+
if (resources) {
|
|
70
|
+
await removeOldResources(executionContext.themeRootDir, resources);
|
|
65
71
|
await this.#themeFetchApi.fetchResources(credentials.shopUrl, executionContext.themeRootDir, resources);
|
|
72
|
+
}
|
|
66
73
|
await removeFile(join(executionContext.themeRootDir, THEME_FILES_LIST_FILE_NAME));
|
|
67
74
|
await themeChecksums.updateAllChecksums();
|
|
68
75
|
}
|
|
@@ -150,7 +157,11 @@ export class ThemePushService {
|
|
|
150
157
|
const localFiles = {};
|
|
151
158
|
for (const [actionKey, actionData] of Object.entries(pushAction.data)) {
|
|
152
159
|
if (actionData.type === THEME_ACTION_DATA_TYPE.file) {
|
|
153
|
-
const filesGlobs = getFilesGlobsThatMatchesActionName(
|
|
160
|
+
const filesGlobs = ThemeActionsUtils.getFilesGlobsThatMatchesActionName({
|
|
161
|
+
actionType: THEME_ACTIONS_TYPES.push,
|
|
162
|
+
actionValue: actionKey,
|
|
163
|
+
filesStructure
|
|
164
|
+
});
|
|
154
165
|
for (const fileGlob of filesGlobs) {
|
|
155
166
|
const files = await globs(fileGlob, {
|
|
156
167
|
suppressErrors: true,
|
|
@@ -6,7 +6,7 @@ export class ThemeSkinstoreApi extends FeatureApi {
|
|
|
6
6
|
this.#service = service;
|
|
7
7
|
}
|
|
8
8
|
async getPublishFormData() {
|
|
9
|
-
return this.#service.getPublishFormData();
|
|
9
|
+
// return this.#service.getPublishFormData();
|
|
10
10
|
}
|
|
11
11
|
async publish(themeId) {
|
|
12
12
|
// return this.#service.publish(themeId);
|
|
@@ -3,5 +3,15 @@ export class ThemeSkinstoreHttpApi {
|
|
|
3
3
|
constructor(httpApi) {
|
|
4
4
|
this.#httpApi = httpApi;
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
getPublishFormData({ actionData, shopUrl }) {
|
|
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
|
+
}
|
|
7
17
|
}
|
|
@@ -1,3 +1,31 @@
|
|
|
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';
|
|
1
4
|
export class ThemeSkinstoreService {
|
|
2
|
-
|
|
5
|
+
#httpApi;
|
|
6
|
+
constructor(httpApi) {
|
|
7
|
+
this.#httpApi = httpApi;
|
|
8
|
+
}
|
|
9
|
+
async getPublishFormData({ credentials, actionData }) {
|
|
10
|
+
try {
|
|
11
|
+
const { response: request } = this.#httpApi.getPublishFormData({ actionData, shopUrl: credentials.shopUrl });
|
|
12
|
+
const response = await request;
|
|
13
|
+
if (response?.status !== STATUS_CODES.ok)
|
|
14
|
+
return;
|
|
15
|
+
return response?.data;
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
//TODO to basic class
|
|
19
|
+
switch (err.response?.status) {
|
|
20
|
+
case 403:
|
|
21
|
+
throw HttpErrorsFactory.createForbiddenError();
|
|
22
|
+
case 401:
|
|
23
|
+
throw HttpErrorsFactory.createUnauthorizedError();
|
|
24
|
+
case 404:
|
|
25
|
+
throw HttpErrorsFactory.createNotFoundError();
|
|
26
|
+
default:
|
|
27
|
+
throw DownloadFileErrorsFactory.downloadError(err.response.status);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
3
31
|
}
|
|
@@ -21,7 +21,7 @@ export class ThemeImagesUtils {
|
|
|
21
21
|
}
|
|
22
22
|
static async removeUploadedOriginalFiles(themeRootDir, uploadedImagesData) {
|
|
23
23
|
await Promise.all(uploadedImagesData
|
|
24
|
-
.filter(({ originalFilename }) => Boolean(originalFilename))
|
|
24
|
+
.filter(({ originalFilename, uploadedFilename }) => Boolean(originalFilename) && Boolean(uploadedFilename))
|
|
25
25
|
.map(({ originalFilename, location }) => {
|
|
26
26
|
const originalFilePath = join(themeRootDir, location, originalFilename);
|
|
27
27
|
return removeFile(originalFilePath);
|
package/package.json
CHANGED
|
@@ -1,39 +0,0 @@
|
|
|
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
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|