@magentrix-corp/magentrix-cli 1.2.0 → 1.3.0
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/README.md +282 -2
- package/actions/autopublish.js +9 -48
- package/actions/iris/buildStage.js +330 -0
- package/actions/iris/delete.js +211 -0
- package/actions/iris/dev.js +338 -0
- package/actions/iris/index.js +6 -0
- package/actions/iris/link.js +377 -0
- package/actions/iris/recover.js +228 -0
- package/actions/publish.js +258 -15
- package/actions/pull.js +520 -327
- package/actions/setup.js +62 -15
- package/bin/magentrix.js +43 -1
- package/package.json +2 -1
- package/utils/autopublishLock.js +77 -0
- package/utils/cli/helpers/compare.js +4 -5
- package/utils/cli/helpers/ensureApiKey.js +28 -22
- package/utils/cli/helpers/ensureInstanceUrl.js +35 -27
- package/utils/cli/writeRecords.js +13 -2
- package/utils/config.js +76 -0
- package/utils/iris/backup.js +201 -0
- package/utils/iris/builder.js +304 -0
- package/utils/iris/config-reader.js +296 -0
- package/utils/iris/deleteHelper.js +102 -0
- package/utils/iris/linker.js +490 -0
- package/utils/iris/validator.js +281 -0
- package/utils/iris/zipper.js +239 -0
- package/utils/logger.js +13 -5
- package/utils/magentrix/api/auth.js +45 -6
- package/utils/magentrix/api/iris.js +235 -0
- package/utils/permissionError.js +70 -0
- package/utils/progress.js +87 -1
- package/utils/updateFileBase.js +14 -2
- package/vars/global.js +1 -0
package/actions/publish.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
ENTITY_TYPE_MAP,
|
|
12
12
|
EXPORT_ROOT,
|
|
13
13
|
TYPE_DIR_MAP,
|
|
14
|
+
IRIS_APPS_DIR,
|
|
14
15
|
} from "../vars/global.js";
|
|
15
16
|
import { getFileTag, setFileTag } from "../utils/filetag.js";
|
|
16
17
|
import { sha256 } from "../utils/hash.js";
|
|
@@ -20,6 +21,11 @@ import { deleteEntity } from "../utils/magentrix/api/deleteEntity.js";
|
|
|
20
21
|
import { removeFromBase, updateBase } from "../utils/updateFileBase.js";
|
|
21
22
|
import { deleteAsset, uploadAsset, createFolder } from "../utils/magentrix/api/assets.js";
|
|
22
23
|
import { toApiPath, toApiFolderPath } from "../utils/assetPaths.js";
|
|
24
|
+
import { publishApp } from "../utils/magentrix/api/iris.js";
|
|
25
|
+
import { createIrisZip, hashIrisAppFolder } from "../utils/iris/zipper.js";
|
|
26
|
+
import { validateIrisAppFolder } from "../utils/iris/validator.js";
|
|
27
|
+
import { getLinkedProjects } from "../utils/iris/linker.js";
|
|
28
|
+
import { deleteIrisAppFromServer } from "../utils/iris/deleteHelper.js";
|
|
23
29
|
|
|
24
30
|
const config = new Config();
|
|
25
31
|
|
|
@@ -120,6 +126,8 @@ const walkFolders = (dir) => {
|
|
|
120
126
|
* Gets display name for an action in log messages.
|
|
121
127
|
*/
|
|
122
128
|
const getActionDisplayName = (action) => {
|
|
129
|
+
// Iris app actions
|
|
130
|
+
if (action.slug) return `${action.appName || action.slug} (${action.slug})`;
|
|
123
131
|
if (action.folderName) return action.folderName;
|
|
124
132
|
if (action.names) return action.names.join(", ");
|
|
125
133
|
if (action.type) return action.type;
|
|
@@ -185,8 +193,8 @@ const handleDeleteStaticAssetAction = async (instanceUrl, apiKey, action) => {
|
|
|
185
193
|
const errorMessage = error?.message || String(error);
|
|
186
194
|
const errorLower = errorMessage.toLowerCase();
|
|
187
195
|
const isNotFound = errorLower.includes('404') ||
|
|
188
|
-
|
|
189
|
-
|
|
196
|
+
errorLower.includes('not found') ||
|
|
197
|
+
errorLower.includes('item not found');
|
|
190
198
|
|
|
191
199
|
if (isNotFound) {
|
|
192
200
|
// Clean up base.json since file doesn't exist on server
|
|
@@ -214,8 +222,8 @@ const handleCreateFolderAction = async (instanceUrl, apiKey, action) => {
|
|
|
214
222
|
const errorMessage = error?.message || String(error);
|
|
215
223
|
const errorLower = errorMessage.toLowerCase();
|
|
216
224
|
const alreadyExists = errorLower.includes('already exists') ||
|
|
217
|
-
|
|
218
|
-
|
|
225
|
+
errorLower.includes('folder exists') ||
|
|
226
|
+
errorLower.includes('duplicate');
|
|
219
227
|
|
|
220
228
|
if (alreadyExists) {
|
|
221
229
|
// Folder already exists, update cache and treat as success
|
|
@@ -239,8 +247,8 @@ const handleDeleteFolderAction = async (instanceUrl, apiKey, action) => {
|
|
|
239
247
|
const errorMessage = error?.message || String(error);
|
|
240
248
|
const errorLower = errorMessage.toLowerCase();
|
|
241
249
|
const isNotFound = errorLower.includes('404') ||
|
|
242
|
-
|
|
243
|
-
|
|
250
|
+
errorLower.includes('not found') ||
|
|
251
|
+
errorLower.includes('item not found');
|
|
244
252
|
|
|
245
253
|
if (isNotFound) {
|
|
246
254
|
// Clean up base.json since folder doesn't exist on server
|
|
@@ -273,11 +281,109 @@ const handleDeleteFolderAction = async (instanceUrl, apiKey, action) => {
|
|
|
273
281
|
}
|
|
274
282
|
};
|
|
275
283
|
|
|
284
|
+
/**
|
|
285
|
+
* Handles CREATE_IRIS_APP or UPDATE_IRIS_APP action.
|
|
286
|
+
*/
|
|
287
|
+
const handlePublishIrisAppAction = async (instanceUrl, apiKey, action) => {
|
|
288
|
+
// Create zip from the app folder
|
|
289
|
+
const zipBuffer = await createIrisZip(action.appPath, action.slug);
|
|
290
|
+
|
|
291
|
+
// Publish via API with app-name parameter
|
|
292
|
+
const response = await publishApp(
|
|
293
|
+
instanceUrl,
|
|
294
|
+
apiKey,
|
|
295
|
+
zipBuffer,
|
|
296
|
+
`${action.slug}.zip`,
|
|
297
|
+
action.appName
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return response;
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Handles DELETE_IRIS_APP action.
|
|
305
|
+
*/
|
|
306
|
+
const handleDeleteIrisAppAction = async (instanceUrl, apiKey, action) => {
|
|
307
|
+
// Use shared delete utility for consistency
|
|
308
|
+
return await deleteIrisAppFromServer(instanceUrl, apiKey, action.slug, {
|
|
309
|
+
updateCache: true // Cache will be updated by the utility
|
|
310
|
+
});
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Synchronizes class name in content with filename, or vice versa.
|
|
315
|
+
*/
|
|
316
|
+
const syncClassAndFileNames = (action, recordId) => {
|
|
317
|
+
// Only for ActiveClass
|
|
318
|
+
if (action.entity !== 'ActiveClass') return;
|
|
319
|
+
|
|
320
|
+
const filePath = action.filePath;
|
|
321
|
+
// If file was deleted or doesn't exist, skip
|
|
322
|
+
if (!fs.existsSync(filePath)) return;
|
|
323
|
+
|
|
324
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
325
|
+
const filename = path.basename(filePath, path.extname(filePath));
|
|
326
|
+
|
|
327
|
+
// Regex to find class/interface/enum name
|
|
328
|
+
// Matches: public class Name, public interface Name, public enum Name
|
|
329
|
+
// We assume standard formatting
|
|
330
|
+
const classRegex = /public\s+(?:class|interface|enum)\s+(\w+)/;
|
|
331
|
+
const match = content.match(classRegex);
|
|
332
|
+
|
|
333
|
+
if (match) {
|
|
334
|
+
const classNameInContent = match[1];
|
|
335
|
+
|
|
336
|
+
if (classNameInContent !== filename) {
|
|
337
|
+
// Mismatch detected
|
|
338
|
+
|
|
339
|
+
// Case 1: File was renamed (action.renamed is true) -> Update content
|
|
340
|
+
if (action.renamed) {
|
|
341
|
+
const newContent = content.replace(classRegex, (fullMatch, name) => {
|
|
342
|
+
return fullMatch.replace(name, filename);
|
|
343
|
+
});
|
|
344
|
+
fs.writeFileSync(filePath, newContent);
|
|
345
|
+
console.log(chalk.cyan(` ↻ Updated class name in file to: ${filename}`));
|
|
346
|
+
|
|
347
|
+
// Update cache with new content hash
|
|
348
|
+
updateBase(filePath, { Id: recordId, Type: 'ActiveClass' });
|
|
349
|
+
}
|
|
350
|
+
// Case 2: Content was updated (action.renamed is false) -> Rename file
|
|
351
|
+
else {
|
|
352
|
+
// Rename file to match class name
|
|
353
|
+
const dir = path.dirname(filePath);
|
|
354
|
+
const ext = path.extname(filePath);
|
|
355
|
+
const newFilename = `${classNameInContent}${ext}`;
|
|
356
|
+
const newFilePath = path.join(dir, newFilename);
|
|
357
|
+
|
|
358
|
+
if (fs.existsSync(newFilePath)) {
|
|
359
|
+
console.warn(chalk.yellow(` ⚠️ Cannot rename ${filename} to ${classNameInContent}: File already exists.`));
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
try {
|
|
364
|
+
fs.renameSync(filePath, newFilePath);
|
|
365
|
+
console.log(chalk.cyan(` ↻ Renamed file to match class: ${newFilename}`));
|
|
366
|
+
|
|
367
|
+
// Update cache: update the entry for this recordId to point to new path
|
|
368
|
+
updateBase(newFilePath, { Id: recordId, Type: 'ActiveClass' }, newFilePath);
|
|
369
|
+
} catch (err) {
|
|
370
|
+
console.warn(chalk.yellow(` ⚠️ Failed to rename file: ${err.message}`));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
276
377
|
/**
|
|
277
378
|
* Updates cache after successful operations.
|
|
278
379
|
*/
|
|
279
380
|
const updateCacheAfterSuccess = async (action, operationResult) => {
|
|
280
381
|
try {
|
|
382
|
+
// Sync class names/filenames if needed (Bug 2 Fix)
|
|
383
|
+
if (action.action === 'update' && operationResult?.recordId) {
|
|
384
|
+
syncClassAndFileNames(action, operationResult.recordId);
|
|
385
|
+
}
|
|
386
|
+
|
|
281
387
|
switch (action.action) {
|
|
282
388
|
case "create": {
|
|
283
389
|
const createSnapshot = action.fields && Object.values(action.fields)[0]
|
|
@@ -356,6 +462,28 @@ const updateCacheAfterSuccess = async (action, operationResult) => {
|
|
|
356
462
|
}
|
|
357
463
|
break;
|
|
358
464
|
}
|
|
465
|
+
|
|
466
|
+
case "create_iris_app":
|
|
467
|
+
case "update_iris_app": {
|
|
468
|
+
// Update base.json with new/updated Iris app info including content hash
|
|
469
|
+
updateBase(action.appPath, {
|
|
470
|
+
Id: `iris-app:${action.slug}`,
|
|
471
|
+
Type: 'IrisApp',
|
|
472
|
+
folderName: action.slug,
|
|
473
|
+
appName: action.appName,
|
|
474
|
+
modifiedOn: new Date().toISOString(),
|
|
475
|
+
contentHash: action.contentHash // Store hash for change detection
|
|
476
|
+
}, action.appPath);
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
case "delete_iris_app": {
|
|
481
|
+
// Skip if already cleaned from cache during 404 handling
|
|
482
|
+
if (!operationResult?.cleanedFromCache) {
|
|
483
|
+
removeFromBase(`iris-app:${action.slug}`);
|
|
484
|
+
}
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
359
487
|
}
|
|
360
488
|
} catch (error) {
|
|
361
489
|
console.warn(chalk.yellow(`Warning: Failed to update cache for ${action.action}: ${error.message}`));
|
|
@@ -375,8 +503,8 @@ const groupActionsByResource = (actionQueue) => {
|
|
|
375
503
|
for (let i = 0; i < actionQueue.length; i++) {
|
|
376
504
|
const action = { ...actionQueue[i], originalIndex: i };
|
|
377
505
|
|
|
378
|
-
// Asset operations don't need sequencing
|
|
379
|
-
if (['create_static_asset', 'delete_static_asset', 'create_folder', 'delete_folder'].includes(action.action)) {
|
|
506
|
+
// Asset and Iris app operations don't need sequencing
|
|
507
|
+
if (['create_static_asset', 'delete_static_asset', 'create_folder', 'delete_folder', 'create_iris_app', 'update_iris_app', 'delete_iris_app'].includes(action.action)) {
|
|
380
508
|
assets.push(action);
|
|
381
509
|
continue;
|
|
382
510
|
}
|
|
@@ -475,6 +603,13 @@ const executeAction = async (instanceUrl, token, action) => {
|
|
|
475
603
|
case "delete_folder":
|
|
476
604
|
result = await handleDeleteFolderAction(instanceUrl, token, action);
|
|
477
605
|
break;
|
|
606
|
+
case "create_iris_app":
|
|
607
|
+
case "update_iris_app":
|
|
608
|
+
result = await handlePublishIrisAppAction(instanceUrl, token, action);
|
|
609
|
+
break;
|
|
610
|
+
case "delete_iris_app":
|
|
611
|
+
result = await handleDeleteIrisAppAction(instanceUrl, token, action);
|
|
612
|
+
break;
|
|
478
613
|
default:
|
|
479
614
|
throw new Error(`Unknown action: ${action.action}`);
|
|
480
615
|
}
|
|
@@ -518,7 +653,8 @@ const performNetworkRequestSequential = async (actionQueue) => {
|
|
|
518
653
|
console.log();
|
|
519
654
|
console.log(chalk.bgRed.bold.white(' ✖ Operation Failed '));
|
|
520
655
|
console.log(chalk.redBright('─'.repeat(48)));
|
|
521
|
-
|
|
656
|
+
const actionPath = action.filePath || action.folderPath || action.folder || action.appPath || action.slug || 'unknown';
|
|
657
|
+
console.log(chalk.red.bold(`[${i + 1}] ${action.action.toUpperCase()} ${displayName} (${actionPath}):`));
|
|
522
658
|
console.log(formatMultilineError(error.message));
|
|
523
659
|
console.log(chalk.redBright('─'.repeat(48)));
|
|
524
660
|
}
|
|
@@ -624,7 +760,8 @@ const performNetworkRequestParallel = async (actionQueue) => {
|
|
|
624
760
|
console.log();
|
|
625
761
|
console.log(chalk.bgRed.bold.white(' ✖ Operation Failed '));
|
|
626
762
|
console.log(chalk.redBright('─'.repeat(48)));
|
|
627
|
-
|
|
763
|
+
const actionPath = action.filePath || action.folderPath || action.folder || action.appPath || action.slug || 'unknown';
|
|
764
|
+
console.log(chalk.red.bold(`[${index + 1}] ${action.action.toUpperCase()} ${getActionDisplayName(action)} (${actionPath}):`));
|
|
628
765
|
console.log(formatMultilineError(error));
|
|
629
766
|
console.log(chalk.redBright('─'.repeat(48)));
|
|
630
767
|
}
|
|
@@ -721,6 +858,7 @@ export const runPublish = async (options = {}) => {
|
|
|
721
858
|
...c,
|
|
722
859
|
tag: c.recordId,
|
|
723
860
|
filePath: c.filePath || c.lastKnownPath,
|
|
861
|
+
type: c.type || c.Type, // Normalize Type/type property
|
|
724
862
|
}));
|
|
725
863
|
const mapTime = Date.now() - mapStart;
|
|
726
864
|
|
|
@@ -728,11 +866,16 @@ export const runPublish = async (options = {}) => {
|
|
|
728
866
|
progress.completeStep('load', `✓ Loaded ${cachedFiles.length} entries (${loadTime}ms load, ${mapTime}ms map)`);
|
|
729
867
|
}
|
|
730
868
|
|
|
731
|
-
// Step 3: Scan local workspace (excluding Assets
|
|
869
|
+
// Step 3: Scan local workspace (excluding Assets and iris-apps folders)
|
|
732
870
|
if (progress) progress.startStep('scan');
|
|
733
871
|
|
|
734
872
|
const walkStart = Date.now();
|
|
735
|
-
const localPaths = await walkFiles(EXPORT_ROOT, {
|
|
873
|
+
const localPaths = await walkFiles(EXPORT_ROOT, {
|
|
874
|
+
ignore: [
|
|
875
|
+
path.join(EXPORT_ROOT, 'Assets'),
|
|
876
|
+
path.join(EXPORT_ROOT, IRIS_APPS_DIR)
|
|
877
|
+
]
|
|
878
|
+
});
|
|
736
879
|
const walkTime = Date.now() - walkStart;
|
|
737
880
|
|
|
738
881
|
const tagStart = Date.now();
|
|
@@ -902,6 +1045,9 @@ export const runPublish = async (options = {}) => {
|
|
|
902
1045
|
// Skip folders - they're handled separately
|
|
903
1046
|
if (cacheFile?.type === 'Folder') continue;
|
|
904
1047
|
|
|
1048
|
+
// Skip Iris apps - they're handled separately (check both type and ID prefix)
|
|
1049
|
+
if (cacheFile?.type === 'IrisApp' || id.startsWith('iris-app:')) continue;
|
|
1050
|
+
|
|
905
1051
|
// Handle static asset files
|
|
906
1052
|
if (cacheFile?.type === 'File') {
|
|
907
1053
|
// Use lastKnownActualPath which has the correct path (e.g., "src/Assets/...")
|
|
@@ -997,6 +1143,94 @@ export const runPublish = async (options = {}) => {
|
|
|
997
1143
|
progress.completeStep('compare-code', `✓ Compared ${allIdsArray.length} code entities`);
|
|
998
1144
|
}
|
|
999
1145
|
|
|
1146
|
+
// Step 7b: Scan and compare Iris apps
|
|
1147
|
+
const irisAppsPath = path.join(EXPORT_ROOT, IRIS_APPS_DIR);
|
|
1148
|
+
|
|
1149
|
+
// Get cached Iris apps (always check, even if local folder doesn't exist)
|
|
1150
|
+
// Also include entries with iris-app: prefix in case type wasn't properly set
|
|
1151
|
+
const cachedIrisApps = cachedFiles
|
|
1152
|
+
.filter(cf => cf.type === 'IrisApp' || (cf.tag && cf.tag.startsWith('iris-app:')))
|
|
1153
|
+
.map(cf => {
|
|
1154
|
+
// Extract slug from folderName, or from the ID (iris-app:<slug>)
|
|
1155
|
+
const slug = cf.folderName || (cf.tag && cf.tag.startsWith('iris-app:') ? cf.tag.replace('iris-app:', '') : null);
|
|
1156
|
+
return {
|
|
1157
|
+
slug,
|
|
1158
|
+
appName: cf.appName || slug,
|
|
1159
|
+
modifiedOn: cf.modifiedOn,
|
|
1160
|
+
contentHash: cf.contentHash || null // Track content hash for change detection
|
|
1161
|
+
};
|
|
1162
|
+
})
|
|
1163
|
+
.filter(app => app.slug); // Filter out any entries without a valid slug
|
|
1164
|
+
|
|
1165
|
+
// Get local Iris apps (empty if folder doesn't exist)
|
|
1166
|
+
const localIrisApps = fs.existsSync(irisAppsPath)
|
|
1167
|
+
? fs.readdirSync(irisAppsPath, { withFileTypes: true })
|
|
1168
|
+
.filter(d => d.isDirectory())
|
|
1169
|
+
.map(d => d.name)
|
|
1170
|
+
: [];
|
|
1171
|
+
|
|
1172
|
+
const cachedIrisSlugs = new Set(cachedIrisApps.map(a => a.slug));
|
|
1173
|
+
const localIrisSlugs = new Set(localIrisApps);
|
|
1174
|
+
|
|
1175
|
+
// Detect new and modified Iris apps
|
|
1176
|
+
for (const slug of localIrisApps) {
|
|
1177
|
+
const appPath = path.join(irisAppsPath, slug);
|
|
1178
|
+
|
|
1179
|
+
// Validate the app folder has required files
|
|
1180
|
+
const validation = validateIrisAppFolder(appPath);
|
|
1181
|
+
if (!validation.valid) {
|
|
1182
|
+
if (!silent) {
|
|
1183
|
+
console.log(chalk.yellow(`⚠ Skipping invalid Iris app '${slug}': ${validation.errors.join(', ')}`));
|
|
1184
|
+
}
|
|
1185
|
+
continue;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
// Get app name from linked project config (stored globally) or use slug
|
|
1189
|
+
const linkedProjects = getLinkedProjects();
|
|
1190
|
+
const linkedProject = linkedProjects.find(p => p.slug === slug);
|
|
1191
|
+
const appName = linkedProject?.appName || slug;
|
|
1192
|
+
|
|
1193
|
+
// Calculate content hash for change detection
|
|
1194
|
+
const currentHash = hashIrisAppFolder(appPath);
|
|
1195
|
+
|
|
1196
|
+
// Check if this is a new or existing app
|
|
1197
|
+
const isNew = !cachedIrisSlugs.has(slug);
|
|
1198
|
+
|
|
1199
|
+
if (isNew) {
|
|
1200
|
+
actionQueue.push({
|
|
1201
|
+
action: 'create_iris_app',
|
|
1202
|
+
slug,
|
|
1203
|
+
appName,
|
|
1204
|
+
appPath,
|
|
1205
|
+
contentHash: currentHash
|
|
1206
|
+
});
|
|
1207
|
+
} else {
|
|
1208
|
+
// Only update if content has changed
|
|
1209
|
+
const cachedApp = cachedIrisApps.find(a => a.slug === slug);
|
|
1210
|
+
const contentChanged = !cachedApp?.contentHash || cachedApp.contentHash !== currentHash;
|
|
1211
|
+
|
|
1212
|
+
if (contentChanged) {
|
|
1213
|
+
actionQueue.push({
|
|
1214
|
+
action: 'update_iris_app',
|
|
1215
|
+
slug,
|
|
1216
|
+
appName: linkedProject?.appName || cachedApp?.appName || slug,
|
|
1217
|
+
appPath,
|
|
1218
|
+
contentHash: currentHash
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// Detect deleted Iris apps (works even if iris-apps folder doesn't exist)
|
|
1225
|
+
for (const cachedApp of cachedIrisApps) {
|
|
1226
|
+
if (!localIrisSlugs.has(cachedApp.slug)) {
|
|
1227
|
+
actionQueue.push({
|
|
1228
|
+
action: 'delete_iris_app',
|
|
1229
|
+
slug: cachedApp.slug
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1000
1234
|
// Step 8: Handle brand-new, tag-less files
|
|
1001
1235
|
if (progress) progress.startStep('prepare');
|
|
1002
1236
|
|
|
@@ -1077,19 +1311,28 @@ export const runPublish = async (options = {}) => {
|
|
|
1077
1311
|
const num = chalk.green(`[${i + 1}]`);
|
|
1078
1312
|
const act = chalk.yellow(a.action.toUpperCase());
|
|
1079
1313
|
|
|
1080
|
-
let type, displayPath;
|
|
1081
|
-
if (a.
|
|
1314
|
+
let type, displayPath, label;
|
|
1315
|
+
if (a.slug) {
|
|
1316
|
+
// Iris app action
|
|
1317
|
+
type = chalk.cyan(`${a.appName || a.slug}`);
|
|
1318
|
+
displayPath = a.appPath || a.slug;
|
|
1319
|
+
label = "App";
|
|
1320
|
+
} else if (a.folderName) {
|
|
1082
1321
|
type = chalk.cyan(a.folderName);
|
|
1083
1322
|
displayPath = a.folderPath;
|
|
1323
|
+
label = "Folder";
|
|
1084
1324
|
} else if (a.names) {
|
|
1085
1325
|
type = chalk.cyan(a.names.join(", "));
|
|
1086
1326
|
displayPath = a.folder;
|
|
1327
|
+
label = "File";
|
|
1087
1328
|
} else if (a.filePath) {
|
|
1088
1329
|
type = chalk.cyan(a.type || path.basename(a.filePath));
|
|
1089
1330
|
displayPath = a.filePath;
|
|
1331
|
+
label = a.type ? "Type" : "File";
|
|
1090
1332
|
} else {
|
|
1091
1333
|
type = chalk.cyan(a.type || "Unknown");
|
|
1092
1334
|
displayPath = a.folder || "Unknown";
|
|
1335
|
+
label = "File";
|
|
1093
1336
|
}
|
|
1094
1337
|
|
|
1095
1338
|
const idInfo = a.recordId ? ` ${chalk.magenta(a.recordId)}` : "";
|
|
@@ -1097,7 +1340,7 @@ export const runPublish = async (options = {}) => {
|
|
|
1097
1340
|
? ` → ${chalk.gray(a.oldPath)} ${chalk.white("→")} ${chalk.gray(a.filePath)}`
|
|
1098
1341
|
: "";
|
|
1099
1342
|
|
|
1100
|
-
console.log(`${num} ${act} | ${
|
|
1343
|
+
console.log(`${num} ${act} | ${label}: ${type}${idInfo}${renameInfo} (${displayPath})`);
|
|
1101
1344
|
});
|
|
1102
1345
|
|
|
1103
1346
|
console.log(chalk.blue("\n--- Publishing Changes ---"));
|