Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
e547412
test: update to latest version of jest
Benj0s Aug 19, 2025
703f579
feat: adding burstable queue
Benj0s Aug 22, 2025
4c72bb4
feat: adding publishing and publishing job services - wip
Benj0s Aug 22, 2025
92d98e4
feat: first pass content item publish (not tested) wip
deeebeee3 Aug 29, 2025
228f4d9
refactor: update options, command options, modify tests
deeebeee3 Sep 1, 2025
070d854
feat: content item import publish to use new services
deeebeee3 Sep 2, 2025
19084d9
refactor: update return types and publishing service actions - wip
deeebeee3 Sep 5, 2025
a4728ca
feat: pass headers via custom dc http client to match sdk
Benj0s Sep 5, 2025
8ca20d1
test: updating import tests to use new publishing service
Benj0s Sep 5, 2025
29921b3
feat: removing redundant publishing flags
Benj0s Sep 5, 2025
49a1fa2
test: updating publish tests to use new publishing service
deeebeee3 Sep 5, 2025
c5bc0bf
feat: add publish progress and only log to log file
Benj0s Sep 8, 2025
5c768d9
feat: allow publish checks to occur without user input
Benj0s Sep 8, 2025
e0c13b7
test: adding tests for publishing services
deeebeee3 Sep 9, 2025
b637988
fix: improve logging when publishing content
Benj0s Sep 15, 2025
2f0caba
fix: moving publish complete log to correct scope
Benj0s Sep 15, 2025
3286ecd
feat: add min time to burstable queue to spread load
Benj0s Sep 15, 2025
0b893cb
fix: lowering min time to make sure we use the full burst interval re…
Benj0s Sep 16, 2025
056743b
feat: add unpublish command
deeebeee3 Sep 17, 2025
4b47d06
Merge branch 'master' into feature/publish-queue-improvements
Benj0s Sep 23, 2025
d76d481
Merge branch 'feature/publish-queue-improvements' into feature/unpublish
deeebeee3 Sep 23, 2025
149b812
fix: ensure action gets called
deeebeee3 Sep 23, 2025
d5c6104
refactor: unpublish method, add tests to cover all statuses
deeebeee3 Sep 23, 2025
98ccb2d
fix: prevent unpublish for item with status NONE
deeebeee3 Sep 26, 2025
b9a17b9
fix: remove unpublish children logic
deeebeee3 Sep 29, 2025
28f5311
fix: log immediate children
deeebeee3 Sep 30, 2025
4fe256a
fix: reintroduce publish content tree child item filtering
Benj0s Oct 6, 2025
d3b5c3a
Merge branch 'feature/publish-queue-improvements' into feature/unpublish
Benj0s Oct 6, 2025
11cb298
feat: adding commands for content sync jobs - wip
Benj0s Oct 7, 2025
1491b6e
feat: making content item fetch reusable
Benj0s Oct 8, 2025
0cf11b1
feat: sync test coverage and minor fixes
Benj0s Oct 9, 2025
41f437e
feat: update create sync request model and clearer dedup function name
Benj0s Oct 10, 2025
6d9fec2
feat: bump to latest management sdk
Benj0s Oct 15, 2025
f2bd9d1
Merge branch 'feature/publish-queue-improvements' into feature/unpublish
Benj0s Oct 15, 2025
3a438c9
Merge branch 'feature/unpublish' into feature/content-sync
Benj0s Oct 16, 2025
66ee633
Merge branch 'master' into feature/publish-queue-improvements
Benj0s Oct 20, 2025
bcfb285
Merge branch 'feature/publish-queue-improvements' into feature/unpublish
Benj0s Oct 20, 2025
a04791d
Merge branch 'feature/unpublish' into feature/content-sync
Benj0s Oct 20, 2025
288d292
fix: pin specific jest dependency versions
Benj0s Oct 20, 2025
a4447a3
Merge branch 'feature/publish-queue-improvements' into feature/unpublish
Benj0s Oct 20, 2025
e6af255
Merge branch 'feature/unpublish' into feature/content-sync
Benj0s Oct 20, 2025
161c399
Merge branch 'master' into feature/content-sync
Benj0s Oct 21, 2025
e995cc2
Merge branch 'master' into feature/content-sync
Benj0s Oct 24, 2025
d347c4b
fix: change missing content item behaviour to match similar commands
Benj0s Oct 24, 2025
b9ee4b6
Merge branch 'feature/content-sync' of github.com:amplience/dc-cli in…
Benj0s Oct 24, 2025
f60e30c
fix: only display missing content message when id arg used
Benj0s Oct 28, 2025
66212ca
feat: use common content item fetch logic for publish command
Benj0s Oct 28, 2025
6578b04
fix: make sure sync command exits early when no content found
Benj0s Oct 28, 2025
126c270
Merge branch 'feature/content-sync' into feature/content-item-command…
Benj0s Oct 28, 2025
cdd04a0
feat: update unpublish command to use shared content item fetch
Benj0s Oct 28, 2025
163cccb
feat: update archive to use shared content item fetch helpers
Benj0s Oct 31, 2025
3d961d7
docs: adding content item sync documentation
Benj0s Oct 31, 2025
c1ccaa2
feat: update unarchive to use reusable get content and refactor inter…
Benj0s Oct 31, 2025
0e9444c
docs: content item sync examples with --destinationHubId
neilmistryamplience Nov 5, 2025
93576c2
chore: bumping management sdk to latest version
Benj0s Nov 5, 2025
6aa14b0
Merge branch 'feature/content-sync' into feature/content-item-command…
Benj0s Nov 5, 2025
e20728e
fix: removing job list command
Benj0s Nov 6, 2025
26fa92d
Merge branch 'feature/content-sync' into feature/content-item-command…
Benj0s Nov 6, 2025
dc3cb7f
Merge branch 'master' into feature/content-item-command-improvements
Benj0s Nov 10, 2025
9e82c11
Merge branch 'master' into feature/content-item-command-improvements
Benj0s Nov 12, 2025
9982bc4
Merge branch 'master' into feature/content-item-command-improvements
Benj0s Nov 14, 2025
710f53d
test: increasing timeout interval to avoid race condition
Benj0s Nov 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 77 additions & 146 deletions src/commands/content-item/archive.spec.ts

