@shoper/cli 0.1.0-7 → 0.1.0-8
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/api/cli_auth_api.js +15 -2
- package/build/cli/auth/cli_auth_constants.js +6 -0
- package/build/cli/auth/cli_auth_errors_factory.js +10 -0
- package/build/cli/auth/cli_auth_initializer.js +19 -0
- package/build/cli/auth/cli_auth_utils.js +22 -0
- package/build/cli/auth/model/cli_credentials.js +10 -0
- package/build/cli/auth/service/cli_auth_service.js +34 -0
- package/build/cli/auth/tokens/api/cli_auth_tokens_api.js +43 -1
- package/build/cli/auth/tokens/cli_auth_tokens_constants.js +6 -0
- package/build/cli/auth/tokens/cli_auth_tokens_errors_factory.js +10 -0
- package/build/cli/auth/tokens/cli_auth_tokens_initalizer.js +35 -1
- package/build/cli/auth/tokens/cli_auth_tokens_utils.js +26 -0
- package/build/cli/auth/tokens/service/cli_auth_tokens_service.js +84 -4
- package/build/cli/auth/tokens/service/cli_auth_tokens_service_constants.js +2 -0
- package/build/cli/class/base_cli_command.js +3 -0
- package/build/cli/class/errors/app_error/app_error.js +17 -0
- package/build/cli/class/errors/app_error/app_error_constants.js +7 -0
- package/build/cli/class/errors/file_system_errors_factory.js +26 -0
- package/build/cli/class/errors/http_errors_factory.js +21 -0
- package/build/cli/cli_constants.js +1 -0
- package/build/cli/commands/auth/cli_auth_add_token_command.js +32 -0
- package/build/cli/commands/auth/cli_auth_list_tokens_command.js +17 -0
- package/build/cli/commands/auth/cli_auth_remove_token_command.js +37 -0
- package/build/cli/commands/auth/cli_auth_switch_token_command.js +36 -0
- package/build/cli/commands/cli_update_command.js +7 -3
- package/build/cli/commands/commands_constants.js +5 -1
- package/build/cli/commands/files_diff_command.js +174 -0
- package/build/cli/commands/utils/prompt_for_token_utils.js +25 -0
- package/build/cli/core/cli_setup.js +20 -7
- package/build/cli/features/caches/json_cache/json_cache.js +50 -0
- package/build/cli/features/caches/memory_cache.js +6 -0
- package/build/cli/features/data_directory/cli_data_directory_constants.js +0 -1
- package/build/cli/features/data_directory/cli_data_directory_utils.js +3 -4
- package/build/cli/features/data_directory/service/cli_data_directory_service.js +2 -2
- package/build/cli/features/execution_context/execution_context_service.js +3 -5
- package/build/cli/features/http_requester/http_client.js +32 -1
- package/build/cli/features/version/service/cli_version_service.js +2 -4
- package/build/cli/hooks/authorization/ensure_authorization_hook.js +11 -6
- package/build/cli/hooks/authorization/ensure_authorization_hook_constants.js +8 -1
- package/build/index.js +34 -1
- package/build/theme/class/fetch_resources/fetch_resources.js +126 -0
- package/build/theme/class/fetch_resources/fetch_resources_constants.js +2 -0
- package/build/theme/class/fetch_resources/fetch_resources_errors_factory.js +11 -0
- package/build/theme/class/fetch_resources/fetch_resources_utils.js +35 -0
- package/build/theme/commands/theme_commands_constants.js +8 -0
- package/build/theme/commands/theme_init_command.js +53 -0
- package/build/theme/commands/theme_list_command.js +16 -0
- package/build/theme/commands/theme_pull_command.js +124 -0
- package/build/theme/commands/theme_push_command.js +65 -0
- package/build/theme/commands/theme_show_changes_command.js +60 -0
- package/build/theme/commands/theme_verify_command.js +43 -0
- package/build/theme/features/theme/actions/api/theme_actions_api.js +19 -0
- package/build/theme/features/theme/actions/service/theme_actions_service.js +92 -0
- package/build/theme/features/theme/actions/service/theme_actions_service_constants.js +2 -0
- package/build/theme/features/theme/actions/theme_actions_constants.js +15 -0
- package/build/theme/features/theme/actions/theme_actions_initializer.js +27 -0
- package/build/theme/features/theme/actions/theme_actions_utils.js +8 -0
- package/build/theme/features/theme/directory/theme_directory_utils.js +61 -14
- package/build/theme/features/theme/fetch/api/theme_fetch_api.js +16 -0
- package/build/theme/features/theme/fetch/http/theme_fetch_http_api.js +18 -0
- package/build/theme/features/theme/fetch/service/theme_fetch_service.js +113 -0
- package/build/theme/features/theme/fetch/theme_fetch_constants.js +7 -0
- package/build/theme/features/theme/fetch/theme_fetch_initializer.js +23 -0
- package/build/theme/features/theme/init/api/theme_init_api.js +13 -0
- package/build/theme/features/theme/init/http/theme_init_http_api.js +18 -0
- package/build/theme/features/theme/init/service/theme_init_service.js +28 -0
- package/build/theme/features/theme/init/theme_init_constants.js +2 -0
- package/build/theme/features/theme/init/theme_init_initializer.js +22 -0
- package/build/theme/features/theme/merge/api/theme_merge_api.js +28 -0
- package/build/theme/features/theme/merge/service/theme_merge_service.js +56 -0
- package/build/theme/features/theme/merge/theme_merge_constants.js +9 -0
- package/build/theme/features/theme/merge/theme_merge_initializer.js +18 -0
- package/build/theme/features/theme/publish/theme_publish_constants.js +2 -0
- package/build/theme/features/theme/publish/theme_publish_utils.js +7 -0
- package/build/theme/features/theme/push/api/theme_push_api.js +13 -0
- package/build/theme/features/theme/push/http_api/theme_push_http_api.js +21 -0
- package/build/theme/features/theme/push/service/theme_push_service.js +194 -0
- package/build/theme/features/theme/push/service/theme_push_service_constants.js +1 -0
- package/build/theme/features/theme/push/theme_push_constants.js +4 -0
- package/build/theme/features/theme/push/theme_push_errors_factory.js +41 -0
- package/build/theme/features/theme/push/theme_push_initializer.js +27 -0
- package/build/theme/features/theme/theme_constants.js +6 -0
- package/build/theme/features/theme/utils/checksums/theme_checksums_error_factory.js +10 -0
- package/build/theme/features/theme/utils/checksums/theme_checksums_utils.js +94 -0
- package/build/theme/features/theme/utils/directories/theme_resources_with_id_directory_utils.js +80 -0
- package/build/theme/features/theme/utils/theme_images_utils.js +31 -0
- package/build/theme/features/themes/list/api/themes_list_api.js +13 -0
- package/build/theme/features/themes/{http/shoper_themes_http_api.js → list/http/themes_list_http_api.js} +3 -2
- package/build/theme/features/themes/{model/theme_metadata.js → list/model/theme_list_metadata.js} +3 -1
- package/build/theme/features/themes/list/services/themes_list_service.js +37 -0
- package/build/theme/features/themes/list/themes_list_constants.js +2 -0
- package/build/theme/features/themes/list/themes_list_initializer.js +20 -0
- package/build/theme/hooks/ensure_theme_meta_data_untouched.js +17 -0
- package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date.js +21 -0
- package/build/theme/hooks/theme_checksums/ensure_theme_current_checksums_up_to_date_constants.js +7 -0
- package/build/theme/hooks/themes_actions/ensure_themes_actions_hook.js +45 -0
- package/build/theme/hooks/themes_actions/ensure_themes_actions_hook_constants.js +7 -0
- package/build/theme/index.js +13 -4
- package/build/theme/utils/directory_validator/directory_validator_constants.js +13 -0
- package/build/theme/utils/directory_validator/directory_validator_utils.js +187 -0
- package/build/utils/checksums/checksums_utils.js +95 -0
- package/build/utils/checksums/checksums_utils_constants.js +1 -0
- package/build/utils/date_utils.js +3 -0
- package/build/utils/download_file/download_file_errors_factory.js +9 -0
- package/build/utils/download_file/download_file_utils.js +46 -0
- package/build/utils/fs/errors/stream_read_error.js +11 -0
- package/build/utils/fs/errors/stream_write_error.js +11 -0
- package/build/utils/fs/fs_utils.js +152 -0
- package/build/utils/http_utils.js +10 -0
- package/build/utils/path_utils.js +34 -0
- package/build/utils/stream_transforms/json_indent_transform.js +21 -0
- package/build/utils/url_utils.js +9 -0
- package/build/utils/zip/create_zip_utils.js +80 -0
- package/build/utils/zip/errors/create_zip_error.js +11 -0
- package/build/utils/zip/errors/open_zip_error.js +11 -0
- package/build/utils/zip/extract_zip_utils.js +104 -0
- package/oclif.config.js +4 -2
- package/package.json +34 -7
- package/build/cli/hooks/migration/migration_hook.js +0 -4
- package/build/theme/commands/list_command.js +0 -12
- package/build/theme/commands/pull_command.js +0 -24
- package/build/theme/features/theme/directory/theme_directories_utils.js +0 -10
- package/build/theme/features/theme/pull/api/shoper_theme_pull_api.js +0 -9
- package/build/theme/features/theme/pull/http/shoper_theme_pull_http_api.js +0 -14
- package/build/theme/features/theme/pull/service/shoper_theme_pull_service.js +0 -68
- package/build/theme/features/theme/pull/shoper_theme_pull_initializer.js +0 -22
- package/build/theme/features/themes/api/shoper_themes_api.js +0 -14
- package/build/theme/features/themes/services/shoper_themes_service.js +0 -15
- package/build/theme/features/themes/shoper_themes_constants.js +0 -2
- package/build/theme/features/themes/shoper_themes_initalizer.js +0 -20
- package/build/utils/fs.js +0 -44
- package/build/utils/path.js +0 -13
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import { BaseCliCommand } from '../class/base_cli_command.js';
|
|
3
|
+
import * as readline from 'node:readline/promises';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import { Args } from '@oclif/core';
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import { diffWords } from 'diff';
|
|
9
|
+
export class CliFilesDiffCommand extends BaseCliCommand {
|
|
10
|
+
static summary = 'Differentiate between two files';
|
|
11
|
+
static args = {
|
|
12
|
+
file1: Args.string({
|
|
13
|
+
name: 'file1',
|
|
14
|
+
required: true,
|
|
15
|
+
description: 'First file to compare',
|
|
16
|
+
type: 'string'
|
|
17
|
+
}),
|
|
18
|
+
file2: Args.string({
|
|
19
|
+
name: 'file2',
|
|
20
|
+
required: true,
|
|
21
|
+
description: 'Second file to compare',
|
|
22
|
+
type: 'string'
|
|
23
|
+
})
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { args } = await this.parse(CliFilesDiffCommand);
|
|
27
|
+
const inputAPath = args.file1;
|
|
28
|
+
const inputBPath = args.file2;
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
Promise.all([readLines(inputAPath), readLines(inputBPath)]).then((result) => {
|
|
31
|
+
const [aLines, bLines] = result;
|
|
32
|
+
// console.log('aLines', aLines);
|
|
33
|
+
// console.log('bLines', bLines);
|
|
34
|
+
merge(aLines, bLines);
|
|
35
|
+
resolve();
|
|
36
|
+
});
|
|
37
|
+
// aStream.on('line', (input) => {
|
|
38
|
+
// console.log('aStream line: ', input);
|
|
39
|
+
// });
|
|
40
|
+
//
|
|
41
|
+
// bStream.on('line', (input) => {
|
|
42
|
+
// console.log('bStream line: ', input);
|
|
43
|
+
// });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const readLines = async (filePath) => {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const lines = [];
|
|
50
|
+
const inputStream = readline.createInterface({
|
|
51
|
+
input: fs.createReadStream(path.resolve(process.cwd(), filePath)),
|
|
52
|
+
crlfDelay: Infinity
|
|
53
|
+
});
|
|
54
|
+
inputStream.on('line', (line) => {
|
|
55
|
+
lines.push(line);
|
|
56
|
+
});
|
|
57
|
+
inputStream.on('close', () => {
|
|
58
|
+
resolve(lines);
|
|
59
|
+
});
|
|
60
|
+
inputStream.on('error', (err) => {
|
|
61
|
+
reject(err);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
const merge = (aLines, bLines) => {
|
|
66
|
+
let hasConflict = false;
|
|
67
|
+
const maxLength = Math.max(aLines.length, bLines.length);
|
|
68
|
+
const outputPath = path.resolve(process.cwd(), 'merge.txt');
|
|
69
|
+
const outStream = fs.createWriteStream(outputPath, { encoding: 'utf8' });
|
|
70
|
+
for (let i = 0; i < maxLength; i++) {
|
|
71
|
+
const a = aLines[i] ?? '';
|
|
72
|
+
const b = bLines[i] ?? '';
|
|
73
|
+
if (a === b) {
|
|
74
|
+
outStream.write(a + '\n');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
hasConflict = true;
|
|
78
|
+
console.log('⚠️ Conflict detected:');
|
|
79
|
+
console.log('a:', a);
|
|
80
|
+
console.log('b:', b);
|
|
81
|
+
const { aFormatted, bFormatted } = formatWordDiff(a, b);
|
|
82
|
+
console.log('aFormatted', aFormatted);
|
|
83
|
+
console.log('bFormatted', bFormatted);
|
|
84
|
+
outStream.write('<<<<<<< mine\n');
|
|
85
|
+
outStream.write(aFormatted + '\n');
|
|
86
|
+
outStream.write('=======\n');
|
|
87
|
+
outStream.write(bFormatted + '\n');
|
|
88
|
+
outStream.write('>>>>>>> theirs\n');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
outStream.end();
|
|
92
|
+
outStream.on('finish', () => {
|
|
93
|
+
if (hasConflict) {
|
|
94
|
+
console.log('⚠️ Conflicts detected. Check', outputPath);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.log('✅ Merged with no conflicts. Output written to', outputPath);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
function formatWordDiff(aLine, bLine) {
|
|
102
|
+
const changes = diffWords(aLine, bLine);
|
|
103
|
+
const aFormatted = changes.map((part) => (part.added ? '' : part.value)).join('');
|
|
104
|
+
const bFormatted = changes.map((part) => (part.removed ? '' : part.value)).join('');
|
|
105
|
+
return {
|
|
106
|
+
aFormatted: aFormatted.trimEnd(),
|
|
107
|
+
bFormatted: bFormatted.trimEnd()
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// const fs = require('fs');
|
|
111
|
+
// const path = require('path');
|
|
112
|
+
// const readline = require('readline');
|
|
113
|
+
// const Diff = require('diff');
|
|
114
|
+
//
|
|
115
|
+
// async function mergeWithCommentsStream(fileAPath, fileBPath, outputPath) {
|
|
116
|
+
// const textA = await fs.promises.readFile(fileAPath, 'utf8');
|
|
117
|
+
// const textB = await fs.promises.readFile(fileBPath, 'utf8');
|
|
118
|
+
//
|
|
119
|
+
// const diffs = Diff.diffLines(textA, textB);
|
|
120
|
+
// const outputStream = fs.createWriteStream(outputPath, { encoding: 'utf8' });
|
|
121
|
+
//
|
|
122
|
+
// let currentState = 'equal'; // 'equal' | 'added' | 'removed'
|
|
123
|
+
//
|
|
124
|
+
// for (const part of diffs) {
|
|
125
|
+
// const lines = part.value.endsWith('\n') ? part.value.slice(0, -1).split('\n') : part.value.split('\n');
|
|
126
|
+
//
|
|
127
|
+
// if (part.added) {
|
|
128
|
+
// if (currentState !== 'added') {
|
|
129
|
+
// outputStream.write('added >>>>>\n');
|
|
130
|
+
// currentState = 'added';
|
|
131
|
+
// }
|
|
132
|
+
// for (const line of lines) {
|
|
133
|
+
// outputStream.write(line + '\n');
|
|
134
|
+
// }
|
|
135
|
+
// } else if (part.removed) {
|
|
136
|
+
// if (currentState !== 'removed') {
|
|
137
|
+
// outputStream.write('removed >>>>>\n');
|
|
138
|
+
// currentState = 'removed';
|
|
139
|
+
// }
|
|
140
|
+
// for (const line of lines) {
|
|
141
|
+
// outputStream.write(line + '\n');
|
|
142
|
+
// }
|
|
143
|
+
// } else {
|
|
144
|
+
// // Close any previous block
|
|
145
|
+
// if (currentState === 'added') {
|
|
146
|
+
// outputStream.write('end-added >>>\n');
|
|
147
|
+
// } else if (currentState === 'removed') {
|
|
148
|
+
// outputStream.write('end-removed >>>\n');
|
|
149
|
+
// }
|
|
150
|
+
// currentState = 'equal';
|
|
151
|
+
//
|
|
152
|
+
// for (const line of lines) {
|
|
153
|
+
// outputStream.write(line + '\n');
|
|
154
|
+
// }
|
|
155
|
+
// }
|
|
156
|
+
// }
|
|
157
|
+
//
|
|
158
|
+
// // Final cleanup in case the last block was added/removed
|
|
159
|
+
// if (currentState === 'added') {
|
|
160
|
+
// outputStream.write('end-added >>>\n');
|
|
161
|
+
// } else if (currentState === 'removed') {
|
|
162
|
+
// outputStream.write('end-removed >>>\n');
|
|
163
|
+
// }
|
|
164
|
+
//
|
|
165
|
+
// outputStream.end();
|
|
166
|
+
// console.log(`✅ Merge complete. Output written to: ${outputPath}`);
|
|
167
|
+
// }
|
|
168
|
+
//
|
|
169
|
+
// // Example usage
|
|
170
|
+
// const fileA = path.resolve('versionA.txt');
|
|
171
|
+
// const fileB = path.resolve('versionB.txt');
|
|
172
|
+
// const outputFile = path.resolve('mergedWithComments.txt');
|
|
173
|
+
//
|
|
174
|
+
// mergeWithCommentsStream(fileA, fileB, outputFile);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CLiAuthTokensUtils } from '../../auth/tokens/cli_auth_tokens_utils.js';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
export const promptForToken = async (cliAuthTokensApi) => {
|
|
4
|
+
try {
|
|
5
|
+
const { token } = await inquirer.prompt([
|
|
6
|
+
{
|
|
7
|
+
type: 'input',
|
|
8
|
+
name: 'token',
|
|
9
|
+
required: true,
|
|
10
|
+
message: 'Enter token: '
|
|
11
|
+
}
|
|
12
|
+
]);
|
|
13
|
+
if (CLiAuthTokensUtils.hasTokenExpired(token)) {
|
|
14
|
+
console.log('Token is expired');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
cliAuthTokensApi.addToken(token);
|
|
18
|
+
cliAuthTokensApi.setDefaultToken(cliAuthTokensApi.getTokensCount());
|
|
19
|
+
console.log('Token added successfully');
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error(err);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -1,31 +1,44 @@
|
|
|
1
|
-
import { getOSRootDirectory } from '../../utils/fs.js';
|
|
1
|
+
import { getOSRootDirectory } from '../../utils/fs/fs_utils.js';
|
|
2
2
|
import * as process from 'process';
|
|
3
3
|
import tmp from 'tmp-promise';
|
|
4
|
-
import { SanitizerInitializer, StarCoreSetup } from '@dreamcommerce/star_core';
|
|
5
4
|
import { HTTPRequesterInitializer } from '../features/http_requester/http_requester_initializer.js';
|
|
6
|
-
import {
|
|
5
|
+
import { SanitizerInitializer, StarCoreSetup } from '@dreamcommerce/star_core';
|
|
6
|
+
import { CliDataDirectoryInitializer } from '../features/data_directory/cli_data_directory_initializer.js';
|
|
7
7
|
import { ExecutionContextInitializer } from '../features/execution_context/execution_context_initalizer.js';
|
|
8
8
|
import { CliVersionInitializer } from '../features/version/cli_version_initializer.js';
|
|
9
|
-
import {
|
|
9
|
+
import { CliAuthTokensInitializer } from '../auth/tokens/cli_auth_tokens_initalizer.js';
|
|
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';
|
|
10
17
|
tmp.setGracefulCleanup();
|
|
11
18
|
export const cliSetup = async () => {
|
|
12
19
|
//TODO jakis ładny komuniakt błedu
|
|
13
20
|
if (process.cwd() === getOSRootDirectory())
|
|
14
21
|
throw 'You cannot run this command in the root directory of the os system';
|
|
15
22
|
await StarCoreSetup.setup({
|
|
16
|
-
//TODO dnamicznie inicjalizowanie ficzurów wykorzystywanych w poszczególnych komendach
|
|
17
23
|
features: [
|
|
18
24
|
SanitizerInitializer,
|
|
19
25
|
HTTPRequesterInitializer,
|
|
20
26
|
CliDataDirectoryInitializer,
|
|
21
27
|
ExecutionContextInitializer,
|
|
22
28
|
CliVersionInitializer,
|
|
23
|
-
|
|
29
|
+
CliAuthTokensInitializer,
|
|
30
|
+
CliAuthInitializer,
|
|
31
|
+
ThemesListInitializer,
|
|
32
|
+
ThemeActionsInitializer,
|
|
33
|
+
//TODO dnamicznie inicjalizowanie ficzurów wykorzystywanych w poszczególnych komendach
|
|
34
|
+
ThemeInitInitializer,
|
|
35
|
+
ThemeMergeInitializer,
|
|
36
|
+
ThemeFetchInitializer,
|
|
37
|
+
ThemePushInitializer
|
|
24
38
|
],
|
|
25
39
|
options: {
|
|
26
40
|
featuresTracking: false,
|
|
27
41
|
messageQueue: false
|
|
28
42
|
}
|
|
29
43
|
});
|
|
30
|
-
//TODO structure validation
|
|
31
44
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { FeatureCore } from '@dreamcommerce/star_core';
|
|
2
|
+
import Conf from 'conf';
|
|
3
|
+
export class JsonCache extends FeatureCore {
|
|
4
|
+
#cache;
|
|
5
|
+
moduleName = 'JsonCache';
|
|
6
|
+
constructor({ path, name, configFileMode = 600, ...rest }) {
|
|
7
|
+
super();
|
|
8
|
+
this.#cache = new Conf({
|
|
9
|
+
cwd: path,
|
|
10
|
+
configName: name,
|
|
11
|
+
configFileMode,
|
|
12
|
+
...rest
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
set(key, value) {
|
|
16
|
+
this.#cache.set(key, value);
|
|
17
|
+
}
|
|
18
|
+
get(key) {
|
|
19
|
+
return this.#cache.get(key) ?? null;
|
|
20
|
+
}
|
|
21
|
+
getAll() {
|
|
22
|
+
return Object.keys(this.#cache.store).map((key) => this.get(key));
|
|
23
|
+
}
|
|
24
|
+
getKeys() {
|
|
25
|
+
return Object.keys(this.#cache.store);
|
|
26
|
+
}
|
|
27
|
+
remove(key) {
|
|
28
|
+
this.#cache.delete(key);
|
|
29
|
+
}
|
|
30
|
+
clear() {
|
|
31
|
+
this.#cache.clear();
|
|
32
|
+
}
|
|
33
|
+
has(key) {
|
|
34
|
+
return this.#cache.has(key);
|
|
35
|
+
}
|
|
36
|
+
get size() {
|
|
37
|
+
return this.#cache.size;
|
|
38
|
+
}
|
|
39
|
+
getMultiple(keys) {
|
|
40
|
+
return keys.map((key) => this.get(key)).filter(Boolean);
|
|
41
|
+
}
|
|
42
|
+
setMultiple(storeRecord) {
|
|
43
|
+
storeRecord.forEach(({ key, value }) => {
|
|
44
|
+
this.set(key, value);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
removeMultiple(keys) {
|
|
48
|
+
keys.forEach((key) => this.remove(key));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -14,6 +14,12 @@ export class MemoryCache extends FeatureCore {
|
|
|
14
14
|
get(key) {
|
|
15
15
|
return this.#cache.get(key) ?? null;
|
|
16
16
|
}
|
|
17
|
+
getAll() {
|
|
18
|
+
return Array.from(this.#cache.values());
|
|
19
|
+
}
|
|
20
|
+
getKeys() {
|
|
21
|
+
return Array.from(this.#cache.keys());
|
|
22
|
+
}
|
|
17
23
|
remove(key) {
|
|
18
24
|
this.#cache.delete(key);
|
|
19
25
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { directoryExists, makeDirectory } from '../../../utils/fs.js';
|
|
2
|
-
import { join } from '../../../utils/
|
|
3
|
-
import {
|
|
1
|
+
import { directoryExists, makeDirectory } from '../../../utils/fs/fs_utils.js';
|
|
2
|
+
import { join } from '../../../utils/path_utils.js';
|
|
3
|
+
import { SHOPER_CLI_DATA_DIRECTORY } from './cli_data_directory_constants.js';
|
|
4
4
|
export class CliDataDirectoryUtils {
|
|
5
5
|
static async createDataDirectory(path) {
|
|
6
6
|
try {
|
|
7
7
|
await makeDirectory(join(path, SHOPER_CLI_DATA_DIRECTORY));
|
|
8
|
-
await makeDirectory(join(path, SHOPER_CLI_DATA_DIRECTORY, SHOPER_CLI_CACHE_DIRECTORY));
|
|
9
8
|
}
|
|
10
9
|
catch (e) {
|
|
11
10
|
// TODO handle error
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as os from 'os';
|
|
1
|
+
import * as os from 'node:os';
|
|
2
2
|
import { CliDataDirectoryUtils } from '../cli_data_directory_utils.js';
|
|
3
|
-
import { join } from '../../../../utils/
|
|
3
|
+
import { join } from '../../../../utils/path_utils.js';
|
|
4
4
|
import { SHOPER_CLI_DATA_DIRECTORY } from '../cli_data_directory_constants.js';
|
|
5
5
|
export class CliDataDirectoryService {
|
|
6
6
|
#dataDirectoryPath = os.homedir();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import process from 'process';
|
|
1
|
+
import process from 'node:process';
|
|
2
2
|
import { EXECUTION_CONTEXTS } from './execution_context_constants.js';
|
|
3
3
|
import { ThemeDirectoryUtils } from '../../../theme/features/theme/directory/theme_directory_utils.js';
|
|
4
4
|
export class ExecutionContextService {
|
|
@@ -11,9 +11,7 @@ export class ExecutionContextService {
|
|
|
11
11
|
}
|
|
12
12
|
async _getGlobalExecutionContext() {
|
|
13
13
|
return {
|
|
14
|
-
type: EXECUTION_CONTEXTS.global
|
|
15
|
-
//TODO get available themes within process.cwd()
|
|
16
|
-
availableThemes: []
|
|
14
|
+
type: EXECUTION_CONTEXTS.global
|
|
17
15
|
};
|
|
18
16
|
}
|
|
19
17
|
async getExecutionContext() {
|
|
@@ -31,7 +29,7 @@ export class ExecutionContextService {
|
|
|
31
29
|
type: EXECUTION_CONTEXTS.theme,
|
|
32
30
|
themeId: themeDirectoryMetadata.themeId,
|
|
33
31
|
executionDir: process.cwd(),
|
|
34
|
-
|
|
32
|
+
themeRootDir: themeRoot
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
35
|
}
|
|
@@ -1,8 +1,39 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
|
|
2
|
+
import { FeatureCore } from '@dreamcommerce/star_core';
|
|
3
|
+
import { CLI_AUTH_API_NAME } from '../../auth/cli_auth_constants.js';
|
|
4
|
+
import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
|
|
5
|
+
export class HttpClient extends FeatureCore {
|
|
3
6
|
#axios;
|
|
4
7
|
constructor() {
|
|
8
|
+
super();
|
|
5
9
|
this.#axios = axios;
|
|
10
|
+
this._setupMiddlewares();
|
|
11
|
+
}
|
|
12
|
+
_setupMiddlewares() {
|
|
13
|
+
this.#axios.interceptors.request.use((config) => {
|
|
14
|
+
if (config.isPrivate) {
|
|
15
|
+
const accessToken = this._getAccessToken();
|
|
16
|
+
if (!accessToken)
|
|
17
|
+
throw Error('Unauthorized');
|
|
18
|
+
config.headers['Authorization'] = `Bearer ${accessToken}`;
|
|
19
|
+
}
|
|
20
|
+
return config;
|
|
21
|
+
}, (error) => {
|
|
22
|
+
return Promise.reject(error);
|
|
23
|
+
});
|
|
24
|
+
this.#axios.interceptors.response.use((response) => {
|
|
25
|
+
return response;
|
|
26
|
+
}, (error) => {
|
|
27
|
+
return Promise.reject(error);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
_getAccessToken() {
|
|
31
|
+
const credentialsApi = this.getApiSync(CLI_AUTH_API_NAME);
|
|
32
|
+
const credentials = credentialsApi.getCredentials();
|
|
33
|
+
if (!credentials)
|
|
34
|
+
return null;
|
|
35
|
+
const cliAuthTokensApi = this.getApiSync(CLI_AUTH_TOKENS_API_NAME);
|
|
36
|
+
return cliAuthTokensApi.getDefaultToken();
|
|
6
37
|
}
|
|
7
38
|
fetch(options) {
|
|
8
39
|
const axiosOptions = {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { exec } from 'child_process';
|
|
2
2
|
import { CLI_NAME } from '../../../cli_constants.js';
|
|
3
|
-
//TODO clean cache command
|
|
4
3
|
export class CliVersionService {
|
|
5
4
|
async update() {
|
|
6
|
-
return new Promise((resolve) => {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
7
6
|
exec(`npm update -g ${CLI_NAME}`, (error, stdout) => {
|
|
8
|
-
//TODO error
|
|
9
7
|
if (error)
|
|
10
|
-
|
|
8
|
+
reject(error);
|
|
11
9
|
resolve(stdout);
|
|
12
10
|
});
|
|
13
11
|
});
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION } from './ensure_authorization_hook_constants.js';
|
|
2
|
+
import { useApi } from '../ensure_cli_initialized_hook.js';
|
|
3
|
+
import { CLI_AUTH_API_NAME } from '../../auth/cli_auth_constants.js';
|
|
4
|
+
import { CLI_AUTH_TOKENS_API_NAME } from '../../auth/tokens/cli_auth_tokens_constants.js';
|
|
5
|
+
import { promptForToken } from '../../commands/utils/prompt_for_token_utils.js';
|
|
6
|
+
import { CliAuthUtils } from '../../auth/cli_auth_utils.js';
|
|
2
7
|
const ensureAuthorizationHook = async ({ Command }) => {
|
|
3
|
-
|
|
4
|
-
if (isAuthorized || COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION.includes(Command.id))
|
|
8
|
+
if (COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION.includes(Command.id))
|
|
5
9
|
return;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
const cliAuthApi = useApi(CLI_AUTH_API_NAME);
|
|
11
|
+
const cliAuthTokensApi = useApi(CLI_AUTH_TOKENS_API_NAME);
|
|
12
|
+
while (!CliAuthUtils.checkCredentials(cliAuthApi, Command)) {
|
|
13
|
+
await promptForToken(cliAuthTokensApi);
|
|
14
|
+
}
|
|
10
15
|
};
|
|
11
16
|
export default ensureAuthorizationHook;
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
import { CLI_COMMANDS_NAMES } from '../../commands/commands_constants.js';
|
|
2
|
-
export const COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION = [
|
|
2
|
+
export const COMMANDS_THAT_NOT_REQUIRE_AUTHORIZATION = [
|
|
3
|
+
CLI_COMMANDS_NAMES.update,
|
|
4
|
+
CLI_COMMANDS_NAMES.update,
|
|
5
|
+
CLI_COMMANDS_NAMES.authAddToken,
|
|
6
|
+
CLI_COMMANDS_NAMES.authRemoveToken,
|
|
7
|
+
CLI_COMMANDS_NAMES.authListTokens,
|
|
8
|
+
CLI_COMMANDS_NAMES.switchToken
|
|
9
|
+
];
|
package/build/index.js
CHANGED
|
@@ -3,6 +3,10 @@ import { COMMANDS as THEME_COMMANDS } from './theme/index.js';
|
|
|
3
3
|
import crypto from 'crypto';
|
|
4
4
|
import { CLI_COMMANDS_NAMES } from './cli/commands/commands_constants.js';
|
|
5
5
|
import { CliUpdateCommand } from './cli/commands/cli_update_command.js';
|
|
6
|
+
import { CliAuthListTokensCommand } from './cli/commands/auth/cli_auth_list_tokens_command.js';
|
|
7
|
+
import { CliAuthAddTokenCommand } from './cli/commands/auth/cli_auth_add_token_command.js';
|
|
8
|
+
import { CliAuthRemoveTokenCommand } from './cli/commands/auth/cli_auth_remove_token_command.js';
|
|
9
|
+
import { CliAuthSwitchTokenCommand } from './cli/commands/auth/cli_auth_switch_token_command.js';
|
|
6
10
|
//TODO
|
|
7
11
|
//@ts-ignore
|
|
8
12
|
if (typeof global.crypto !== 'object') {
|
|
@@ -19,7 +23,11 @@ function getRandomValues(array) {
|
|
|
19
23
|
}
|
|
20
24
|
process.on('uncaughtException', (err) => {
|
|
21
25
|
//TODO handle error
|
|
22
|
-
console.
|
|
26
|
+
console.error('Uncaught Exception:', err);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
});
|
|
29
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
30
|
+
console.error('Unhandled Rejection:', reason);
|
|
23
31
|
process.exit(1);
|
|
24
32
|
});
|
|
25
33
|
const signals = ['SIGINT', 'SIGTERM', 'SIGQUIT'];
|
|
@@ -30,6 +38,31 @@ signals.forEach((signal) => {
|
|
|
30
38
|
});
|
|
31
39
|
export const COMMANDS = {
|
|
32
40
|
[CLI_COMMANDS_NAMES.update]: CliUpdateCommand,
|
|
41
|
+
[CLI_COMMANDS_NAMES.authListTokens]: CliAuthListTokensCommand,
|
|
42
|
+
[CLI_COMMANDS_NAMES.authAddToken]: CliAuthAddTokenCommand,
|
|
43
|
+
[CLI_COMMANDS_NAMES.authRemoveToken]: CliAuthRemoveTokenCommand,
|
|
44
|
+
[CLI_COMMANDS_NAMES.switchToken]: CliAuthSwitchTokenCommand,
|
|
33
45
|
...THEME_COMMANDS
|
|
34
46
|
};
|
|
35
47
|
export { runCLI } from './cli/index.js';
|
|
48
|
+
/**
|
|
49
|
+
* TODO:
|
|
50
|
+
* testy verify
|
|
51
|
+
* - usuniecie po koleji .shoper, macros, modules, settings, styles...
|
|
52
|
+
* testy theme show-changes
|
|
53
|
+
* - macro
|
|
54
|
+
* - dodawanie, zmienianie i usuwanie makr
|
|
55
|
+
* testy theme verify
|
|
56
|
+
* - makro
|
|
57
|
+
* - dodawanie, zmienianie i usuwanie makr
|
|
58
|
+
* testy pull push
|
|
59
|
+
* - nie skinstore
|
|
60
|
+
* - push nowego modułu, podmieni sie folder i checksumy przywróćenie foledu bez checksum i push error z permissions
|
|
61
|
+
* - dodawanie, modzenie i usuwanie customowych makr
|
|
62
|
+
* - modzenie makr
|
|
63
|
+
* - dodawanie i usuwanie customowych modułów
|
|
64
|
+
* - podmiana thumbnail
|
|
65
|
+
* - skinstore
|
|
66
|
+
* - modzenie danych settingsów skinstore
|
|
67
|
+
* - dodawanie, usuwanie, podmienianie obrazków
|
|
68
|
+
*/
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { REQUEST_TYPES } from '@dreamcommerce/star_core';
|
|
2
|
+
import { downloadFile } from '../../../utils/download_file/download_file_utils.js';
|
|
3
|
+
import { extractZip } from '../../../utils/zip/extract_zip_utils.js';
|
|
4
|
+
import { join } from '../../../utils/path_utils.js';
|
|
5
|
+
import tmp from 'tmp-promise';
|
|
6
|
+
import { copyFile, fileExists, readJSONFile } from '../../../utils/fs/fs_utils.js';
|
|
7
|
+
import { getResourcesPath, isResourceObject } from './fetch_resources_utils.js';
|
|
8
|
+
import { MAX_REQUEST_FOR_RESOURCES } from './fetch_resources_constants.js';
|
|
9
|
+
import { isRelativeUrl } from '../../../utils/url_utils.js';
|
|
10
|
+
import { FetchResourcesErrorsFactory } from './fetch_resources_errors_factory.js';
|
|
11
|
+
export class FetchResources {
|
|
12
|
+
#urlsAttempts = {};
|
|
13
|
+
#httpApi;
|
|
14
|
+
constructor(httpApi) {
|
|
15
|
+
this.#httpApi = httpApi;
|
|
16
|
+
}
|
|
17
|
+
async fetchResources({ dist, resourcesPart, parts, shopUrl }) {
|
|
18
|
+
if (Array.isArray(resourcesPart)) {
|
|
19
|
+
for (let i = 0; i < resourcesPart.length; i++) {
|
|
20
|
+
const resource = resourcesPart[i];
|
|
21
|
+
if (isResourceObject(resource)) {
|
|
22
|
+
await this._fetchResource({
|
|
23
|
+
url: isRelativeUrl(resource.url) ? `${shopUrl}${resource.url}` : resource.url,
|
|
24
|
+
dist,
|
|
25
|
+
parts: [...parts, i],
|
|
26
|
+
shopUrl,
|
|
27
|
+
isPrivate: resource.isPrivate ?? false
|
|
28
|
+
});
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
await this.fetchResources({
|
|
32
|
+
dist,
|
|
33
|
+
resourcesPart: resourcesPart[i],
|
|
34
|
+
parts: [...parts, i],
|
|
35
|
+
shopUrl
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (typeof resourcesPart === 'object') {
|
|
41
|
+
if (isResourceObject(resourcesPart)) {
|
|
42
|
+
await this._fetchResource({
|
|
43
|
+
url: isRelativeUrl(resourcesPart.url) ? `${shopUrl}${resourcesPart.url}` : resourcesPart.url,
|
|
44
|
+
dist,
|
|
45
|
+
parts,
|
|
46
|
+
shopUrl,
|
|
47
|
+
isPrivate: resourcesPart.isPrivate ?? false
|
|
48
|
+
});
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
await Promise.all(Object.keys(resourcesPart).map((key) => {
|
|
52
|
+
return this.fetchResources({
|
|
53
|
+
dist,
|
|
54
|
+
resourcesPart: resourcesPart[key],
|
|
55
|
+
parts: [...parts, key],
|
|
56
|
+
shopUrl
|
|
57
|
+
});
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async _getResourcesFileContent(resourcePath) {
|
|
62
|
+
return await readJSONFile(resourcePath);
|
|
63
|
+
}
|
|
64
|
+
_getResourcesPart(resources, parts) {
|
|
65
|
+
return parts.reduce((acc, part) => acc[part] ?? {}, resources);
|
|
66
|
+
}
|
|
67
|
+
async _fetchResource({ url, shopUrl, parts, dist, isPrivate }) {
|
|
68
|
+
this.#urlsAttempts[url] = (this.#urlsAttempts[url] ?? 0) + 1;
|
|
69
|
+
if (this.#urlsAttempts[url] > MAX_REQUEST_FOR_RESOURCES)
|
|
70
|
+
throw FetchResourcesErrorsFactory.createErrorFetchingResource(shopUrl, [
|
|
71
|
+
`Failed to fetch ${url} after 3 attempts, for: ${parts.join('')}`
|
|
72
|
+
]);
|
|
73
|
+
const { path: tmpDir } = await tmp.dir({ unsafeCleanup: true, prefix: 'theme_resources_tmp' });
|
|
74
|
+
try {
|
|
75
|
+
const { filename, ext, basename } = await downloadFile({
|
|
76
|
+
dist: tmpDir,
|
|
77
|
+
request: this._getRequest({ url, isPrivate }).response
|
|
78
|
+
});
|
|
79
|
+
if (ext === '.zip') {
|
|
80
|
+
await extractZip({
|
|
81
|
+
source: join(tmpDir, filename),
|
|
82
|
+
dist: join(tmpDir, basename)
|
|
83
|
+
});
|
|
84
|
+
if (!(await fileExists(getResourcesPath(join(tmpDir, basename)))))
|
|
85
|
+
return;
|
|
86
|
+
await copyFile(join(tmpDir, basename), dist, {
|
|
87
|
+
recursive: true,
|
|
88
|
+
force: true
|
|
89
|
+
});
|
|
90
|
+
const newResources = await this._getResourcesFileContent(getResourcesPath(join(tmpDir, basename)));
|
|
91
|
+
await this.fetchResources({
|
|
92
|
+
dist,
|
|
93
|
+
resourcesPart: this._getResourcesPart(newResources, parts),
|
|
94
|
+
parts,
|
|
95
|
+
shopUrl
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
await copyFile(join(tmpDir, filename), join(dist, this._getFilepathFromParts(parts), filename));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
throw FetchResourcesErrorsFactory.createErrorFetchingResource(shopUrl, err.message ? [err.message] : ['Unknown error']);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
_getRequest({ url, isPrivate }) {
|
|
107
|
+
return this.#httpApi.fetch({
|
|
108
|
+
url,
|
|
109
|
+
method: REQUEST_TYPES.get,
|
|
110
|
+
//TODO tajping
|
|
111
|
+
//@ts-ignore
|
|
112
|
+
responseType: 'stream',
|
|
113
|
+
sanitizeOptions: {
|
|
114
|
+
disable: true
|
|
115
|
+
},
|
|
116
|
+
isPrivate
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
_getFilepathFromParts(parts) {
|
|
120
|
+
return parts
|
|
121
|
+
.filter((part) => typeof part === 'string')
|
|
122
|
+
.reduce((acc, part) => {
|
|
123
|
+
return join(acc, part);
|
|
124
|
+
}, '');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AppError } from '../../../cli/class/errors/app_error/app_error.js';
|
|
2
|
+
export class FetchResourcesErrorsFactory {
|
|
3
|
+
static createErrorFetchingResource(shopUrl, messages) {
|
|
4
|
+
return new AppError({
|
|
5
|
+
code: 'theme.fetch_resources.error_fetching_resource',
|
|
6
|
+
message: `Error while fetching resources from shop "${shopUrl}"`,
|
|
7
|
+
level: 'error',
|
|
8
|
+
details: messages
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|