@shoper/cli 0.1.0-8 → 0.1.0-9
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/theme/class/fetch_resources/fetch_resources.js +4 -3
- package/build/theme/commands/theme_pull_command.js +2 -0
- package/build/theme/features/theme/push/service/theme_push_service.js +14 -8
- package/build/theme/features/theme/utils/theme_images_utils.js +4 -5
- package/build/theme/utils/directory_validator/directory_validator_utils.js +11 -13
- package/build/utils/fs/fs_utils.js +5 -2
- package/build/utils/path_utils.js +3 -0
- package/package.json +4 -2
|
@@ -4,10 +4,11 @@ import { extractZip } from '../../../utils/zip/extract_zip_utils.js';
|
|
|
4
4
|
import { join } from '../../../utils/path_utils.js';
|
|
5
5
|
import tmp from 'tmp-promise';
|
|
6
6
|
import { copyFile, fileExists, readJSONFile } from '../../../utils/fs/fs_utils.js';
|
|
7
|
-
import { getResourcesPath, isResourceObject } from './fetch_resources_utils.js';
|
|
7
|
+
import { getResourcesPath, isResourceObject, mapResourcesToTree } from './fetch_resources_utils.js';
|
|
8
8
|
import { MAX_REQUEST_FOR_RESOURCES } from './fetch_resources_constants.js';
|
|
9
9
|
import { isRelativeUrl } from '../../../utils/url_utils.js';
|
|
10
10
|
import { FetchResourcesErrorsFactory } from './fetch_resources_errors_factory.js';
|
|
11
|
+
import { move } from 'fs-extra';
|
|
11
12
|
export class FetchResources {
|
|
12
13
|
#urlsAttempts = {};
|
|
13
14
|
#httpApi;
|
|
@@ -59,7 +60,7 @@ export class FetchResources {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
async _getResourcesFileContent(resourcePath) {
|
|
62
|
-
return await readJSONFile(resourcePath);
|
|
63
|
+
return mapResourcesToTree(await readJSONFile(resourcePath));
|
|
63
64
|
}
|
|
64
65
|
_getResourcesPart(resources, parts) {
|
|
65
66
|
return parts.reduce((acc, part) => acc[part] ?? {}, resources);
|
|
@@ -96,7 +97,7 @@ export class FetchResources {
|
|
|
96
97
|
});
|
|
97
98
|
}
|
|
98
99
|
else {
|
|
99
|
-
await
|
|
100
|
+
await move(join(tmpDir, filename), join(dist, this._getFilepathFromParts(parts), filename), { overwrite: true });
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
catch (err) {
|
|
@@ -89,6 +89,8 @@ export class ThemePullCommand extends BaseThemeCommand {
|
|
|
89
89
|
});
|
|
90
90
|
this.log('\n');
|
|
91
91
|
const changes = await themeMergeApi.getChangesBetweenThemes(join(tmpDir, name), executionContext.themeRootDir);
|
|
92
|
+
console.log('changes', changes);
|
|
93
|
+
console.log('is modified', await themeMergeApi.hasThemeBeenModified(executionContext.themeRootDir));
|
|
92
94
|
if (await themeMergeApi.hasThemeBeenModified(executionContext.themeRootDir)) {
|
|
93
95
|
console.log('changes', changes);
|
|
94
96
|
this.log('You have unpublished changes in your theme...\n');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import tmp from 'tmp-promise';
|
|
2
2
|
import { THEME_ACTION_DATA_TYPE, THEME_ACTIONS_TYPES } from '../../actions/theme_actions_constants.js';
|
|
3
3
|
import { createZip } from '../../../../../utils/zip/create_zip_utils.js';
|
|
4
|
-
import { basename, dirname, extname, join, looksLikeDirectory } from '../../../../../utils/path_utils.js';
|
|
4
|
+
import { basename, dirname, extname, join, looksLikeDirectory, toUnixPath } from '../../../../../utils/path_utils.js';
|
|
5
5
|
import { createReadStream } from 'node:fs';
|
|
6
6
|
import { v4 as uuid } from 'uuid';
|
|
7
7
|
import globs from 'fast-glob';
|
|
@@ -34,7 +34,6 @@ export class ThemePushService {
|
|
|
34
34
|
filesStructure,
|
|
35
35
|
executionContext
|
|
36
36
|
});
|
|
37
|
-
console.log('uploadData', uploadData);
|
|
38
37
|
if (uploadData.length) {
|
|
39
38
|
await this._uploadThemeFiles({
|
|
40
39
|
filesToUpload: uploadData,
|
|
@@ -68,7 +67,7 @@ export class ThemePushService {
|
|
|
68
67
|
});
|
|
69
68
|
if (modules)
|
|
70
69
|
await this._updateDataForNewCreatedModules({ modules, themeRootDir: executionContext.themeRootDir });
|
|
71
|
-
console.log(
|
|
70
|
+
console.log(JSON.stringify(resources));
|
|
72
71
|
if (resources)
|
|
73
72
|
await this.#themeFetchApi.fetchResources(credentials.shopUrl, executionContext.themeRootDir, resources);
|
|
74
73
|
await removeFile(join(executionContext.themeRootDir, THEME_FILES_LIST_FILE_NAME));
|
|
@@ -115,7 +114,7 @@ export class ThemePushService {
|
|
|
115
114
|
const uploadedImageData = await this._uploadFiles(filesToUpload, credentials);
|
|
116
115
|
const newFilesList = ThemeImagesUtils.updateOriginalFilenameToUploadedFilename(localFiles, uploadedImageData);
|
|
117
116
|
if (uploadedImageData.length)
|
|
118
|
-
await ThemeImagesUtils.
|
|
117
|
+
await ThemeImagesUtils.removeUploadedOriginalFiles(themeRootDir, uploadedImageData);
|
|
119
118
|
await this._createAFilesListFile(themeRootDir, newFilesList);
|
|
120
119
|
}
|
|
121
120
|
catch (err) {
|
|
@@ -186,9 +185,16 @@ export class ThemePushService {
|
|
|
186
185
|
}
|
|
187
186
|
}
|
|
188
187
|
async _createAFilesListFile(themeRootDir, filesList) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
188
|
+
if (!filesList || !Object.keys(filesList).length)
|
|
189
|
+
return;
|
|
190
|
+
const toUnixStyleFilesList = Object.entries(filesList).reduce((acc, [path, value]) => {
|
|
191
|
+
const unixPath = toUnixPath(path);
|
|
192
|
+
const finalPath = looksLikeDirectory(path) ? `${unixPath}/` : unixPath;
|
|
193
|
+
return {
|
|
194
|
+
...acc,
|
|
195
|
+
[finalPath]: value
|
|
196
|
+
};
|
|
197
|
+
}, {});
|
|
198
|
+
await writeJSONFile(join(themeRootDir, THEME_FILES_LIST_FILE_NAME), toUnixStyleFilesList);
|
|
193
199
|
}
|
|
194
200
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from '../../../../utils/path_utils.js';
|
|
2
|
-
import {
|
|
2
|
+
import { removeFile } from '../../../../utils/fs/fs_utils.js';
|
|
3
3
|
export class ThemeImagesUtils {
|
|
4
4
|
static updateOriginalFilenameToUploadedFilename(filesList, uploadedImageData) {
|
|
5
5
|
const newFilesList = { ...filesList };
|
|
@@ -19,13 +19,12 @@ export class ThemeImagesUtils {
|
|
|
19
19
|
});
|
|
20
20
|
return newFilesList;
|
|
21
21
|
}
|
|
22
|
-
static async
|
|
22
|
+
static async removeUploadedOriginalFiles(themeRootDir, uploadedImagesData) {
|
|
23
23
|
await Promise.all(uploadedImagesData
|
|
24
24
|
.filter(({ originalFilename }) => Boolean(originalFilename))
|
|
25
|
-
.map(({
|
|
25
|
+
.map(({ originalFilename, location }) => {
|
|
26
26
|
const originalFilePath = join(themeRootDir, location, originalFilename);
|
|
27
|
-
|
|
28
|
-
return renameFile(originalFilePath, newFilePath);
|
|
27
|
+
return removeFile(originalFilePath);
|
|
29
28
|
}));
|
|
30
29
|
}
|
|
31
30
|
}
|
|
@@ -67,18 +67,16 @@ const _checkPermissions = async ({ permissionPart, permissionParts, parts = [],
|
|
|
67
67
|
});
|
|
68
68
|
if (action)
|
|
69
69
|
unpermittedActions.push(action);
|
|
70
|
-
if (await isDirectory(join(fullPath, file))) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
}
|
|
70
|
+
if ((await fileExists(join(rootDirectory, join(...parts, file)))) && (await isDirectory(join(fullPath, file)))) {
|
|
71
|
+
await _checkPermissions({
|
|
72
|
+
permissionPart: permission,
|
|
73
|
+
parts: [...parts, file],
|
|
74
|
+
permissionParts: permissionKey ? [...permissionParts, permissionKey] : permissionParts,
|
|
75
|
+
checksumsPart: checksumsPart?.[file] ?? {},
|
|
76
|
+
rootDirectory,
|
|
77
|
+
unpermittedActions,
|
|
78
|
+
permissions
|
|
79
|
+
});
|
|
82
80
|
}
|
|
83
81
|
}
|
|
84
82
|
return;
|
|
@@ -122,7 +120,7 @@ const _checkPermission = async ({ permission, path, checksumsPart, filesInDirect
|
|
|
122
120
|
relativePath
|
|
123
121
|
};
|
|
124
122
|
}
|
|
125
|
-
if (!looksLikeDirectory(join(rootDirectory, path)) && !permission.canEdit && checksumsPart[path]
|
|
123
|
+
if ((await fileExists(fullPath)) && !looksLikeDirectory(join(rootDirectory, path)) && !permission.canEdit && checksumsPart[path]) {
|
|
126
124
|
const currentChecksum = await computeFileChecksum(fullPath);
|
|
127
125
|
if (currentChecksum !== checksumsPart[path][CHECKSUM_KEY]) {
|
|
128
126
|
return {
|
|
@@ -9,6 +9,7 @@ import { JSON_FILE_INDENT } from '../../cli/cli_constants.js';
|
|
|
9
9
|
import tmp from 'tmp-promise';
|
|
10
10
|
import { pipeline } from 'node:stream/promises';
|
|
11
11
|
import { jsonIndentTransform } from '../stream_transforms/json_indent_transform.js';
|
|
12
|
+
import { move } from 'fs-extra';
|
|
12
13
|
export const fileExists = async (path) => {
|
|
13
14
|
try {
|
|
14
15
|
await fsPromises.access(path);
|
|
@@ -50,13 +51,15 @@ export const writeJSONFile = async (path, data) => {
|
|
|
50
51
|
}
|
|
51
52
|
};
|
|
52
53
|
export const formatJSONFile = async (path, indent = JSON_FILE_INDENT) => {
|
|
53
|
-
const { path: tmpDir } = await tmp.dir({ unsafeCleanup: true });
|
|
54
|
+
const { path: tmpDir, cleanup } = await tmp.dir({ unsafeCleanup: true });
|
|
54
55
|
const fileName = basename(path);
|
|
55
56
|
const formattedTmpFilePath = join(tmpDir, fileName);
|
|
56
57
|
const readStream = createReadStream(path);
|
|
57
58
|
const writeStream = fs.createWriteStream(formattedTmpFilePath);
|
|
58
59
|
await pipeline(readStream, jsonIndentTransform(indent), writeStream);
|
|
59
|
-
await copyFile(formattedTmpFilePath, path, { force: true });
|
|
60
|
+
// await copyFile(formattedTmpFilePath, path, { force: true });
|
|
61
|
+
await move(formattedTmpFilePath, path, { overwrite: true });
|
|
62
|
+
await cleanup();
|
|
60
63
|
};
|
|
61
64
|
export const openFile = async (path, flags, mode) => {
|
|
62
65
|
return fsPromises.open(path, flags, mode);
|
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-
|
|
5
|
+
"version": "0.1.0-9",
|
|
6
6
|
"description": "CLI tool for Shoper",
|
|
7
7
|
"author": "Joanna Firek",
|
|
8
8
|
"license": "MIT",
|
|
@@ -58,7 +58,8 @@
|
|
|
58
58
|
"klaw": "4.1.0",
|
|
59
59
|
"walk-sync": "3.0.0",
|
|
60
60
|
"lodash": "4.17.21",
|
|
61
|
-
"uuid": "11.1.0"
|
|
61
|
+
"uuid": "11.1.0",
|
|
62
|
+
"fs-extra": "11.3.0"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
65
|
"@babel/core": "7.27.1",
|
|
@@ -67,6 +68,7 @@
|
|
|
67
68
|
"@oclif/test": "4.1.12",
|
|
68
69
|
"@tsconfig/node18": "18.2.4",
|
|
69
70
|
"@types/jest": "29.5.14",
|
|
71
|
+
"@types/fs-extra": "11.0.4",
|
|
70
72
|
"@types/jsonwebtoken": "9.0.9",
|
|
71
73
|
"@types/node": "18.19.84",
|
|
72
74
|
"@types/react": "19.1.3",
|