UNPKG

@agility/cli

Version:

Agility CLI for working with your content. (Public Beta)

433 lines 29.1 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.processPage = processPage; var ansi_colors_1 = __importDefault(require("ansi-colors")); var content_item_mapper_1 = require("lib/mappers/content-item-mapper"); var template_mapper_1 = require("lib/mappers/template-mapper"); // Internal helper function to process a single page var translate_zone_names_1 = require("./translate-zone-names"); var find_page_in_other_locale_1 = require("./find-page-in-other-locale"); function processPage(_a) { return __awaiter(this, arguments, void 0, function (_b) { var existingPage, channelID, templateMapper, targetTemplate, templateRef, pageMapping, mappingToOtherLocale, sitemap, websiteChannel, hasTargetChanged, hasSourceChanged, isConflict, updateRequired, createRequired, pageTypeDisplay, sourceUrl, targetUrl, sourceZones, mappedZones, contentIdsToValidate, _i, _c, _d, zoneName, zoneModules, _e, zoneModules_1, module_1, sourceContentId, contentMapper_1, _f, _g, _h, zoneName, zoneModules, newZoneContent, _j, zoneModules_2, module_2, newModule, sourceContentId, targetContentID, targetContentId, mappingResults_1, foundMappings_1, missingMappings_1, totalModules, isLegitimateEmptyPage, originalZones, originalModuleCount, _k, _l, _m, zoneName, zoneModules, formattedZones, pageTitle, pageJSON, pageCopy, payload, parentIDArg, mapping, placeBeforeIDArg, mapping, pageIDInOtherLocale, otherLocale, savePageResponse, finalContentIds_1, batchID, _o, pollBatchUntilComplete, extractBatchResults, completedBatch, _p, batchSuccessItems, batchFailedItems, actualPageID, savedPageVersionID, createdPageData, pageTypeDisplay_1, error_1; var _q, _r; var channel = _b.channel, page = _b.page, sourceGuid = _b.sourceGuid, targetGuid = _b.targetGuid, locale = _b.locale, apiClient = _b.apiClient, _s = _b.overwrite, overwrite = _s === void 0 ? false : _s, _t = _b.insertBeforePageId, insertBeforePageId = _t === void 0 ? null : _t, pageMapper = _b.pageMapper, parentPageID = _b.parentPageID, logger = _b.logger; return __generator(this, function (_u) { switch (_u.label) { case 0: existingPage = null; channelID = -1; templateMapper = new template_mapper_1.TemplateMapper(sourceGuid, targetGuid); _u.label = 1; case 1: _u.trys.push([1, 10, , 11]); targetTemplate = null; // Only try to find template mapping for non-folder pages if (page.pageType !== "folder" && page.templateName) { templateRef = templateMapper.getTemplateMappingByPageTemplateName(page.templateName, 'source'); if (!templateRef) { logger.page.error(page, "Missing page template ".concat(page.templateName, " in source data, skipping"), locale, channel, targetGuid); return [2 /*return*/, "skip"]; } targetTemplate = templateMapper.getMappedEntity(templateRef, 'target'); } pageMapping = pageMapper.getPageMapping(page, 'source'); existingPage = pageMapper.getMappedEntity(pageMapping, 'target'); mappingToOtherLocale = null; if (!!existingPage) return [3 /*break*/, 3]; return [4 /*yield*/, (0, find_page_in_other_locale_1.findPageInOtherLocale)({ sourcePageID: page.pageID, locale: locale, sourceGuid: sourceGuid, targetGuid: targetGuid })]; case 2: //check the other locales to see if this page has been mapped in another locale mappingToOtherLocale = _u.sent(); _u.label = 3; case 3: return [4 /*yield*/, apiClient.pageMethods.getSitemap(targetGuid, locale)]; case 4: sitemap = _u.sent(); websiteChannel = sitemap === null || sitemap === void 0 ? void 0 : sitemap.find(function (channelObj) { return channelObj.name.toLowerCase() === channel.toLowerCase(); }); if (websiteChannel) { channelID = websiteChannel.digitalChannelID; } else { channelID = ((_q = sitemap === null || sitemap === void 0 ? void 0 : sitemap[0]) === null || _q === void 0 ? void 0 : _q.digitalChannelID) || 1; // Fallback to first channel or default } hasTargetChanged = pageMapper.hasTargetChanged(existingPage); hasSourceChanged = pageMapper.hasSourceChanged(page); isConflict = hasTargetChanged && hasSourceChanged; updateRequired = (hasSourceChanged && !isConflict) || overwrite; createRequired = !existingPage; pageTypeDisplay = { static: "Page", link: "Link", folder: "Folder", }[page.pageType] || page.pageType; if (isConflict) { sourceUrl = "https://app.agilitycms.com/instance/".concat(sourceGuid, "/").concat(locale, "/pages/").concat(page.pageID); targetUrl = "https://app.agilitycms.com/instance/".concat(targetGuid, "/").concat(locale, "/pages/").concat(existingPage.pageID); console.warn("\u26A0\uFE0F Conflict detected ".concat(pageTypeDisplay, " ").concat(ansi_colors_1.default.underline(page.name), " ").concat(ansi_colors_1.default.bold.grey("changes detected in both source and target"), ". Please resolve manually.")); console.warn(" - Source: ".concat(sourceUrl)); console.warn(" - Target: ".concat(targetUrl)); } else if (createRequired) { //CREATE NEW PAGE - nothing to do here yet... } else if (!updateRequired) { // Add to reference mapper for future lookups if (existingPage) { pageMapper.addMapping(page, existingPage); } logger.page.skipped(page, "up to date, skipping", locale, channel, targetGuid); return [2 /*return*/, "skip"]; // Skip processing - page already exists } sourceZones = page.zones ? __assign({}, page.zones) : {}; mappedZones = (0, translate_zone_names_1.translateZoneNames)(sourceZones, targetTemplate); contentIdsToValidate = []; for (_i = 0, _c = Object.entries(mappedZones); _i < _c.length; _i++) { _d = _c[_i], zoneName = _d[0], zoneModules = _d[1]; if (Array.isArray(zoneModules)) { for (_e = 0, zoneModules_1 = zoneModules; _e < zoneModules_1.length; _e++) { module_1 = zoneModules_1[_e]; if (module_1.item && typeof module_1.item === "object") { sourceContentId = module_1.item.contentid || module_1.item.contentId; if (sourceContentId && sourceContentId > 0) { contentIdsToValidate.push(sourceContentId); } } } } } contentMapper_1 = new content_item_mapper_1.ContentItemMapper(sourceGuid, targetGuid, locale); for (_f = 0, _g = Object.entries(mappedZones); _f < _g.length; _f++) { _h = _g[_f], zoneName = _h[0], zoneModules = _h[1]; newZoneContent = []; if (Array.isArray(zoneModules)) { for (_j = 0, zoneModules_2 = zoneModules; _j < zoneModules_2.length; _j++) { module_2 = zoneModules_2[_j]; newModule = __assign({}, module_2); // Check if module has content item reference if (module_2.item && typeof module_2.item === "object") { sourceContentId = module_2.item.contentid || module_2.item.contentId; if (sourceContentId && sourceContentId > 0) { targetContentID = contentMapper_1.getContentItemMappingByContentID(sourceContentId, 'source').targetContentID; if (targetContentID) { targetContentId = targetContentID; newModule.item = __assign(__assign({}, module_2.item), { contentid: targetContentId, fulllist: module_2.item.fulllist }); // Remove contentId field to avoid confusion delete newModule.item.contentId; newZoneContent.push(newModule); } else { // Content mapping failed - log detailed debug info for troubleshooting console.error("\u274C No content mapping found for ".concat(module_2.module, ": contentID ").concat(sourceContentId, " in page ").concat(page.name)); // const contentMappings = contentMapper.getRecordsByType("content"); // console.log("Page", JSON.stringify(page, null, 2)); // console.error(`Total content mappings available: ${contentMappings.length}`); // const allContentRecords = pageMapper.getRecordsByType("content"); // const matchingRecord = allContentRecords.find((r) => r.source.contentID === sourceContentId); // if (matchingRecord) { // console.error(`Found matching source record but issue with target:`, { // sourceID: matchingRecord.source.contentID, // targetID: matchingRecord.target?.contentID, // hasTarget: !!matchingRecord.target, // }); // } else { // console.error(`No record found with source contentID: ${sourceContentId}`); // } } } else { // Module without content reference - keep it newZoneContent.push(newModule); } } else { // Module without content reference - keep it newZoneContent.push(newModule); } } } mappedZones[zoneName] = newZoneContent; } // Content mapping validation - check which mappings were successful if (contentIdsToValidate.length > 0) { mappingResults_1 = {}; foundMappings_1 = 0; missingMappings_1 = 0; contentIdsToValidate.forEach(function (sourceContentId) { var targetContentID = contentMapper_1.getContentItemMappingByContentID(sourceContentId, 'source').targetContentID; if (targetContentID) { mappingResults_1[sourceContentId] = { found: true, targetId: targetContentID, }; foundMappings_1++; } else { mappingResults_1[sourceContentId] = { found: false, error: targetContentID ? "Invalid target ID" : "No mapping found", }; missingMappings_1++; } }); if (missingMappings_1 > 0) { console.error(ansi_colors_1.default.bgRed("\u2717 Page \"".concat(page.name, "\" failed - ").concat(missingMappings_1, "/").concat(contentIdsToValidate.length, " missing content mappings"))); return [2 /*return*/, "failure"]; } } totalModules = Object.values(mappedZones).reduce(function (sum, zone) { return sum + (Array.isArray(zone) ? zone.length : 0); }, 0); isLegitimateEmptyPage = function (page) { // Folder pages don't have content modules if (page.pageType === "folder") return true; // Link pages don't have content modules - they redirect to other URLs/pages/files if (page.pageType === "link") return true; // Dynamic pages don't have modules in zones - their content comes from dynamic containers // Check for dynamic page indicators var pageAny = page; if (pageAny.dynamic && pageAny.dynamic.referenceName) return true; if (pageAny.dynamicPageContentViewReferenceName) return true; // Pages with redirect URLs are link pages (even if pageType isn't explicitly 'link') // Check for common redirect URL properties (using 'any' type to access properties safely) if (pageAny.redirectUrl && pageAny.redirectUrl.trim()) return true; if (pageAny.redirect && pageAny.redirect.url && pageAny.redirect.url.trim()) return true; // Pages that link to files or other pages don't need modules // Using safe property access since these may not be in the type definition if (pageAny.linkToFileID && pageAny.linkToFileID > 0) return true; if (pageAny.linkToPageID && pageAny.linkToPageID > 0) return true; if (pageAny.linkToFile && pageAny.linkToFile > 0) return true; if (pageAny.linkToPage && pageAny.linkToPage > 0) return true; return false; }; // Check if page has any content left after filtering if (totalModules === 0) { originalZones = page.zones || {}; originalModuleCount = 0; for (_k = 0, _l = Object.entries(originalZones); _k < _l.length; _k++) { _m = _l[_k], zoneName = _m[0], zoneModules = _m[1]; if (Array.isArray(zoneModules)) { originalModuleCount += zoneModules.length; } } // If the page originally had modules but now has none, that's a problem // If it never had modules, that's fine (folder pages, etc.) if (originalModuleCount > 0 && !existingPage && !isLegitimateEmptyPage(page)) { console.error("\u2717 Page \"".concat(page.name, "\" lost all ").concat(originalModuleCount, " modules during content mapping")); return [2 /*return*/, "failure"]; } } formattedZones = mappedZones && typeof mappedZones === "object" ? mappedZones : {}; pageTitle = page.title || page.menuText || page.name || "Untitled Page"; pageJSON = JSON.stringify(page, null, 2); pageCopy = JSON.parse(pageJSON); payload = __assign(__assign({}, pageCopy), { pageID: existingPage ? existingPage.pageID : -1, title: pageTitle, channelID: channelID, zones: formattedZones, // CRITICAL: Include path field from sitemap enrichment (API bug: target sitemap returns null paths) path: page.path || "" }); parentIDArg = -1; if (parentPageID && parentPageID > 0) { mapping = pageMapper.getPageMappingByPageID(parentPageID, 'source'); if (((mapping === null || mapping === void 0 ? void 0 : mapping.targetPageID) || 0) > 0) { parentIDArg = mapping.targetPageID; payload.parentPageID = mapping.targetPageID; } else { parentIDArg = -1; payload.parentPageID = -1; // No parent } } else { payload.parentPageID = -1; // Ensure no parent } placeBeforeIDArg = -1; if (insertBeforePageId && insertBeforePageId > 0) { mapping = pageMapper.getPageMappingByPageID(insertBeforePageId, 'source'); if (((mapping === null || mapping === void 0 ? void 0 : mapping.targetPageID) || 0) > 0) { placeBeforeIDArg = mapping.targetPageID; } } pageIDInOtherLocale = mappingToOtherLocale ? mappingToOtherLocale.PageIDOtherLanguage : -1; otherLocale = mappingToOtherLocale ? mappingToOtherLocale.OtherLanguageCode : null; return [4 /*yield*/, apiClient.pageMethods.savePage(payload, targetGuid, locale, parentIDArg, placeBeforeIDArg, true, pageIDInOtherLocale, otherLocale)]; case 5: savePageResponse = _u.sent(); if (!(Array.isArray(savePageResponse) && savePageResponse.length > 0)) return [3 /*break*/, 8]; finalContentIds_1 = []; Object.values(payload.zones || {}).forEach(function (zone) { if (Array.isArray(zone)) { zone.forEach(function (module) { var _a; if ((_a = module.item) === null || _a === void 0 ? void 0 : _a.contentid) { finalContentIds_1.push(module.item.contentid); } }); } }); batchID = savePageResponse[0]; return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("../batch-polling")); })]; case 6: _o = _u.sent(), pollBatchUntilComplete = _o.pollBatchUntilComplete, extractBatchResults = _o.extractBatchResults; return [4 /*yield*/, pollBatchUntilComplete(apiClient, batchID, targetGuid, [payload], // Pass payload for FIFO error matching 300, // maxAttempts 2000, // intervalMs "Page" // batchType )]; case 7: completedBatch = _u.sent(); _p = extractBatchResults(completedBatch, [page]), batchSuccessItems = _p.successfulItems, batchFailedItems = _p.failedItems; actualPageID = -1; savedPageVersionID = -1; if (batchSuccessItems.length > 0) { //grab the save page info form the batch success items actualPageID = batchSuccessItems[0].newId; savedPageVersionID = ((_r = batchSuccessItems[0].newItem) === null || _r === void 0 ? void 0 : _r.processedItemVersionID) || -1; } else if (batchFailedItems.length > 0) { logger.page.error(page, "\u2717 Page ".concat(page.name, " batch failed: ").concat(batchFailedItems[0].error), locale, channel, targetGuid); } if (actualPageID > 0) { createdPageData = __assign(__assign({}, payload), { pageID: actualPageID }); if (savedPageVersionID > 0) { // Set version ID if available createdPageData.properties.versionID = savedPageVersionID; // Set version ID from batch result } pageMapper.addMapping(page, createdPageData); // Use original page for source key pageTypeDisplay_1 = { static: "Page", link: "Link", folder: "Folder", }[page.pageType] || page.pageType; if (existingPage) { if (overwrite) { logger.page.updated(page, "updated", locale, channel, targetGuid); } else { logger.page.updated(page, "updated", locale, channel, targetGuid); } } else { logger.page.created(page, "created", locale, channel, targetGuid); } return [2 /*return*/, "success"]; // Success } else { // Show errorData if available, otherwise generic failure if (completedBatch.errorData && completedBatch.errorData.trim()) { logger.page.error(page, "\u2717 Page \"".concat(page.name, "\" failed - ").concat(completedBatch.errorData, ", locale:").concat(locale), locale, channel, targetGuid); } else { logger.page.error(page, "\u2717 Page \"".concat(page.name, "\" failed - invalid page ID: ").concat(actualPageID, ", locale:").concat(locale), locale, channel, targetGuid); } return [2 /*return*/, "failure"]; } return [3 /*break*/, 9]; case 8: logger.page.error(page, "\u2717 Page \"".concat(page.name, "\" failed in locale:").concat(locale, " - unexpected response format"), locale, channel, targetGuid); return [2 /*return*/, "failure"]; // Failure case 9: return [3 /*break*/, 11]; case 10: error_1 = _u.sent(); logger.page.error(page, "\u2717 Page \"".concat(page.name, "\" failed in locale:").concat(locale, " - ").concat(error_1.message), locale, channel, targetGuid); return [2 /*return*/, "failure"]; // Failure case 11: return [2 /*return*/]; } }); }); } //# sourceMappingURL=process-page.js.map