Large diffs are not rendered by default.

177 changes: 56 additions & 121 deletions src/commands/content-item/archive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import dynamicContentClientFactory from '../../services/dynamic-content-client-f
import { ArchiveLog } from '../../common/archive/archive-log';
import { confirmAllContent } from '../../common/content-item/confirm-all-content';
import ArchiveOptions from '../../common/archive/archive-options';
import { ContentItem, DynamicContent, Status } from 'dc-management-sdk-js';
import { ContentItem, Status } from 'dc-management-sdk-js';
import { getDefaultLogPath, createLog } from '../../common/log-helpers';
import { FileLog } from '../../common/file-log';
import { withOldFilters } from '../../common/filter/facet';
import { getContent } from '../../common/filter/fetch-content';
import { progressBar } from '../../common/progress-bar/progress-bar';
import { getContentByIds } from '../../common/content-item/get-content-items-by-ids';

export const command = 'archive [id]';

Expand Down Expand Up @@ -86,108 +87,20 @@ export const builder = (yargs: Argv): void => {
});
};

export const getContentItems = async ({
client,
id,
hubId,
repoId,
folderId,
revertLog,
facet
}: {
client: DynamicContent;
id?: string | string[];
hubId: string;
repoId?: string | string[];
folderId?: string | string[];
revertLog?: string;
facet?: string;
}): Promise<{ contentItems: ContentItem[]; missingContent: boolean }> => {
try {
let contentItems: ContentItem[] = [];

if (revertLog != null) {
const log = await new ArchiveLog().loadFromFile(revertLog);
id = log.getData('UNARCHIVE');
}

if (id != null) {
const itemIds = Array.isArray(id) ? id : [id];
const items: ContentItem[] = [];

for (const id of itemIds) {
try {
items.push(await client.contentItems.get(id));
} catch {
// Missing item.
}
}

contentItems.push(...items.filter(item => item.status === Status.ACTIVE));

return {
contentItems,
missingContent: contentItems.length != itemIds.length
};
}

const hub = await client.hubs.get(hubId);

contentItems = await getContent(client, hub, facet, { repoId, folderId, status: Status.ACTIVE, enrichItems: true });

return { contentItems, missingContent: false };
} catch (err) {
console.log(err);

return {
contentItems: [],
missingContent: false
};
}
};

