@magentrix-corp/magentrix-cli 1.1.1 → 1.1.3
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/actions/publish.js +122 -17
- package/package.json +1 -1
- package/utils/magentrix/api/assets.js +1 -1
package/actions/publish.js
CHANGED
|
@@ -165,27 +165,98 @@ const handleCreateStaticAssetAction = async (instanceUrl, apiKey, action) => {
|
|
|
165
165
|
* Handles DELETE_STATIC_ASSET action.
|
|
166
166
|
*/
|
|
167
167
|
const handleDeleteStaticAssetAction = async (instanceUrl, apiKey, action) => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
try {
|
|
169
|
+
const response = await deleteAsset(instanceUrl, apiKey, `/${action.folder}`, action.names);
|
|
170
|
+
return response;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
// Check if this is a "not found" error
|
|
173
|
+
const errorMessage = error?.message || String(error);
|
|
174
|
+
const errorLower = errorMessage.toLowerCase();
|
|
175
|
+
const isNotFound = errorLower.includes('404') ||
|
|
176
|
+
errorLower.includes('not found') ||
|
|
177
|
+
errorLower.includes('item not found');
|
|
178
|
+
|
|
179
|
+
if (isNotFound) {
|
|
180
|
+
// Clean up base.json since file doesn't exist on server
|
|
181
|
+
for (const name of action.names) {
|
|
182
|
+
const filePath = action.filePath || `${EXPORT_ROOT}/${action.folder}/${name}`;
|
|
183
|
+
removeFromBase(filePath);
|
|
184
|
+
}
|
|
185
|
+
return { cleanedFromCache: true };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Other errors should still fail
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
171
191
|
};
|
|
172
192
|
|
|
173
193
|
/**
|
|
174
194
|
* Handles CREATE_FOLDER action.
|
|
175
195
|
*/
|
|
176
196
|
const handleCreateFolderAction = async (instanceUrl, apiKey, action) => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
197
|
+
try {
|
|
198
|
+
const response = await createFolder(instanceUrl, apiKey, action.parentPath, action.folderName);
|
|
199
|
+
return response;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
// Check if folder already exists (likely created by file upload)
|
|
202
|
+
const errorMessage = error?.message || String(error);
|
|
203
|
+
const errorLower = errorMessage.toLowerCase();
|
|
204
|
+
const alreadyExists = errorLower.includes('already exists') ||
|
|
205
|
+
errorLower.includes('folder exists') ||
|
|
206
|
+
errorLower.includes('duplicate');
|
|
207
|
+
|
|
208
|
+
if (alreadyExists) {
|
|
209
|
+
// Folder already exists, update cache and treat as success
|
|
210
|
+
return { alreadyExisted: true };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Other errors should still fail
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
180
216
|
};
|
|
181
217
|
|
|
182
218
|
/**
|
|
183
219
|
* Handles DELETE_FOLDER action.
|
|
184
220
|
*/
|
|
185
221
|
const handleDeleteFolderAction = async (instanceUrl, apiKey, action) => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
222
|
+
try {
|
|
223
|
+
const response = await deleteAsset(instanceUrl, apiKey, action.parentPath, [action.folderName]);
|
|
224
|
+
return response;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
// Check if this is a "not found" error
|
|
227
|
+
const errorMessage = error?.message || String(error);
|
|
228
|
+
const errorLower = errorMessage.toLowerCase();
|
|
229
|
+
const isNotFound = errorLower.includes('404') ||
|
|
230
|
+
errorLower.includes('not found') ||
|
|
231
|
+
errorLower.includes('item not found');
|
|
232
|
+
|
|
233
|
+
if (isNotFound) {
|
|
234
|
+
// Clean up base.json since folder doesn't exist on server
|
|
235
|
+
removeFromBase(action.folderPath);
|
|
236
|
+
|
|
237
|
+
// Also remove all files and subfolders inside this folder from base
|
|
238
|
+
const hits = await config.searchObject({}, { filename: "base.json", global: false });
|
|
239
|
+
const cachedResults = hits?.[0]?.value || {};
|
|
240
|
+
|
|
241
|
+
for (const [recordId, cachedEntry] of Object.entries(cachedResults)) {
|
|
242
|
+
const entryPath = cachedEntry.filePath || cachedEntry.lastKnownPath;
|
|
243
|
+
if (entryPath && typeof entryPath === 'string') {
|
|
244
|
+
const normalizedEntryPath = path.normalize(entryPath);
|
|
245
|
+
const normalizedFolderPath = path.normalize(action.folderPath);
|
|
246
|
+
|
|
247
|
+
// Check if this entry is inside the deleted folder
|
|
248
|
+
if (normalizedEntryPath.startsWith(normalizedFolderPath + path.sep)) {
|
|
249
|
+
removeFromBase(recordId);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return { cleanedFromCache: true };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Other errors should still fail
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
189
260
|
};
|
|
190
261
|
|
|
191
262
|
/**
|
|
@@ -227,8 +298,12 @@ const updateCacheAfterSuccess = async (action, operationResult) => {
|
|
|
227
298
|
break;
|
|
228
299
|
|
|
229
300
|
case "delete_static_asset":
|
|
230
|
-
|
|
231
|
-
|
|
301
|
+
// Skip if already cleaned from cache during 404 handling
|
|
302
|
+
if (!operationResult?.cleanedFromCache) {
|
|
303
|
+
for (const name of action.names) {
|
|
304
|
+
const filePath = action.filePath || `${EXPORT_ROOT}/${action.folder}/${name}`;
|
|
305
|
+
removeFromBase(filePath);
|
|
306
|
+
}
|
|
232
307
|
}
|
|
233
308
|
break;
|
|
234
309
|
|
|
@@ -240,9 +315,31 @@ const updateCacheAfterSuccess = async (action, operationResult) => {
|
|
|
240
315
|
updateBase(action.folderPath, { Id: action.folderPath, Type: "Folder" });
|
|
241
316
|
break;
|
|
242
317
|
|
|
243
|
-
case "delete_folder":
|
|
244
|
-
|
|
318
|
+
case "delete_folder": {
|
|
319
|
+
// Skip if already cleaned from cache during 404 handling
|
|
320
|
+
if (!operationResult?.cleanedFromCache) {
|
|
321
|
+
// Remove the folder itself from base
|
|
322
|
+
removeFromBase(action.folderPath);
|
|
323
|
+
|
|
324
|
+
// Also remove all files and subfolders inside this folder from base
|
|
325
|
+
const hits = await config.searchObject({}, { filename: "base.json", global: false });
|
|
326
|
+
const cachedResults = hits?.[0]?.value || {};
|
|
327
|
+
|
|
328
|
+
for (const [recordId, cachedEntry] of Object.entries(cachedResults)) {
|
|
329
|
+
const entryPath = cachedEntry.filePath || cachedEntry.lastKnownPath;
|
|
330
|
+
if (entryPath && typeof entryPath === 'string') {
|
|
331
|
+
const normalizedEntryPath = path.normalize(entryPath);
|
|
332
|
+
const normalizedFolderPath = path.normalize(action.folderPath);
|
|
333
|
+
|
|
334
|
+
// Check if this entry is inside the deleted folder
|
|
335
|
+
if (normalizedEntryPath.startsWith(normalizedFolderPath + path.sep)) {
|
|
336
|
+
removeFromBase(recordId);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
245
341
|
break;
|
|
342
|
+
}
|
|
246
343
|
}
|
|
247
344
|
} catch (error) {
|
|
248
345
|
console.warn(chalk.yellow(`Warning: Failed to update cache for ${action.action}: ${error.message}`));
|
|
@@ -472,7 +569,8 @@ export const runPublish = async (options = {}) => {
|
|
|
472
569
|
actionQueue.push({
|
|
473
570
|
action: 'delete_static_asset',
|
|
474
571
|
folder: toApiPath(cacheFile.filePath),
|
|
475
|
-
names: [path.basename(cacheFile.filePath)]
|
|
572
|
+
names: [path.basename(cacheFile.filePath)],
|
|
573
|
+
filePath: cacheFile.filePath // Store actual file path for filtering
|
|
476
574
|
});
|
|
477
575
|
continue;
|
|
478
576
|
}
|
|
@@ -578,10 +676,17 @@ export const runPublish = async (options = {}) => {
|
|
|
578
676
|
.map(a => a.folderPath);
|
|
579
677
|
|
|
580
678
|
const filteredActionQueue = actionQueue.filter(action => {
|
|
581
|
-
if (action.action === 'delete_static_asset') {
|
|
582
|
-
|
|
679
|
+
if (action.action === 'delete_static_asset' && action.filePath) {
|
|
680
|
+
// Check if this file's directory is inside any folder being deleted
|
|
681
|
+
const fileDir = path.dirname(action.filePath);
|
|
583
682
|
for (const deletedFolder of foldersBeingDeleted) {
|
|
584
|
-
|
|
683
|
+
// Use path.normalize to handle trailing slashes and ensure proper comparison
|
|
684
|
+
const normalizedFileDir = path.normalize(fileDir);
|
|
685
|
+
const normalizedDeletedFolder = path.normalize(deletedFolder);
|
|
686
|
+
|
|
687
|
+
// Check if file is inside the deleted folder (or is the folder itself)
|
|
688
|
+
if (normalizedFileDir === normalizedDeletedFolder ||
|
|
689
|
+
normalizedFileDir.startsWith(normalizedDeletedFolder + path.sep)) {
|
|
585
690
|
return false; // Skip - covered by folder deletion
|
|
586
691
|
}
|
|
587
692
|
}
|
package/package.json
CHANGED
|
@@ -80,7 +80,7 @@ export const deleteAsset = async (instanceUrl, token, path = '/contents/assets',
|
|
|
80
80
|
if (!path) throw new Error("Path is required when deleting assets.");
|
|
81
81
|
if (!Array.isArray(names) || names?.length === 0) throw new Error("At least one file name is required when deleting static assets.");
|
|
82
82
|
|
|
83
|
-
let reqPath = `/api/3.0/staticassets?path=${encodeURIComponent(path)}&names=${names.join(",")}`;
|
|
83
|
+
let reqPath = `/api/3.0/staticassets?path=${encodeURIComponent(path)}&names=${names.map(name => encodeURIComponent(name)).join(",")}`;
|
|
84
84
|
|
|
85
85
|
const response = await fetchMagentrix({
|
|
86
86
|
instanceUrl,
|