export const processItems = async ({
const processItems = async ({
contentItems,
force,
silent,
logFile,
allContent,
missingContent,
log,
ignoreError,
ignoreSchemaValidation
}: {
contentItems: ContentItem[];
force?: boolean;
silent?: boolean;
logFile: FileLog;
allContent: boolean;
missingContent: boolean;
log: FileLog;
ignoreError?: boolean;
ignoreSchemaValidation?: boolean;
}): Promise<void> => {
if (contentItems.length == 0) {
console.log('Nothing found to archive, aborting.');
return;
}

console.log('The following content items will be archived:');
contentItems.forEach((contentItem: ContentItem) => {
console.log(` ${contentItem.label} (${contentItem.id})`);
});
console.log(`Total: ${contentItems.length}`);

if (!force) {
const yes = await confirmAllContent('archive', 'content item', allContent, missingContent);
if (!yes) {
return;
}
}

const log = logFile.open();

}): Promise<{ failedArchives: ContentItem[] }> => {
const progress = progressBar(contentItems.length, 0, { title: 'Archiving content items' });
const failedArchives = [];

let successCount = 0;
for (let i = 0; i < contentItems.length; i++) {
try {
const deliveryKey = contentItems[i].body._meta.deliveryKey;
Expand All @@ -206,74 +119,96 @@ export const processItems = async ({
await contentItems[i].related.archive();
progress.increment();
log.addAction('ARCHIVE', `${args}`);
successCount++;
} catch (e) {
failedArchives.push(contentItems[i]);
progress.increment();
log.addComment(`ARCHIVE FAILED: ${contentItems[i].id}`);
log.addComment(e.toString());

if (ignoreError) {
log.warn(`Failed to archive ${contentItems[i].label} (${contentItems[i].id}), continuing.`, e);
log.warn(`\nFailed to archive ${contentItems[i].label} (${contentItems[i].id}), continuing.`, e);
} else {
progress.stop();
log.error(`Failed to archive ${contentItems[i].label} (${contentItems[i].id}), aborting.`, e);
log.error(`\nFailed to archive ${contentItems[i].label} (${contentItems[i].id}), aborting.`, e);
break;
}
}
}

progress.stop();

await log.close(!silent);

console.log(`Archived ${successCount} content items.`);
return { failedArchives };
};

export const handler = async (argv: Arguments<ArchiveOptions & ConfigurationParameters>): Promise<void> => {
const { id, logFile, force, silent, ignoreError, hubId, revertLog, repoId, folderId, ignoreSchemaValidation } = argv;
const log = logFile.open();
const client = dynamicContentClientFactory(argv);

const facet = withOldFilters(argv.facet, argv);

const allContent = !id && !facet && !revertLog && !folderId && !repoId;

if (repoId && id) {
console.log('ID of content item is specified, ignoring repository ID');
log.appendLine('ID of content item is specified, ignoring repository ID');
}

if (id && facet) {
console.log('Please specify either a facet or an ID - not both.');
log.appendLine('Please specify either a facet or an ID - not both.');
return;
}

if (repoId && folderId) {
console.log('Folder is specified, ignoring repository ID');
log.appendLine('Folder is specified, ignoring repository ID');
}

if (allContent) {
console.log('No filter was given, archiving all content');
log.appendLine('No filter was given, archiving all content');
}

const { contentItems, missingContent } = await getContentItems({
client,
id,
hubId,
repoId,
folderId,
revertLog,
facet
});
let ids: string[] = [];

if (id) {
ids = Array.isArray(id) ? id : [id];
}

await processItems({
if (revertLog) {
const log = await new ArchiveLog().loadFromFile(revertLog);
ids = log.getData('UNARCHIVE');
}

const hub = await client.hubs.get(hubId);
const contentItems = ids.length
? (await getContentByIds(client, ids)).filter(item => item.status === Status.ACTIVE)
: await getContent(client, hub, facet, { repoId, folderId, status: Status.ACTIVE, enrichItems: true });

if (!contentItems.length) {
log.appendLine('Nothing found to archive, aborting');
return;
}

const missingContentItems = ids.length > 0 ? Boolean(ids.length !== contentItems.length) : false;
log.appendLine(`Found ${contentItems.length} content items to archive`);

if (!force) {
const yes = await confirmAllContent('archive', 'content item', allContent, missingContentItems);
if (!yes) {
return;
}
}

const { failedArchives } = await processItems({
contentItems,
force,
silent,
logFile,
allContent,
missingContent,
log,
ignoreError,
ignoreSchemaValidation
});

const failedArchiveMsg = failedArchives.length
? `with ${failedArchives.length} failed archives - check logs for details`
: ``;

log.appendLine(`Archived content items ${failedArchiveMsg}`);

await log.close(!silent);
};

// log format:
Expand Down
Loading
Loading