From 7598aaf41679abe7283d5db703f31e4ace0a8720 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 21 May 2026 12:30:56 +0530 Subject: [PATCH 01/44] feat: add support for asset scaning in import command --- .talismanrc | 18 ++---------------- .../src/import/module-importer.ts | 16 ++++++++++++++++ .../src/import/modules/assets.ts | 7 +++++++ .../src/types/import-config.ts | 1 + 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/.talismanrc b/.talismanrc index 16286bff7..1999c2dd4 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,18 +1,4 @@ fileignoreconfig: - - filename: pnpm-lock.yaml - checksum: 264c0294416c2aa2028c8283831aa7ed17d63e8c69553a7b2b9774336bc0811f - - filename: packages/contentstack-bootstrap/test/bootstrap.test.js - checksum: 37b502482fc32831c39091dd1755e8b0a9f6f8bac89e5eb9d397c6af1f213d83 - - filename: packages/contentstack-bootstrap/test/utils.test.js - checksum: e0ca2eb58ab1c3ac3b4d9c14a17bb8f4788678074dd65f6acc128a8a8f51997f - - filename: packages/contentstack-export-to-csv/test/unit/base-command.test.ts - checksum: 4c2befce053135453c1db31f21351bf3f797ff2f15723ca52e183ed6ed9e48e4 - - filename: packages/contentstack-export-to-csv/test/unit/utils/teams-export.functional.test.ts - checksum: 17cdae91c22a935309bf4514b6616f1aea91fd0166fede182e673ade43667a36 - - filename: packages/contentstack-export-to-csv/test/unit/utils/interactive.test.ts - checksum: 72c1e719e5c51a42debc817a5fe5bb1adee63b2d823df2e9ee36d0b970db7886 - - filename: packages/contentstack-export-to-csv/test/unit/utils/api-client.functional.test.ts - checksum: 6d6638919ef7260f642d32cf730e2654d159d2d3582714fb2d7a9c209b9c6eeb - - filename: packages/contentstack-export-to-csv/test/unit/commands/export-to-csv.test.ts - checksum: 9621a9d013796e99a25e894404c4d7c6799bd33bde77852f09d5e32b4d1c1c49 + - filename: packages/contentstack-import/src/import/modules/assets.ts + checksum: 8d6d1cadf9178f79aeae508f157c019342e1899f9c3f8116bd25b4ec27e593be version: '1.0' diff --git a/packages/contentstack-import/src/import/module-importer.ts b/packages/contentstack-import/src/import/module-importer.ts index 930350a18..109c54160 100755 --- a/packages/contentstack-import/src/import/module-importer.ts +++ b/packages/contentstack-import/src/import/module-importer.ts @@ -26,6 +26,12 @@ class ModuleImporter { const stackDetails: Record = await this.stackAPIClient.fetch(); this.importConfig.stackName = stackDetails.name as string; this.importConfig.org_uid = stackDetails.org_uid as string; + + const assetScanningEnabled = await this.detectAssetScanning(this.importConfig.org_uid); + if (assetScanningEnabled) { + this.importConfig.assetScanningEnabled = true; + this.importConfig.skipAssetsPublish = true; + } } await this.resolveImportPath(); @@ -194,6 +200,16 @@ class ModuleImporter { log.error(`Audit failed with following error. ${error}`, this.importConfig.context); } } + + private async detectAssetScanning(orgUid: string): Promise { + try { + const orgDetails = await this.managementAPIClient.organization(orgUid).fetch({ include_plan: true }); + const features: Array<{ uid: string; enabled?: boolean }> = orgDetails?.plan?.features || []; + return features.some((f) => (f.uid === 'assetsScan' || f.uid === 'amAssetsScan') && f.enabled === true); + } catch { + return false; + } + } } export default ModuleImporter; diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index c65345d91..c2ab64bc9 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -197,6 +197,13 @@ export default class ImportAssets extends BaseClass { this.completeProgress(true); log.success('Assets imported successfully!', this.importConfig.context); + + if (this.importConfig.assetScanningEnabled) { + log.info('ℹ Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); + log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); + log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key ', this.importConfig.context); + } } catch (error) { this.completeProgress(false, error?.message || 'Asset import failed'); handleAndLogError(error, { ...this.importConfig.context }); diff --git a/packages/contentstack-import/src/types/import-config.ts b/packages/contentstack-import/src/types/import-config.ts index 1587a360e..60fa64389 100644 --- a/packages/contentstack-import/src/types/import-config.ts +++ b/packages/contentstack-import/src/types/import-config.ts @@ -14,6 +14,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig { authenticationMethod?: string; skipAssetsPublish?: boolean; skipEntriesPublish?: boolean; + assetScanningEnabled?: boolean; cliLogsPath: string; canCreatePrivateApp: boolean; contentDir: string; From 09f2db8da97dbb7d7977736e52b49ac6d10f6f36 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 21 May 2026 12:34:32 +0530 Subject: [PATCH 02/44] chore: update talisman file --- .talismanrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.talismanrc b/.talismanrc index 1999c2dd4..88cd645b3 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,4 @@ fileignoreconfig: - - filename: packages/contentstack-import/src/import/modules/assets.ts +- filename: packages/contentstack-import/src/import/modules/assets.ts checksum: 8d6d1cadf9178f79aeae508f157c019342e1899f9c3f8116bd25b4ec27e593be version: '1.0' From d94825f0f306dd9b071a20d33c575e918ffb16c0 Mon Sep 17 00:00:00 2001 From: Naman Dembla Date: Thu, 28 May 2026 14:29:35 +0530 Subject: [PATCH 03/44] chore: update log message --- packages/contentstack-import/src/import/modules/assets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index c2ab64bc9..abf864637 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -199,7 +199,7 @@ export default class ImportAssets extends BaseClass { log.success('Assets imported successfully!', this.importConfig.context); if (this.importConfig.assetScanningEnabled) { - log.info('ℹ Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key ', this.importConfig.context); From be27c50f3f87fbdc6083977cc9ac8a699552a285 Mon Sep 17 00:00:00 2001 From: Naman Dembla Date: Thu, 28 May 2026 14:30:28 +0530 Subject: [PATCH 04/44] chore: update log message spacing --- packages/contentstack-import/src/import/modules/assets.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index abf864637..fbce6e743 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -199,7 +199,7 @@ export default class ImportAssets extends BaseClass { log.success('Assets imported successfully!', this.importConfig.context); if (this.importConfig.assetScanningEnabled) { - log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key ', this.importConfig.context); From 661e8e198e3fe7f9b385be550c6ae223fda92726 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 29 May 2026 14:13:10 +0530 Subject: [PATCH 05/44] feat: feat: add asset scanning support --- .talismanrc | 4 + .../src/base-bulk-command.ts | 12 +- .../src/commands/cm/stacks/bulk-assets.ts | 284 +++++++++++++++++- .../src/interfaces/index.ts | 8 +- .../src/messages/index.ts | 19 ++ .../src/services/asset-service.ts | 49 ++- .../src/services/bulk-operation-service.ts | 60 +++- .../src/utils/batch-queue-handler.ts | 14 +- .../src/utils/config-builder.ts | 70 +++-- .../src/utils/data-dir-asset-fetcher.ts | 114 +++++++ .../src/utils/helpers.ts | 36 ++- .../src/utils/index.ts | 6 + .../src/utils/item-fetcher.ts | 1 + 13 files changed, 611 insertions(+), 66 deletions(-) create mode 100644 packages/contentstack-bulk-operations/src/utils/data-dir-asset-fetcher.ts diff --git a/.talismanrc b/.talismanrc index 3db7ed059..d07a9f629 100644 --- a/.talismanrc +++ b/.talismanrc @@ -5,4 +5,8 @@ fileignoreconfig: checksum: 580932f192dd3fdd8bb2c55b7a7a78f1694f646ef5c5041f86c75668778f7ecb - filename: packages/contentstack-bulk-operations/test/unit/utils/asset-uids-from-file.test.ts checksum: 8123f7a675a0275795b59b15d0f2d5f8f1e57ccbecf3f97249a0dc5a037b9203 +- filename: packages/contentstack-bulk-operations/src/utils/data-dir-asset-fetcher.ts + checksum: ddcf4601ac47be300eba0eb901e4d45d748c2c4eab676c56677cb9a802fe3db0 +- filename: packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts + checksum: c8767e79c1010cccf984d2124b2c6252b7cba1fb1b6a9f216fa7ddb5b195a935 version: '1.0' diff --git a/packages/contentstack-bulk-operations/src/base-bulk-command.ts b/packages/contentstack-bulk-operations/src/base-bulk-command.ts index e5f0bc62c..a6b0a987a 100644 --- a/packages/contentstack-bulk-operations/src/base-bulk-command.ts +++ b/packages/contentstack-bulk-operations/src/base-bulk-command.ts @@ -132,7 +132,7 @@ export abstract class BaseBulkCommand extends Command { protected rateLimiter!: AdaptiveRateLimiter; protected retryStrategy!: RetryStrategy; protected operationExecutor!: OperationExecutor; - private batchResults: Map = new Map(); + protected batchResults: Map = new Map(); protected parsedFlags: any; /** @@ -165,7 +165,7 @@ export abstract class BaseBulkCommand extends Command { } // Fill missing required flags via interactive prompts - flags = await fillMissingFlags(flags); + flags = await this.resolveFlagsInteractively(flags); this.parsedFlags = flags; await this.buildConfiguration(flags); @@ -265,6 +265,14 @@ export abstract class BaseBulkCommand extends Command { } } + + /** + * Resolve flags interactively — subclasses can override to skip prompts for specific modes. + */ + protected async resolveFlagsInteractively(flags: any): Promise { + return await fillMissingFlags(flags); + } + /** * Build operation configuration */ diff --git a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts index 71122a91d..53bc50c1a 100644 --- a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts +++ b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts @@ -1,12 +1,17 @@ -import { flags, handleAndLogError, FlagInput } from '@contentstack/cli-utilities'; +import * as fs from 'fs'; +import * as path from 'path'; -import { ResourceType } from '../../../interfaces'; +import { flags, handleAndLogError, log } from '@contentstack/cli-utilities'; + +import { AssetPublishData, BulkOperationResult, OperationType, ResourceType } from '../../../interfaces'; import { BaseBulkCommand } from '../../../base-bulk-command'; -import { $t, messages, fetchAssets } from '../../../utils'; +import { $t, messages, fetchAssets, scanDataDirStats, BATCH_CONSTANTS, categorizeByScanStatus } from '../../../utils'; +import type { DataDirScanStats } from '../../../utils'; +import { AssetService } from '../../../services'; /** * Bulk operations command for assets - * Supports publish, unpublish, and cross publish operations + * Supports publish, unpublish, cross-publish, and data-dir publish operations */ export default class BulkAssets extends BaseBulkCommand { static description = messages.BULK_ASSETS_DESCRIPTION; @@ -32,25 +37,47 @@ export default class BulkAssets extends BaseBulkCommand { // Revert (unpublish) previously published assets using success log '<%= config.bin %> <%= command.id %> --revert ./bulk-operation -a myAlias', + + // Publish assets from exported content folder (e.g. after asset scanning clears) + '<%= config.bin %> <%= command.id %> --data-dir ./content --operation publish -k blt123', ]; - static flags: FlagInput = { + static flags = { ...BaseBulkCommand.baseFlags, 'folder-uid': flags.string({ description: messages.FOLDER_UID, }), + 'data-dir': flags.string({ + char: 'd', + description: messages.DATA_DIR_FLAG_DESC, + }), + 'dry-run': flags.boolean({ + description: messages.DRY_RUN_FLAG_DESC, + default: false, + }), }; protected resourceType: ResourceType = ResourceType.ASSET; + protected async resolveFlagsInteractively(flags: any): Promise { + if (flags['data-dir']) { + return flags; + } + return super.resolveFlagsInteractively(flags); + } + async run(): Promise { try { - // Handle cross-publish separately if source-env is specified if (this.bulkOperationConfig.sourceEnv) { await this.handleCrossPublish(this.parsedFlags); return; } + if (this.bulkOperationConfig.dataDir) { + await this.runDataDirFlow(); + return; + } + const assets = await this.fetchItems(); if (assets.length === 0) { @@ -58,18 +85,39 @@ export default class BulkAssets extends BaseBulkCommand { return; } - this.logger.info( - $t(messages.FOUND_ASSETS_TO_OPERATE, { count: assets.length, operation: this.parsedFlags.operation || '' }) - ); + const { clean, pending, quarantined, noStatus } = categorizeByScanStatus(assets); + const scanningEnabled = clean.length + pending.length + quarantined.length > 0; + const publishable = scanningEnabled ? clean : [...clean, ...noStatus]; + + if (scanningEnabled) { + // Log individual skipped assets + pending.forEach((a) => this.logger.warn($t(messages.SCAN_STATUS_SKIPPED_PENDING, { uid: a.uid }))); + quarantined.forEach((a) => this.logger.warn($t(messages.SCAN_STATUS_SKIPPED_QUARANTINED, { uid: a.uid }))); - // Confirm operation - const confirmed = await this.confirmOperation(assets); + this.printScanningDashboard({ + total: assets.length, + clean: clean.length, + pending: pending.length, + quarantined: quarantined.length, + }); + + if (publishable.length === 0) { + this.logger.warn($t(messages.NO_PUBLISHABLE_ASSETS)); + return; + } + } else { + log.info( + $t(messages.FOUND_ASSETS_TO_OPERATE, { count: assets.length, operation: this.parsedFlags.operation || '' }) + ); + } + + const confirmed = await this.confirmOperation(publishable); if (!confirmed) { this.logger.warn($t(messages.OPERATION_CANCELLED)); return; } - const result = await this.executeBulkOperation(assets); + const result = await this.executeBulkOperation(publishable); this.printOperationSummary(result); } catch (error) { handleAndLogError(error); @@ -78,6 +126,218 @@ export default class BulkAssets extends BaseBulkCommand { } } + private async runDataDirFlow(): Promise { + const { dataDir, dryRun } = this.bulkOperationConfig; + + // Capture original CLI locales/envs before pass 1 overwrites them on the config. + const cliLocales = [...(this.bulkOperationConfig.locales || [])]; + const cliEnvs = [...(this.bulkOperationConfig.environments || [])]; + + // Pass 1 — count-only scan: no AssetPublishData objects built, one chunk in memory at a time. + let stats: DataDirScanStats; + try { + stats = await scanDataDirStats(dataDir!, cliEnvs, cliLocales, this.logger); + } catch (err: any) { + this.logger.error($t(messages.DATA_DIR_READ_ERROR, { path: dataDir!, error: err.message || String(err) })); + return; + } + + this.bulkOperationConfig.environments = stats.environments; + this.bulkOperationConfig.locales = stats.locales; + + // Pass 1.5 — fetch scan status for all target UIDs (post-import UIDs on the destination stack). + const targetUids = Object.values(stats.assetUidMapper); + const assetService = new AssetService(this.managementStack, this.deliveryStack, this.logger); + const scanStatusMap = await assetService.fetchScanStatusByUIDs(targetUids); + + let cleanCount = 0; + let pendingCount = 0; + let quarantinedCount = 0; + for (const uid of targetUids) { + const status = scanStatusMap.get(uid); + if (status === 'pending') pendingCount++; + else if (status === 'quarantined') quarantinedCount++; + else cleanCount++; // clean or undefined (scanning disabled) — both are publishable + } + + this.printScanningDashboard({ + total: stats.eligible + stats.skipped + stats.unmapped, + localSkipped: stats.skipped, + unmapped: stats.unmapped, + clean: cleanCount, + pending: pendingCount, + quarantined: quarantinedCount, + }); + + if (cleanCount === 0) { + this.logger.warn($t(messages.NO_PUBLISHABLE_ASSETS)); + return; + } + + // new Array(n) has .length === n but allocates no elements — just for the count. + const confirmed = await this.confirmOperation(new Array(cleanCount)); + if (!confirmed) { + this.logger.warn($t(messages.OPERATION_CANCELLED)); + return; + } + + if (dryRun) { + log.info($t(messages.DATA_DIR_DRY_RUN)); + return; + } + + // Pass 2 — stream and publish: one chunk at a time, batches of ≤50 items enqueued directly. + // stats.assetUidMapper and stats.assetsIndex are reused from pass 1 — no second disk read. + const result = await this.streamAndPublish( + dataDir!, + cliLocales, + stats.totalItems, + stats.assetUidMapper, + stats.assetsIndex, + scanStatusMap + ); + this.printOperationSummary(result); + } + + /** + * Pass 2 of the data-dir flow. + * Reads chunk files one at a time, fills a working batch of ≤50 AssetPublishData items, + * and enqueues each batch directly into the queue manager without ever holding the full + * asset list in memory. Peak memory: one chunk file + one batch of ≤50 items. + * + * assetUidMapper and assetsIndex are passed in from pass 1 to avoid re-reading those files. + * scanStatusMap filters out non-clean assets before enqueueing. + */ + private async streamAndPublish( + dataDir: string, + cliLocales: string[], + totalItemCount: number, + assetUidMapper: Record, + assetsIndex: Record, + scanStatusMap: Map + ): Promise { + // Snapshot both arrays so in-flight mutations to bulkOperationConfig can't corrupt payloads. + const environments = [...this.bulkOperationConfig.environments!]; + const locales = [...this.bulkOperationConfig.locales!]; + const operation = this.bulkOperationConfig.operation as OperationType; + const startTime = Date.now(); + + // Warn early if the mapper is empty — all assets will be skipped and the user needs to know why. + if (Object.keys(assetUidMapper).length === 0) { + this.logger.warn( + 'Asset UID mapper is empty — all assets will be skipped. Ensure the import completed successfully.' + ); + } + + const useOverrideLocales = cliLocales.length > 0; + const BATCH_SIZE = BATCH_CONSTANTS.maxItems; + // totalItemCount comes from pass 1 using identical counting logic — used as upper bound for totalBatches. + // Scan status filtering may reduce the actual count; the invariant check below will log any mismatch. + const totalBatches = Math.ceil(totalItemCount / BATCH_SIZE); + + let workingBatch: AssetPublishData[] = []; + let batchNumber = 0; + let totalSubmitted = 0; + + this.batchResults.clear(); + + const flushBatch = (): void => { + if (workingBatch.length === 0) return; + batchNumber++; + this.queueManager.enqueue(ResourceType.ASSET, operation, { + items: [...workingBatch], + environments, + locales, + batchNumber, + totalBatches, + operation, + }); + totalSubmitted += workingBatch.length; + workingBatch = []; + }; + + for (const chunkFilename of Object.values(assetsIndex)) { + const chunkPath = path.join(dataDir, 'assets', chunkFilename); + const chunkData: Record = JSON.parse(fs.readFileSync(chunkPath, 'utf-8')); + + for (const asset of Object.values(chunkData)) { + if (!asset.publish_details || asset.publish_details.length === 0) continue; + const targetUid = assetUidMapper[asset.uid as string]; + if (!targetUid) continue; + + // Skip assets that did not pass scanning. + const scanStatus = scanStatusMap.get(targetUid); + if (scanStatus === 'quarantined') { + this.logger.warn($t(messages.SCAN_STATUS_SKIPPED_QUARANTINED, { uid: targetUid })); + continue; + } + if (scanStatus === 'pending') { + this.logger.warn($t(messages.SCAN_STATUS_SKIPPED_PENDING, { uid: targetUid })); + continue; + } + + const assetLocales: string[] = useOverrideLocales + ? cliLocales + : [...new Set(asset.publish_details.map((pd: any) => pd.locale as string))]; + + for (const locale of assetLocales) { + workingBatch.push({ type: 'asset', uid: targetUid, locale, version: asset._version }); + if (workingBatch.length >= BATCH_SIZE) { + flushBatch(); + } + } + } + // chunkData falls out of scope here — GC can reclaim it before the next chunk is read. + } + + flushBatch(); + + // Invariant: pass 1 and pass 2 use identical counting logic (excluding scan status filtering). + // If batchNumber < totalBatches, scan status filtering reduced the published count — expected. + if (batchNumber !== totalBatches) { + this.logger.debug( + `Batch count: predicted ${totalBatches}, actual ${batchNumber}. Difference is expected when assets are skipped due to scan status.` + ); + } + + await this.queueManager.waitForCompletion(); + + const duration = Date.now() - startTime; + const jobIds = [...this.batchResults.values()].map((r) => r.jobId).filter((id): id is string => !!id); + + return { success: 0, failed: 0, total: totalSubmitted, duration, jobIds }; + } + + private printScanningDashboard(opts: { + total: number; + clean: number; + pending: number; + quarantined: number; + localSkipped?: number; + unmapped?: number; + }): void { + const { total, clean, pending, quarantined, localSkipped, unmapped } = opts; + const SEP = '─'.repeat(42); + + log.info(''); + log.info(` ${messages.DATA_DIR_ASSET_SCANNING_HEADER}`); + log.info(' ' + SEP); + log.info(` ${messages.DATA_DIR_TOTAL.padEnd(38)} ${total}`); + if (localSkipped !== undefined) { + log.warn(` ${messages.DATA_DIR_NO_PUBLISH_DETAILS.padEnd(38)} ${localSkipped}`); + } + if (unmapped !== undefined) { + log.warn(` ${messages.DATA_DIR_UNMAPPED.padEnd(38)} ${unmapped}`); + } + log.info(' ' + SEP); + log.info(` ${messages.SCAN_STATUS_CLEAN.padEnd(38)} ${clean}`); + if (pending > 0) log.warn(` ${messages.SCAN_STATUS_PENDING.padEnd(38)} ${pending}`); + if (quarantined > 0) log.warn(` ${messages.SCAN_STATUS_QUARANTINED.padEnd(38)} ${quarantined}`); + log.info(' ' + SEP); + log.info(` ${messages.DATA_DIR_WILL_PUBLISH.padEnd(38)} ${clean}`); + log.info(''); + } + protected async fetchItems(): Promise { return await fetchAssets(this.bulkOperationConfig, this.managementStack, this.deliveryStack, this.logger); } diff --git a/packages/contentstack-bulk-operations/src/interfaces/index.ts b/packages/contentstack-bulk-operations/src/interfaces/index.ts index c315fba34..13a4f2959 100644 --- a/packages/contentstack-bulk-operations/src/interfaces/index.ts +++ b/packages/contentstack-bulk-operations/src/interfaces/index.ts @@ -58,6 +58,8 @@ export interface BulkOperationConfig { // Asset-specific options folderUid?: string; + dataDir?: string; + dryRun?: boolean; // Cross-publish sourceEnv?: string; @@ -135,6 +137,7 @@ export interface Asset { title?: string; _version?: number; publish_details?: PublishDetails[]; + _asset_scan_status?: 'pending' | 'clean' | 'quarantined'; [key: string]: any; } @@ -196,6 +199,8 @@ export interface CommandFlags { // Asset-specific flags 'folder-uid'?: string; + 'data-dir'?: string; + 'dry-run'?: boolean; /** AM bulk delete/move */ 'space-uid'?: string; @@ -254,6 +259,7 @@ export interface AssetPublishData { locale: string; version?: number; publish_details?: PublishDetails[]; + _asset_scan_status?: 'pending' | 'clean' | 'quarantined'; } /** One row for AM bulk-delete payload `{ uid, locale }[]`. */ @@ -444,4 +450,4 @@ export interface CrossPublishConfig { contentTypes?: string[]; resourceType: ResourceType; deliveryStack: DeliveryStack | null; // Pass delivery stack from command (optional) -} \ No newline at end of file +} diff --git a/packages/contentstack-bulk-operations/src/messages/index.ts b/packages/contentstack-bulk-operations/src/messages/index.ts index a285f734e..bc9633540 100644 --- a/packages/contentstack-bulk-operations/src/messages/index.ts +++ b/packages/contentstack-bulk-operations/src/messages/index.ts @@ -210,6 +210,25 @@ const bulkAssetsMsg = { CROSS_PUBLISHING: 'Cross-publishing from {sourceEnv} to {targetEnvs}', SYNCED_ASSETS: 'Synced {count} assets from {sourceEnv}', ASSETS_READY_FOR_CROSS_PUBLISH: '{count} assets ready for cross-publish', + + // Data-dir / scanning dashboard + DATA_DIR_ASSET_SCANNING_HEADER: 'Asset Scan Status', + DATA_DIR_TOTAL: 'Total assets found', + DATA_DIR_VALID: 'Clean (will publish)', + DATA_DIR_NO_PUBLISH_DETAILS: 'No publish details (skipped)', + DATA_DIR_UNMAPPED: 'Not imported / UID unmapped (skipped)', + DATA_DIR_WILL_PUBLISH: 'Will publish', + DATA_DIR_DRY_RUN: 'Dry run — no publish API calls will be made.', + DATA_DIR_FLAG_DESC: 'Path to exported content folder containing asset publish details.', + DRY_RUN_FLAG_DESC: 'Preview the publish plan without making any API calls.', + DATA_DIR_READ_ERROR: 'Failed to read data directory at {path}: {error}', + SCAN_STATUS_CLEAN: 'Clean (will publish)', + SCAN_STATUS_PENDING: 'Still scanning (skipped)', + SCAN_STATUS_QUARANTINED: 'Quarantined (skipped)', + SCAN_STATUS_SKIPPED_PENDING: 'Skipped (still scanning): {uid}', + SCAN_STATUS_SKIPPED_QUARANTINED: 'Skipped (quarantined): {uid}', + SCAN_STATUS_FETCHING: 'Checking asset scan status for {count} assets...', + NO_PUBLISHABLE_ASSETS: 'No publishable assets — all assets are either still scanning or quarantined.', }; /** diff --git a/packages/contentstack-bulk-operations/src/services/asset-service.ts b/packages/contentstack-bulk-operations/src/services/asset-service.ts index aba844fb1..903ce3730 100644 --- a/packages/contentstack-bulk-operations/src/services/asset-service.ts +++ b/packages/contentstack-bulk-operations/src/services/asset-service.ts @@ -37,7 +37,7 @@ export class AssetService { const batchUids = uids.slice(i, i + BATCH_CONSTANTS.assetFetchBatchSize); const batchPromises = batchUids.map(async (uid) => { try { - const asset = this.deliveryStack ? await this.deliveryStack.asset(uid).fetch() : undefined; + const asset = await this.deliveryStack?.asset(uid).fetch(); return asset; } catch (error: any) { // Asset might not exist or not be published to this environment @@ -125,7 +125,13 @@ export class AssetService { try { while (hasMore) { - const queryOptions: any = { skip, limit, include_count: true, include_publish_details: true }; + const queryOptions: any = { + skip, + limit, + include_count: true, + include_publish_details: true, + include_asset_scan_status: true, + }; // Add any filters from options if (options.query) { @@ -207,7 +213,14 @@ export class AssetService { while (hasMore) { const query = this.stack .asset() - .query({ skip, limit, include_count: true, include_publish_details: true, folder: folderUid }); + .query({ + skip, + limit, + include_count: true, + include_publish_details: true, + include_asset_scan_status: true, + folder: folderUid, + }); const response = await query.find(); const assets = response.items || []; @@ -273,4 +286,34 @@ export class AssetService { throw error; } } + + /** + * Fetch scan status for a specific list of asset UIDs. + * Batches requests at 100 UIDs per call to stay within API limits. + * Returns a Map — undefined means scanning is not enabled on the stack. + */ + async fetchScanStatusByUIDs(uids: string[]): Promise> { + const statusMap = new Map(); + if (uids.length === 0) return statusMap; + + this.logger.info($t(messages.SCAN_STATUS_FETCHING, { count: uids.length })); + + const BATCH = 100; + for (let i = 0; i < uids.length; i += BATCH) { + const batch = uids.slice(i, i + BATCH); + try { + const response = await this.stack + .asset() + .query({ uid: { $in: batch }, include_asset_scan_status: true, limit: BATCH }) + .find(); + for (const asset of response.items || []) { + statusMap.set(asset.uid, asset._asset_scan_status); + } + } catch (error: any) { + this.logger.warn(`Failed to fetch scan status for batch starting at index ${i}: ${error?.message}`); + } + } + + return statusMap; + } } diff --git a/packages/contentstack-bulk-operations/src/services/bulk-operation-service.ts b/packages/contentstack-bulk-operations/src/services/bulk-operation-service.ts index 705d1a90c..18c9618f5 100644 --- a/packages/contentstack-bulk-operations/src/services/bulk-operation-service.ts +++ b/packages/contentstack-bulk-operations/src/services/bulk-operation-service.ts @@ -47,13 +47,15 @@ export class BulkOperationService { async executeBulkPublish( items: Array, operation: OperationType, - resourceType: ResourceType + resourceType: ResourceType, + environments?: string[], + locales?: string[] ): Promise { this.logger.info($t(messages.SUBMITTING_BULK_JOB, { operation, count: items.length })); try { // Step 1: Submit bulk job - const jobId = await this.submitBulkJob(items, operation, resourceType); + const jobId = await this.submitBulkJob(items, operation, resourceType, environments, locales); this.logger.debug($t(messages.BULK_JOB_CREATED, { jobId })); // Return immediate result after job submission @@ -78,10 +80,12 @@ export class BulkOperationService { private async submitBulkJob( items: Array, operation: OperationType, - resourceType: ResourceType + resourceType: ResourceType, + environments?: string[], + locales?: string[] ): Promise { try { - const payload = this.prepareBulkPayload(items, operation, resourceType); + const payload = this.prepareBulkPayload(items, operation, resourceType, environments, locales); let response: any; switch (operation) { case OperationType.PUBLISH: @@ -203,16 +207,23 @@ export class BulkOperationService { private prepareBulkPayload( items: Array, operation: OperationType, - resourceType: ResourceType + resourceType: ResourceType, + environments?: string[], + locales?: string[] ): any { if (resourceType === ResourceType.ENTRY) { - return this.prepareEntryBulkPayload(items as EntryPublishData[], operation); + return this.prepareEntryBulkPayload(items as EntryPublishData[], operation, environments, locales); } else { - return this.prepareAssetBulkPayload(items as AssetPublishData[], operation); + return this.prepareAssetBulkPayload(items as AssetPublishData[], operation, environments, locales); } } - private prepareEntryBulkPayload(items: EntryPublishData[], operation: OperationType): any { + private prepareEntryBulkPayload( + items: EntryPublishData[], + operation: OperationType, + batchEnvironments?: string[], + batchLocales?: string[] + ): any { const entries = items.map((item) => { const entry: any = { uid: item.uid, @@ -233,8 +244,17 @@ export class BulkOperationService { return entry; }); - const environments = items[0]?.publish_details?.map((pd) => pd.environment) || []; - const locales = Array.from(new Set(items.map((item) => item.locale))); + const environments = batchEnvironments?.length + ? batchEnvironments + : items[0]?.publish_details?.map((pd) => pd.environment) || []; + const locales = batchLocales?.length ? batchLocales : Array.from(new Set(items.map((item) => item.locale))); + + if (!environments.length) { + throw new Error('No environments for bulk publish. Ensure entries have publish_details with environment data.'); + } + if (!locales.length) { + throw new Error('No locales for bulk publish. Ensure entries have a locale field.'); + } return { entries, @@ -244,14 +264,28 @@ export class BulkOperationService { }; } - private prepareAssetBulkPayload(items: AssetPublishData[], operation: OperationType): any { + private prepareAssetBulkPayload( + items: AssetPublishData[], + operation: OperationType, + batchEnvironments?: string[], + batchLocales?: string[] + ): any { const assets = items.map((item) => ({ uid: item.uid, version: item.version, })); - const environments = items[0]?.publish_details?.map((pd) => pd.environment) || []; - const locales = items[0]?.publish_details?.map((pd) => pd.locale) || []; + const environments = batchEnvironments?.length + ? batchEnvironments + : items[0]?.publish_details?.map((pd) => pd.environment) || []; + const locales = batchLocales?.length ? batchLocales : items[0]?.publish_details?.map((pd) => pd.locale) || []; + + if (!environments.length) { + throw new Error('No environments for bulk publish. Ensure assets have publish_details with environment data.'); + } + if (!locales.length) { + throw new Error('No locales for bulk publish. Ensure assets have publish_details with locale data.'); + } return { assets, diff --git a/packages/contentstack-bulk-operations/src/utils/batch-queue-handler.ts b/packages/contentstack-bulk-operations/src/utils/batch-queue-handler.ts index e32eadcd8..4e624e5da 100644 --- a/packages/contentstack-bulk-operations/src/utils/batch-queue-handler.ts +++ b/packages/contentstack-bulk-operations/src/utils/batch-queue-handler.ts @@ -21,7 +21,7 @@ export function setupBatchQueueListeners(config: BatchQueueConfig) { } logger.info( - `Processing batch ${batch.batchNumber ?? 0}/${batch.totalBatches ?? 0}: ` + + `Processing batch ${batch.batchNumber}/${batch.totalBatches}: ` + `${batch.items.length} items, ` + `${batch.locales.length} locales, ` + `${batch.environments.length} environments` @@ -29,7 +29,13 @@ export function setupBatchQueueListeners(config: BatchQueueConfig) { (async () => { try { - const result = await bulkService.executeBulkPublish(batch.items, batch.operation, resourceType); + const result = await bulkService.executeBulkPublish( + batch.items, + batch.operation, + resourceType, + batch.environments, + batch.locales + ); batchResults.set(item.id, result); queueManager.updateItemStatus(item.id, OperationStatus.SUCCESS); @@ -76,7 +82,7 @@ export function setupBatchQueueListeners(config: BatchQueueConfig) { if (!batch) return; handleAndLogError(error, { - batchNumber: `${batch.batchNumber ?? 0}/${batch.totalBatches ?? 0}`, + batchNumber: `${batch.batchNumber}/${batch.totalBatches}`, itemCount: batch.items.length, }); @@ -109,7 +115,7 @@ async function handleRetryOrFailure({ : retryStrategy.getDelay(item.retryCount); logger.warn( - `Batch ${batch.batchNumber ?? 0}/${batch.totalBatches ?? 0} failed with ${ + `Batch ${batch.batchNumber}/${batch.totalBatches} failed with ${ isRateLimit ? '429 Rate Limit' : getErrorCode(error) }, retrying in ${Math.ceil(delay / 1000)}s` ); diff --git a/packages/contentstack-bulk-operations/src/utils/config-builder.ts b/packages/contentstack-bulk-operations/src/utils/config-builder.ts index c53deb98c..e92e9fb7c 100644 --- a/packages/contentstack-bulk-operations/src/utils/config-builder.ts +++ b/packages/contentstack-bulk-operations/src/utils/config-builder.ts @@ -69,24 +69,28 @@ function validateConfig(config: BulkOperationConfig): string[] { errors.push(`Invalid operation type: ${config.operation}. Must be 'publish' or 'unpublish'`); } - // Environments validation - if ( - (operation === OperationType.PUBLISH || operation === OperationType.UNPUBLISH) && - (!config.environments || config.environments.length === 0) - ) { - errors.push('Environments are required for publish/unpublish operations'); - } - if (config.environments?.some((env) => !env || env.trim() === '')) { - errors.push('Environment list cannot contain empty values'); + // Environments validation — skipped when assets are read from a data directory + if (!config.dataDir) { + if ( + (operation === OperationType.PUBLISH || operation === OperationType.UNPUBLISH) && + (!config.environments || config.environments.length === 0) + ) { + errors.push('Environments are required for publish/unpublish operations'); + } + if (config.environments?.some((env) => !env || env.trim() === '')) { + errors.push('Environment list cannot contain empty values'); + } } - // Locales validation + // Locales validation — skipped when assets are read from a data directory const isNonLocalized = config.filter === FilterType.NON_LOCALIZED; - if (!isNonLocalized && (!config.locales || config.locales.length === 0)) { - errors.push('Locales are required'); - } - if (config.locales?.some((locale) => !locale || locale.trim() === '')) { - errors.push('Locale list cannot contain empty values'); + if (!config.dataDir) { + if (!isNonLocalized && (!config.locales || config.locales.length === 0)) { + errors.push('Locales are required'); + } + if (config.locales?.some((locale) => !locale || locale.trim() === '')) { + errors.push('Locale list cannot contain empty values'); + } } // Filter validation @@ -144,24 +148,28 @@ function validateCommandFlags(flags: CommandFlags): string[] { const operation = flags.operation as OperationType; - // Environment validation - if ( - (operation === OperationType.PUBLISH || operation === OperationType.UNPUBLISH) && - (!flags.environments || flags.environments.length === 0) - ) { - errors.push('Environments are required for publish/unpublish operations'); - } - if (flags.environments?.some((env) => !env || env.trim() === '')) { - errors.push('Environment list cannot contain empty values'); + // Environment validation — skipped when assets are read from a data directory + if (!flags['data-dir']) { + if ( + (operation === OperationType.PUBLISH || operation === OperationType.UNPUBLISH) && + (!flags.environments || flags.environments.length === 0) + ) { + errors.push('Environments are required for publish/unpublish operations'); + } + if (flags.environments?.some((env) => !env || env.trim() === '')) { + errors.push('Environment list cannot contain empty values'); + } } - // Locale validation + // Locale validation — skipped when assets are read from a data directory const isNonLocalized = flags.filter === FilterType.NON_LOCALIZED; - if (!isNonLocalized && (!flags.locales || flags.locales.length === 0)) { - errors.push('Locales are required'); - } - if (flags.locales?.some((locale) => !locale || locale.trim() === '')) { - errors.push('Locale list cannot contain empty values'); + if (!flags['data-dir']) { + if (!isNonLocalized && (!flags.locales || flags.locales.length === 0)) { + errors.push('Locales are required'); + } + if (flags.locales?.some((locale) => !locale || locale.trim() === '')) { + errors.push('Locale list cannot contain empty values'); + } } // Content types validation @@ -243,6 +251,8 @@ export function buildConfig(flags: CommandFlags): BulkOperationConfig { contentTypes: flags['content-types'] !== undefined ? expandFlagStringList(flags['content-types']) : undefined, includeVariants: flags['include-variants'], folderUid: flags['folder-uid'], + dataDir: flags['data-dir'], + dryRun: flags['dry-run'], sourceEnv: flags['source-env'], publishMode: (flags['publish-mode'] as PublishMode) || PublishMode.BULK, apiVersion: flags['api-version'] || '3', diff --git a/packages/contentstack-bulk-operations/src/utils/data-dir-asset-fetcher.ts b/packages/contentstack-bulk-operations/src/utils/data-dir-asset-fetcher.ts new file mode 100644 index 000000000..71ea47bd3 --- /dev/null +++ b/packages/contentstack-bulk-operations/src/utils/data-dir-asset-fetcher.ts @@ -0,0 +1,114 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +export interface DataDirScanStats { + /** Number of assets eligible for publish (have publish_details + mapped UID). */ + eligible: number; + /** Total AssetPublishData items that will be created (eligible × locale expansions). */ + totalItems: number; + skipped: number; + unmapped: number; + environments: string[]; + locales: string[]; + /** Reusable in pass 2 — already loaded during pass 1, avoids a second disk read. */ + assetUidMapper: Record; + /** Reusable in pass 2 — already loaded during pass 1, avoids a second disk read. */ + assetsIndex: Record; +} + +/** + * Pass 1: count-only scan of the data directory. + * Reads chunk files one at a time, counts eligible/skipped/unmapped, and + * discovers environments and locales — without building any AssetPublishData objects. + * Memory footprint: uid mapper + env map + one chunk at a time. + * + * Returns assetUidMapper and assetsIndex so pass 2 (streamAndPublish) can reuse them + * without re-reading the same files from disk. + */ +export async function scanDataDirStats( + dataDir: string, + overrideEnvs?: string[], + overrideLocales?: string[], + logger?: any +): Promise { + const assetsIndexPath = path.join(dataDir, 'assets', 'assets.json'); + const environmentsPath = path.join(dataDir, 'environments', 'environments.json'); + const assetUidMapperPath = path.join(dataDir, 'mapper', 'assets', 'uid-mapping.json'); + + if (!fs.existsSync(assetsIndexPath)) { + throw new Error( + `Asset index not found: ${assetsIndexPath}. Ensure --data-dir points to the import backup directory.` + ); + } + + let assetUidMapper: Record = {}; + if (fs.existsSync(assetUidMapperPath)) { + assetUidMapper = JSON.parse(fs.readFileSync(assetUidMapperPath, 'utf-8')); + } else { + logger?.warn( + `Asset UID mapper not found: ${assetUidMapperPath}. Ensure --data-dir points to the import backup directory.` + ); + } + + const environmentsMap: Record = {}; + if (fs.existsSync(environmentsPath)) { + const envData: Record = JSON.parse(fs.readFileSync(environmentsPath, 'utf-8')); + for (const [uid, env] of Object.entries(envData)) { + environmentsMap[uid] = (env as any).name || uid; + } + } else { + logger?.warn(`Environments file not found: ${environmentsPath}`); + } + + const assetsIndex: Record = JSON.parse(fs.readFileSync(assetsIndexPath, 'utf-8')); + + let eligible = 0; + let totalItems = 0; + let skipped = 0; + let unmapped = 0; + const allEnvs = new Set(); + const allLocales = new Set(); + + for (const chunkFilename of Object.values(assetsIndex)) { + const chunkPath = path.join(dataDir, 'assets', chunkFilename); + const chunkData: Record = JSON.parse(fs.readFileSync(chunkPath, 'utf-8')); + + for (const asset of Object.values(chunkData)) { + if (!asset.publish_details || asset.publish_details.length === 0) { + skipped++; + continue; + } + + const targetUid = assetUidMapper[asset.uid as string]; + if (!targetUid) { + unmapped++; + continue; + } + + eligible++; + + if (!overrideLocales?.length) { + for (const pd of asset.publish_details) { + if (pd.locale) allLocales.add(pd.locale as string); + } + } + if (!overrideEnvs?.length) { + for (const pd of asset.publish_details) { + const envName = environmentsMap[pd.environment] || pd.environment; + if (envName) allEnvs.add(envName as string); + } + } + + const localeCount = overrideLocales?.length + ? overrideLocales.length + : new Set(asset.publish_details.map((pd: any) => pd.locale as string)).size; + totalItems += localeCount; + } + // chunkData falls out of scope here — GC reclaims it + } + + const environments = overrideEnvs?.length ? overrideEnvs : [...allEnvs]; + const locales = overrideLocales?.length ? overrideLocales : [...allLocales]; + + return { eligible, totalItems, skipped, unmapped, environments, locales, assetUidMapper, assetsIndex }; +} diff --git a/packages/contentstack-bulk-operations/src/utils/helpers.ts b/packages/contentstack-bulk-operations/src/utils/helpers.ts index 7e5beb260..8b7666048 100644 --- a/packages/contentstack-bulk-operations/src/utils/helpers.ts +++ b/packages/contentstack-bulk-operations/src/utils/helpers.ts @@ -1,7 +1,7 @@ import chalk from 'chalk'; import { getLogPath } from '@contentstack/cli-utilities'; import { $t, messages } from './index'; -import { AssetPublishData, EntryPublishData, BulkOperationResult, BulkJobResult } from '../interfaces'; +import { AssetPublishData, EntryPublishData, BulkOperationResult, BulkJobResult, Asset } from '../interfaces'; export function chunkArray(array: T[], chunkSize: number): T[][] { const chunks: T[][] = []; @@ -122,3 +122,37 @@ export function logSummary(result: any): void { console.log(''); } + +/** + * Categorize assets by their _asset_scan_status field. + * Assets with no status field belong to stacks where scanning is disabled — treat as publishable. + */ +export function categorizeByScanStatus(assets: Asset[]): { + clean: Asset[]; + pending: Asset[]; + quarantined: Asset[]; + noStatus: Asset[]; +} { + const clean: Asset[] = []; + const pending: Asset[] = []; + const quarantined: Asset[] = []; + const noStatus: Asset[] = []; + + for (const asset of assets) { + switch (asset._asset_scan_status) { + case 'clean': + clean.push(asset); + break; + case 'pending': + pending.push(asset); + break; + case 'quarantined': + quarantined.push(asset); + break; + default: + noStatus.push(asset); + } + } + + return { clean, pending, quarantined, noStatus }; +} diff --git a/packages/contentstack-bulk-operations/src/utils/index.ts b/packages/contentstack-bulk-operations/src/utils/index.ts index 02c334e3e..66497598c 100644 --- a/packages/contentstack-bulk-operations/src/utils/index.ts +++ b/packages/contentstack-bulk-operations/src/utils/index.ts @@ -21,6 +21,7 @@ import { aggregateBatchResults, createOperationResult, logSummary, + categorizeByScanStatus, } from './helpers'; import { setupBatchQueueListeners } from './batch-queue-handler'; import { confirmOperation } from './operation-confirmation'; @@ -51,6 +52,8 @@ import { validateAndBuildBulkDeleteItems, LoadAssetUidsError, } from './asset-uids-from-file'; +import { scanDataDirStats } from './data-dir-asset-fetcher'; +import type { DataDirScanStats } from './data-dir-asset-fetcher'; import { compareFieldValues, compareNonLocalizedFields, @@ -90,6 +93,7 @@ export { fetchAssets, fetchEntries, logSummary, + categorizeByScanStatus, logOperationInfo, validateBatch, enqueueIndividualItems, @@ -117,4 +121,6 @@ export { loadBulkDeleteItemsFromFile, validateAndBuildBulkDeleteItems, LoadAssetUidsError, + scanDataDirStats, }; +export type { DataDirScanStats }; diff --git a/packages/contentstack-bulk-operations/src/utils/item-fetcher.ts b/packages/contentstack-bulk-operations/src/utils/item-fetcher.ts index 35076ade2..c794520ce 100644 --- a/packages/contentstack-bulk-operations/src/utils/item-fetcher.ts +++ b/packages/contentstack-bulk-operations/src/utils/item-fetcher.ts @@ -221,6 +221,7 @@ export async function fetchAssets( environment: env, locale, })), + _asset_scan_status: asset._asset_scan_status, }); } } From 13eae5915e36f1a0fa5ebf4d95f8957eca4d129c Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 29 May 2026 14:15:52 +0530 Subject: [PATCH 06/44] chore: add config in bulk package --- packages/contentstack-bulk-operations/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/contentstack-bulk-operations/package.json b/packages/contentstack-bulk-operations/package.json index 39b6c1599..8f787d1bf 100644 --- a/packages/contentstack-bulk-operations/package.json +++ b/packages/contentstack-bulk-operations/package.json @@ -112,6 +112,7 @@ }, "csdxConfig": { "shortCommandName": { + "cm:stacks:bulk-am-assets": "BOAM", "cm:stacks:bulk-assets": "BOA", "cm:stacks:bulk-entries": "BOE", "cm:stacks:bulk-taxonomies": "BOT" From a4d908a3c45e5227875cefe22424687c6dae7374 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 5 Jun 2026 14:39:50 +0530 Subject: [PATCH 07/44] feat: add asset scanning support in import --- .talismanrc | 96 +------------------ .../src/import/module-importer.ts | 16 ++++ .../src/import/modules/assets.ts | 7 ++ .../src/types/import-config.ts | 1 + 4 files changed, 26 insertions(+), 94 deletions(-) diff --git a/.talismanrc b/.talismanrc index abd4b976c..51f9d046d 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,96 +1,4 @@ fileignoreconfig: - - filename: packages/contentstack-migrate-rte/test/dummy/expectedEntriesResponse.json - checksum: a2784a3cb21780434958478d478dcb91d2d9a3a8025567d90fe8d74e9141b052 - - filename: packages/contentstack-migrate-rte/test/dummy/entriesResponse.json - checksum: 691f3dcfbbcf69fd21e109a0d7003bdb500af2d0253bb7d7e8a0636d8f2a58f4 - - filename: pnpm-lock.yaml - checksum: e0fb4541c1f31354c8899eba61bc579942a4c1057658973b4691c2890c98ff93 - - filename: packages/contentstack-bulk-operations/src/utils/bulk-publish-url-generator.ts - checksum: 052d811adb5da9bac8c70e5b3dc4ddf700d5aea274dd2aa90a2df374118fbd26 - - filename: packages/contentstack-bulk-operations/src/utils/client.ts - checksum: efdada21291db6d66e3114b7408163dee4cafe6ddb3904f02aa67140a1a89bb6 - - filename: packages/contentstack-bulk-operations/test/unit/core/index.test.ts - checksum: 0d789258f5a9664e8a7dc5f5b23da846d0eaf8c52638ff20fb1f26104d3f9f8d - - filename: packages/contentstack-migrate-rte/README.md - checksum: 3810817d905405de86814af35fc0f0a6712cacd70f43223869b4f0599b6e579c - - filename: packages/contentstack-bulk-operations/test/unit/messages/index.test.ts - checksum: e86e76db4f4afc899ae2a4742627a71a7d227a7139014361b9d83de6154b3c7a - - filename: packages/contentstack-bulk-operations/test/unit/base-bulk-command.test.ts - checksum: 18684a596707865e671f1ee57b4819cb3f4b4f2633d6c49f7f4b6ce09391359f - - filename: packages/contentstack-bulk-operations/src/base-bulk-command.ts - checksum: 34907f0e00c40096cbe517b680a24fdf57caac351e45bc44b96e41987e619b67 - - filename: packages/contentstack-bulk-operations/test/unit/services/index.test.ts - checksum: aae62ba072551bedf869ec7b1f6bf90238bc039336f37e7c583da8ba0637f9be - - filename: packages/contentstack-bulk-operations/test/unit/utils/bulk-operation-log-handler.test.ts - checksum: cec7ba35157c6516d67931d41deb57b7a156d9fc05dbab93ca5116e89b95c820 - - filename: packages/contentstack-bulk-operations/test/unit/utils/client.test.ts - checksum: 178611b1f153b46a0020da22cc18293d5bd9c539ec2e54557fd8c1a3c2e796b3 - - filename: packages/contentstack-bulk-operations/test/unit/services/taxonomy-service.test.ts - checksum: 33af8ee198158dd92916d76207e172b5316864d063a6929526ca259b459ec79a - - filename: packages/contentstack-cli-tsgen/src/commands/tsgen.ts - checksum: 054ea78f765edca62c785714cf8962df4fb91529c0851439d1ed61e963467408 - - filename: packages/contentstack-cli-cm-regex-validate/messages/index.json - checksum: 044b311bde624dcc3c12434174d6027dbb6b62eefdfae120570a1748f806c60c - - filename: packages/contentstack-cli-tsgen/AGENTS.md - checksum: 75b4f1414b547d0bd83df5ed4fb80020acc0ed849619bed2639491b565be7a1b - - filename: packages/contentstack-bulk-operations/eslint.config.js - checksum: 0d93d7f660fe4cd6d62348c85ac10bf7c66018ea0b8e3e6d5a53419433f15867 - - filename: packages/contentstack-cli-cm-regex-validate/test/utils/connect-stack.test.ts - checksum: 8fcd1dc2770a2a3f55ba462b7ffd3fc2e3cf45342c63e5b6dc5c1db4c2bd9738 - - filename: packages/contentstack-bulk-operations/test/unit/utils/validators.test.ts - checksum: 69cf394584e325b972d6825879de7c31b9dd1bd50b0bb057aecb739258ac0317 - - filename: packages/contentstack-bulk-operations/test/unit/commands/bulk-assets.test.ts - checksum: c099c628c7ae1a40a9ca5580de0afa8309a611b2dff7837b10bb8f70eb92f8b3 - - filename: packages/contentstack-bulk-operations/test/unit/core/operation-executor.test.ts - checksum: 97f0ddd4d547f37a8d93650aa1e8af4ef4dbce343dd51853e34bbde6107cd725 - - filename: packages/contentstack-cli-tsgen/src/lib/helper.ts - checksum: a7ead0030ead9d15b6b6e9623f61e7def77b00325e3988f0e3d73a145180dedc - - filename: packages/contentstack-migrate-rte/test/utils/index.js - checksum: bc2a509a86174aecbaf0bfc44d6ad3afabe57ef871ec91b796d498e00177e3f0 - - filename: packages/contentstack-cli-cm-regex-validate/skills/code-review/SKILL.md - checksum: b92ea1c8e2f901c9e1e60f6ef6986d348a40a7869c236e3c1f3ca53b553dbb8e - - filename: packages/contentstack-migrate-rte/test/commands/json-migration.test.js - checksum: 56e10f1e0d2794fa13bcf5a6bb3e868b28277df1762fb3df0a8a82ad44f8045b - - filename: packages/contentstack-bulk-operations/test/unit/utils/interactive.test.ts - checksum: 3ee0ff5a74929346bfe997aeb977b4e93d398ea63892efc5f85e0b51a21074f6 - - filename: packages/contentstack-bulk-operations/src/core/operation-executor.ts - checksum: 46295f495f007ad291787133936c5af3c76838d72f2be0de9c235bb644d6f905 - - filename: packages/contentstack-bulk-operations/src/utils/batch-queue-handler.ts - checksum: d1d031242b99f5c738e2f4587ca2f5f3e96373e479ebaf4d93b2f98152943593 - - filename: packages/contentstack-bulk-operations/src/messages/index.ts - checksum: 2d904462af6dc3ddc00ae6bb4433c846500ddfecee5a9e1fb1c236bd598a2ee1 - - filename: packages/contentstack-migrate-rte/src/commands/cm/entries/migrate-html-rte.js - checksum: a069c50d5152022a0957d5f597158e2d8c74803b3d24ff6bbbe3b09f0e9053e2 - - filename: packages/contentstack-bulk-operations/test/unit/utils/config-builder.test.ts - checksum: d46757d3bb98d76845e83d4585f269b62b1fa9cb5bee3215b88fed38fd1dbb53 - - filename: packages/contentstack-bulk-operations/src/utils/revert-retry-handler.ts - checksum: 76899098d74de1dd20f1b08401c65f23b2bec584c051388e63f70f3d24a6d1a4 - - filename: packages/contentstack-bulk-operations/src/utils/interactive.ts - checksum: ba4fdd6f17c7d43cae639158f82dea3065ba8a368ddce8c476bfe49a6945e5c1 - - filename: packages/contentstack-bulk-operations/test/unit/utils/taxonomy-interactive-select.test.ts - checksum: 34a085702d01d7e16e1507ea1e434b374c2cba5dd884aad5996c5484412897c0 - - filename: packages/contentstack-bulk-operations/src/core/rate-limiter.ts - checksum: 81e3d624166ab34a589e3e8527b9e57ebc7e7f4374efd0483b1df0dd11788b68 - - filename: packages/contentstack-bulk-operations/src/interfaces/index.ts - checksum: 0ff6bbc372758a20783f36bd391ba9d500530433fde472a1aacaf54f6b4a1688 - - filename: packages/contentstack-bulk-operations/test/unit/utils/operation-confirmation.test.ts - checksum: 043185e56361ffae2116a2af5a4da16986816ad054fd94f189269e5b6150609e - - filename: packages/contentstack-cli-cm-regex-validate/skills/contentstack-cli/SKILL.md - checksum: 9420a516ba6046b05748683c90e3817d091cef76c46e029cb3745d6c0c350838 - - filename: packages/contentstack-cli-cm-regex-validate/skills/dev-workflow/SKILL.md - checksum: b423dd35d0f7f0f25315e2a30198669b50db350f0ab2f917a1d3c4fbb0af0534 - - filename: packages/contentstack-bulk-operations/test/unit/commands/bulk-entries.test.ts - checksum: 845512e660813a6d7d96efd89dcff6eba4591a3f9ff371dc9b1aad38921e18a6 - - filename: packages/contentstack-bulk-operations/test/unit/utils/revert-retry-handler.test.ts - checksum: 078f9633edb53204ed14ebe3cf6b1d6063729dd37b7ee1c6e936a344ceabebda - - filename: packages/contentstack-migrate-rte/src/lib/util/index.js - checksum: 7d85f342c7fd7875713cebfae83f68d8592cc732a15cca48ddecbeae818cb4c5 - - filename: packages/contentstack-cli-cm-regex-validate/src/utils/connect-stack.ts - checksum: c77c7c25efc6d043b26e3dd0a516e22ac50142fa9fa5ff3a53a7c9fb8f24ebd6 - - filename: packages/contentstack-bulk-operations/src/utils/config-builder.ts - checksum: a7b5259ad719b8c5929f9fea3783bdc92610dc2549426204c1bb6813e7e1112a - - filename: packages/contentstack-bulk-operations/README.md - checksum: 169110e7c6159632f19dc16e17dcb5bac22e5d6880339b35ba076a2fe0d75266 - - filename: packages/contentstack-bulk-operations/test/unit/utils/batch-queue-handler.test.ts - checksum: c91f1822b5cfd34a4f4ba05dfc56c10a66e0f5ddb55a1cf5b454fa9549ea0052 +- filename: packages/contentstack-import/src/import/modules/assets.ts + checksum: 85cac8ac469ccb8ac47f4430df5bf6cd0a5f8f4c2d165baabc8121d4ad63919d version: '1.0' diff --git a/packages/contentstack-import/src/import/module-importer.ts b/packages/contentstack-import/src/import/module-importer.ts index 2a6879c09..6e9243fa2 100755 --- a/packages/contentstack-import/src/import/module-importer.ts +++ b/packages/contentstack-import/src/import/module-importer.ts @@ -34,6 +34,12 @@ class ModuleImporter { const stackDetails: Record = await this.stackAPIClient.fetch(); this.importConfig.stackName = stackDetails.name as string; this.importConfig.org_uid = stackDetails.org_uid as string; + + const assetScanningEnabled = await this.detectAssetScanning(this.importConfig.org_uid); + if (assetScanningEnabled) { + this.importConfig.assetScanningEnabled = true; + this.importConfig.skipAssetsPublish = true; + } } await this.resolveImportPath(); @@ -209,6 +215,16 @@ class ModuleImporter { log.error(`Audit failed with following error. ${error}`, this.importConfig.context); } } + + private async detectAssetScanning(orgUid: string): Promise { + try { + const orgDetails = await this.managementAPIClient.organization(orgUid).fetch({ include_plan: true }); + const features: Array<{ uid: string; enabled?: boolean }> = orgDetails?.plan?.features || []; + return features.some((f) => (f.uid === 'assetsScan' || f.uid === 'amAssetsScan') && f.enabled === true); + } catch { + return false; + } + } } export default ModuleImporter; diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index e8b792f0b..ba7705b1b 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -79,6 +79,13 @@ export default class ImportAssets extends BaseClass { } log.success('Assets imported successfully!', this.importConfig.context); + + if (this.importConfig.assetScanningEnabled) { + log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); + log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); + log.info(' csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY]', this.importConfig.context); + } } catch (error) { handleAndLogError(error, { ...this.importConfig.context }); } diff --git a/packages/contentstack-import/src/types/import-config.ts b/packages/contentstack-import/src/types/import-config.ts index 2c4c9a000..70ca10a27 100644 --- a/packages/contentstack-import/src/types/import-config.ts +++ b/packages/contentstack-import/src/types/import-config.ts @@ -15,6 +15,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig { skipAssetsPublish?: boolean; skipEntriesPublish?: boolean; cliLogsPath: string; + assetScanningEnabled?: boolean; canCreatePrivateApp: boolean; contentDir: string; data: string; From 04726617b3658525272815cac5257268b125bbcf Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 5 Jun 2026 15:57:10 +0530 Subject: [PATCH 08/44] chore: fix failing test and lint issues --- .../src/base-bulk-command.ts | 3 +-- .../src/services/asset-service.ts | 18 ++++++++---------- .../services/bulk-operation-service.test.ts | 15 +++++---------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/packages/contentstack-bulk-operations/src/base-bulk-command.ts b/packages/contentstack-bulk-operations/src/base-bulk-command.ts index 567961bce..2693105fe 100644 --- a/packages/contentstack-bulk-operations/src/base-bulk-command.ts +++ b/packages/contentstack-bulk-operations/src/base-bulk-command.ts @@ -164,7 +164,7 @@ export abstract class BaseBulkCommand extends Command { } // Fill missing required flags via interactive prompts - flags = await this.resolveFlagsInteractively(flags); + flags = await this.resolveFlagsInteractively(flags); this.parsedFlags = flags; await this.buildConfiguration(flags); @@ -264,7 +264,6 @@ export abstract class BaseBulkCommand extends Command { } } - /** * Resolve flags interactively — subclasses can override to skip prompts for specific modes. */ diff --git a/packages/contentstack-bulk-operations/src/services/asset-service.ts b/packages/contentstack-bulk-operations/src/services/asset-service.ts index 903ce3730..562e316af 100644 --- a/packages/contentstack-bulk-operations/src/services/asset-service.ts +++ b/packages/contentstack-bulk-operations/src/services/asset-service.ts @@ -211,16 +211,14 @@ export class AssetService { try { while (hasMore) { - const query = this.stack - .asset() - .query({ - skip, - limit, - include_count: true, - include_publish_details: true, - include_asset_scan_status: true, - folder: folderUid, - }); + const query = this.stack.asset().query({ + skip, + limit, + include_count: true, + include_publish_details: true, + include_asset_scan_status: true, + folder: folderUid, + }); const response = await query.find(); const assets = response.items || []; diff --git a/packages/contentstack-bulk-operations/test/unit/services/bulk-operation-service.test.ts b/packages/contentstack-bulk-operations/test/unit/services/bulk-operation-service.test.ts index 60e1d6881..b34a84e20 100644 --- a/packages/contentstack-bulk-operations/test/unit/services/bulk-operation-service.test.ts +++ b/packages/contentstack-bulk-operations/test/unit/services/bulk-operation-service.test.ts @@ -132,7 +132,7 @@ describe('BulkOperationService', () => { content_type: 'blog', locale: 'en-us', version: 1, - publish_details: [], + publish_details: [{ environment: 'production', locale: 'en-us', version: 1 }], }, ]; @@ -168,7 +168,7 @@ describe('BulkOperationService', () => { content_type: 'blog', locale: 'en-us', version: 1, - publish_details: [], + publish_details: [{ environment: 'production', locale: 'en-us', version: 1 }], }, ]; @@ -390,14 +390,9 @@ describe('BulkOperationService', () => { } as EntryPublishData, ]; - const payload = (bulkOperationService as any).prepareBulkPayload( - mockItems, - OperationType.PUBLISH, - ResourceType.ENTRY - ); - - expect(payload.entries).to.have.lengthOf(1); - expect(payload.environments).to.deep.equal([]); + expect(() => + (bulkOperationService as any).prepareBulkPayload(mockItems, OperationType.PUBLISH, ResourceType.ENTRY) + ).to.throw('No environments for bulk publish'); }); }); From 33bd17aceafb8c0e758ccea6d715d7e4fa5f78ec Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Mon, 8 Jun 2026 12:48:52 +0530 Subject: [PATCH 09/44] feat: enhance bulk asset operations with data-dir support and user prompts --- .../src/commands/cm/stacks/bulk-assets.ts | 4 +-- .../src/messages/index.ts | 5 ++++ .../src/utils/interactive.ts | 25 +++++++++++++++++-- .../src/commands/cm/stacks/import.ts | 5 ++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts index 53bc50c1a..5c4770578 100644 --- a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts +++ b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts @@ -5,7 +5,7 @@ import { flags, handleAndLogError, log } from '@contentstack/cli-utilities'; import { AssetPublishData, BulkOperationResult, OperationType, ResourceType } from '../../../interfaces'; import { BaseBulkCommand } from '../../../base-bulk-command'; -import { $t, messages, fetchAssets, scanDataDirStats, BATCH_CONSTANTS, categorizeByScanStatus } from '../../../utils'; +import { $t, messages, fetchAssets, scanDataDirStats, BATCH_CONSTANTS, categorizeByScanStatus, fillMissingFlags } from '../../../utils'; import type { DataDirScanStats } from '../../../utils'; import { AssetService } from '../../../services'; @@ -63,7 +63,7 @@ export default class BulkAssets extends BaseBulkCommand { if (flags['data-dir']) { return flags; } - return super.resolveFlagsInteractively(flags); + return fillMissingFlags(flags, { promptDataDir: true }); } async run(): Promise { diff --git a/packages/contentstack-bulk-operations/src/messages/index.ts b/packages/contentstack-bulk-operations/src/messages/index.ts index ab7e6f7d9..c51fe6023 100644 --- a/packages/contentstack-bulk-operations/src/messages/index.ts +++ b/packages/contentstack-bulk-operations/src/messages/index.ts @@ -379,6 +379,11 @@ const interactiveMsg = { TAXONOMY_UNSUPPORTED_RETRY: 'Retry and revert are not supported for bulk-taxonomies.', TAXONOMY_UNSUPPORTED_CROSS_PUBLISH: 'Cross-publish is not supported for bulk-taxonomies.', + // Data-dir (backup folder) prompt + USE_DATA_DIR_PROMPT: 'Do you want to publish assets using publish details from an import backup folder (data-dir)?', + ENTER_DATA_DIR: 'Enter the path to the import backup folder (data-dir):', + DATA_DIR_REQUIRED: 'Backup folder path is required', + // Errors NO_DELIVERY_TOKENS_FOUND: 'No delivery token aliases found. Add one using: csdx auth:tokens:add -a --delivery-token --api-key --environment --type delivery', diff --git a/packages/contentstack-bulk-operations/src/utils/interactive.ts b/packages/contentstack-bulk-operations/src/utils/interactive.ts index 2aa68cdc1..a17485e9a 100644 --- a/packages/contentstack-bulk-operations/src/utils/interactive.ts +++ b/packages/contentstack-bulk-operations/src/utils/interactive.ts @@ -151,7 +151,7 @@ async function promptForSourceAlias(): Promise { /** * Fills in missing required flags by prompting the user */ -export async function fillMissingFlags(flags: any): Promise { +export async function fillMissingFlags(flags: any, options?: { promptDataDir?: boolean }): Promise { const updatedFlags = { ...flags }; // Skip interactive mode for retry/revert operations @@ -169,9 +169,10 @@ export async function fillMissingFlags(flags: any): Promise { // Check if non-localized filter is used const isNonLocalized = updatedFlags.filter === FilterType.NON_LOCALIZED; const needsLocales = !isNonLocalized && (!updatedFlags.locales || updatedFlags.locales.length === 0); + const needsDataDir = options?.promptDataDir && !updatedFlags['data-dir']; // Only show interactive mode header if we need to prompt - if (needsCredentials || needsOperation || needsEnvironments || needsLocales) { + if (needsCredentials || needsOperation || needsEnvironments || needsLocales || needsDataDir) { cliux.print(messages.INTERACTIVE_MODE_START, { color: 'cyan' }); didPrompt = true; } @@ -191,6 +192,26 @@ export async function fillMissingFlags(flags: any): Promise { updatedFlags.operation = await promptForOperation(); } + // 2.5. Data-dir (import backup folder) — alternative to environments/locales for asset publish + if (needsDataDir) { + const useDataDir = await cliux.inquire({ + type: 'confirm', + name: 'useDataDir', + message: messages.USE_DATA_DIR_PROMPT, + default: false, + }); + if (useDataDir) { + updatedFlags['data-dir'] = await cliux.inquire({ + type: 'input', + name: 'dataDir', + message: messages.ENTER_DATA_DIR, + validate: (v: string) => (!v?.trim() ? messages.DATA_DIR_REQUIRED : true), + }); + cliux.print(messages.INTERACTIVE_MODE_COMPLETE, { color: 'green' }); + return updatedFlags; + } + } + // 3. Check for cross-publish mode const isCrossPublish = updatedFlags['source-env'] || updatedFlags['source-alias']; diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 1d56aca9a..b1aadbb72 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -159,6 +159,11 @@ export default class ImportCommand extends Command { backupDir = importConfig.backupDir; //Note: Final summary is now handled by summary manager CLIProgressManager.printGlobalSummary(); + if (importConfig.assetScanningEnabled) { + cliux.print('\nAsset Scanning is enabled — assets were not published.', { color: 'yellow' }); + cliux.print(' Once scanning completes, publish your assets using:', { color: 'yellow' }); + cliux.print(` csdx cm:stacks:bulk-assets --data-dir ${backupDir} --stack-api-key ${importConfig.apiKey}`, { color: 'cyan' }); + } this.logSuccessAndBackupMessages(backupDir, importConfig); // Clear progress module setting now that import is complete clearProgressModuleSetting(); From 4e091242f171e2e15bdca4a7b3c36ff2d644631f Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Mon, 8 Jun 2026 12:49:33 +0530 Subject: [PATCH 10/44] chore: update talisman --- .talismanrc | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/.talismanrc b/.talismanrc index ca3f83227..736fbb319 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,26 +1,6 @@ fileignoreconfig: - filename: pnpm-lock.yaml checksum: acb2fc21dd3481f162aedaccecbe45d565b3297957345044a12aa50d2850ac4e -- filename: packages/contentstack-variants/test/unit/import/experiences.test.ts - checksum: 6142418bafea6454a72b313d933deb494ce4ea1d8cead7ef918c10e283c2c603 -- filename: packages/contentstack-variants/test/unit/export/variant-entries.test.ts - checksum: e150faeefa7b3586b70a6f454c1f68efe05526f582977dba28243b1e47606a42 -- filename: packages/contentstack-variants/test/unit/export/experiences.test.ts - checksum: eb9c989dd14373a90e8866ba3350245d3c06e8ba43cfebb24f40c1106b2e6b95 -- filename: packages/contentstack-variants/test/unit/utils/personalization-api-adapter.test.ts - checksum: d729c9586d3a19e321d79e490790b9d0aa345f81917376199d962de68317fae1 -- filename: packages/contentstack-variants/test/unit/import/variant-entries.test.ts - checksum: 1337a680c98cfa7d4be2e48db284c8e44866f5eee1e72afb4ba52c2264c3850f -- filename: packages/contentstack-export/src/export/modules/taxonomies.ts - checksum: b6d077118280bc88385405f504f921468a9fd490ac37a4a21f741be729fd1ca3 -- filename: packages/contentstack-import/test/unit/import/modules/base-class.test.ts - checksum: fe372852d5f2f3f57ef62c603406c30ccecdb444c17133ac0b21dda399b962c0 -- filename: packages/contentstack-export/test/unit/export/modules/taxonomies.test.ts - checksum: cab2ad4d897d23f04f988c1f018a9583ab7f0ee1815994d7bc9fce23dea70073 -- filename: packages/contentstack-query-export/src/core/query-executor.ts - checksum: 708f8a9bc837ed15342fe73920588978a97cab9002c401dbc6ad7030e0238f48 -- filename: packages/contentstack-bulk-operations/test/unit/commands/bulk-am-assets.test.ts - checksum: f8d21db7db0ca2eebe7cc40af0a59f02e74e1689efb6d50a1072dc5ca3e03e9b -- filename: packages/contentstack-asset-management/src/query-export/cs-assets-query-exporter.ts - checksum: f7d03d649ab0b6d45985fcd9bd8ae374ea34ad5c44cb9365af92b3c9ae4728e6 +- filename: packages/contentstack-import/src/commands/cm/stacks/import.ts + checksum: d50d85534c8779b99e46b0fb8a765c0b4e5a30881007346852c254e8e2604c03 version: '1.0' From 25acf4961173f2f67f475ff1766092518fb23532 Mon Sep 17 00:00:00 2001 From: Naman Dembla Date: Tue, 9 Jun 2026 11:48:22 +0530 Subject: [PATCH 11/44] chore: removed whitespace --- packages/contentstack-import/src/import/modules/assets.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index ba7705b1b..ebdd2bf89 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -81,10 +81,10 @@ export default class ImportAssets extends BaseClass { log.success('Assets imported successfully!', this.importConfig.context); if (this.importConfig.assetScanningEnabled) { - log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); - log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); - log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); - log.info(' csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY]', this.importConfig.context); + log.info('Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info('Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); + log.info('Once scanning is done, publish your assets using:', this.importConfig.context); + log.info('csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY]', this.importConfig.context); } } catch (error) { handleAndLogError(error, { ...this.importConfig.context }); From 8bb7e4331218cf0045a8d58d89debfd5c471da87 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Tue, 9 Jun 2026 12:21:01 +0530 Subject: [PATCH 12/44] chore: lint fixes --- .../src/commands/cm/stacks/bulk-assets.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts index 5c4770578..e8bfc9835 100644 --- a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts +++ b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts @@ -5,7 +5,15 @@ import { flags, handleAndLogError, log } from '@contentstack/cli-utilities'; import { AssetPublishData, BulkOperationResult, OperationType, ResourceType } from '../../../interfaces'; import { BaseBulkCommand } from '../../../base-bulk-command'; -import { $t, messages, fetchAssets, scanDataDirStats, BATCH_CONSTANTS, categorizeByScanStatus, fillMissingFlags } from '../../../utils'; +import { + $t, + messages, + fetchAssets, + scanDataDirStats, + BATCH_CONSTANTS, + categorizeByScanStatus, + fillMissingFlags, +} from '../../../utils'; import type { DataDirScanStats } from '../../../utils'; import { AssetService } from '../../../services'; From 1b6fb69558e620f24c2ff4fc6178a1a88d5bd6f1 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Wed, 10 Jun 2026 14:41:38 +0530 Subject: [PATCH 13/44] feat: add asset scanning support in bulk publish v1 --- .../contentstack-bulk-publish/.mocharc.json | 3 +- .../src/producer/publish-assets.js | 168 ++++++++++++++++-- .../src/util/asset-scan.js | 121 +++++++++++++ .../test/unit/util/asset-scan.test.js | 162 +++++++++++++++++ 4 files changed, 434 insertions(+), 20 deletions(-) create mode 100644 packages/contentstack-bulk-publish/src/util/asset-scan.js create mode 100644 packages/contentstack-bulk-publish/test/unit/util/asset-scan.test.js diff --git a/packages/contentstack-bulk-publish/.mocharc.json b/packages/contentstack-bulk-publish/.mocharc.json index 50e4a6804..3d76d7307 100644 --- a/packages/contentstack-bulk-publish/.mocharc.json +++ b/packages/contentstack-bulk-publish/.mocharc.json @@ -5,7 +5,8 @@ "test/unit/commands/assets/unpublish.test.js", "test/unit/commands/bulk-publish/cross-publish.test.js", "test/unit/commands/entries/publish.test.js", - "test/unit/commands/entries/unpublish.test.js" + "test/unit/commands/entries/unpublish.test.js", + "test/unit/util/asset-scan.test.js" ], "reporter": "dot", "timeout": 60000, diff --git a/packages/contentstack-bulk-publish/src/producer/publish-assets.js b/packages/contentstack-bulk-publish/src/producer/publish-assets.js index a9afbdd7c..777ed31d4 100644 --- a/packages/contentstack-bulk-publish/src/producer/publish-assets.js +++ b/packages/contentstack-bulk-publish/src/producer/publish-assets.js @@ -1,6 +1,7 @@ /* eslint-disable no-console */ /* eslint-disable new-cap */ /* eslint-disable camelcase */ +const chalk = require('chalk'); const { cliux } = require('@contentstack/cli-utilities'); const { getQueue } = require('../util/queue'); const { performBulkPublish, publishAsset, initializeLogger } = require('../consumer/publish'); @@ -9,14 +10,27 @@ const { validateFile } = require('../util/fs'); const { isEmpty } = require('../util'); const { fetchBulkPublishLimit } = require('../util/common-utility'); const { generateBulkPublishStatusUrl } = require('../util/generate-bulk-publish-url'); +const { resolveInQueueAssets, ASSET_SCAN_STATUS } = require('../util/asset-scan'); const queue = getQueue(); let logFileName; let bulkPublishSet = []; +let pendingAssetsForRetry = []; +let scanSummary = { clean: 0, quarantined: 0, inQueue: 0, noStatus: 0 }; let filePath; /* eslint-disable no-param-reassign */ +function printScanSummary({ clean, noStatus, inQueue, quarantined }) { + const total = clean + noStatus + inQueue + quarantined; + if (total === 0) return; + console.log(chalk.bold(`\nAsset scan summary (${total} total):`)); + console.log(chalk.green(` ✓ Clean (publishing): ${clean}`)); + if (noStatus > 0) console.log(chalk.green(` ✓ No scan status (publishing): ${noStatus}`)); + if (inQueue > 0) console.log(chalk.yellow(` ⧖ In queue (retrying): ${inQueue}`)); + if (quarantined > 0) console.log(chalk.red(` ✗ Quarantined (skipped): ${quarantined}`)); +} + async function getAssets(stack, folder, bulkPublish, environments, locale, apiVersion, bulkPublishLimit, skip = 0) { return new Promise((resolve, reject) => { let queryParams = { @@ -25,6 +39,7 @@ async function getAssets(stack, folder, bulkPublish, environments, locale, apiVe include_count: true, include_folders: true, include_publish_details: true, + include_asset_scan_status: true, }; stack .asset() @@ -34,7 +49,8 @@ async function getAssets(stack, folder, bulkPublish, environments, locale, apiVe if (assetResponse && assetResponse.items.length > 0) { skip += assetResponse.items.length; let assets = assetResponse.items; - for (let index = 0; index < assetResponse.items.length; index++) { + + for (let index = 0; index < assets.length; index++) { if (assets[index].is_dir === true) { await getAssets( stack, @@ -48,6 +64,35 @@ async function getAssets(stack, folder, bulkPublish, environments, locale, apiVe ); continue; } + + const scanStatus = assets[index]._asset_scan_status; + + // Quarantined assets are skipped permanently + if (scanStatus === ASSET_SCAN_STATUS.QUARANTINE) { + scanSummary.quarantined++; + console.log(chalk.yellow(`Skipped (quarantined): Asset UID '${assets[index].uid}'`)); + continue; + } + + // In-queue assets are deferred for retry after all pages are processed + if (scanStatus === ASSET_SCAN_STATUS.IN_QUEUE) { + scanSummary.inQueue++; + pendingAssetsForRetry.push({ + uid: assets[index].uid, + locale, + publish_details: assets[index].publish_details || [], + environments, + }); + continue; + } + + // Ready (clean) or no scan status — enqueue for publish + if (scanStatus === ASSET_SCAN_STATUS.READY) { + scanSummary.clean++; + } else { + scanSummary.noStatus++; + } + if (bulkPublish) { if (bulkPublishSet.length < bulkPublishLimit) { bulkPublishSet.push({ @@ -67,22 +112,6 @@ async function getAssets(stack, folder, bulkPublish, environments, locale, apiVe }); bulkPublishSet = []; } - - if ( - assetResponse.items.length - 1 === index && - bulkPublishSet.length > 0 && - bulkPublishSet.length < bulkPublishLimit - ) { - await queue.Enqueue({ - assets: bulkPublishSet, - Type: 'asset', - environments: environments, - locale, - stack: stack, - apiVersion, - }); - bulkPublishSet = []; - } } else { await queue.Enqueue({ assetUid: assets[index].uid, @@ -94,6 +123,23 @@ async function getAssets(stack, folder, bulkPublish, environments, locale, apiVe }); } } + + // Flush any partial bulk batch at the end of the page. + // Done outside the for-loop so it fires correctly even when some assets + // were skipped (quarantined/in-queue) and the last non-skipped asset is + // not at the final array index. + if (bulkPublish && bulkPublishSet.length > 0) { + await queue.Enqueue({ + assets: bulkPublishSet, + Type: 'asset', + environments: environments, + locale, + stack: stack, + apiVersion, + }); + bulkPublishSet = []; + } + if (skip === assetResponse.count) { return resolve(true); } @@ -109,6 +155,78 @@ async function getAssets(stack, folder, bulkPublish, environments, locale, apiVe }); } +/** + * After all pages/locales are scanned, retry any assets that were in-queue. + * Takes pendingItems explicitly — does not read from module-level state. + * Uses incremental backoff (see asset-scan.js SCAN_RETRY config). + */ +async function processPendingAssets(pendingItems, stack, bulkPublish, environments, apiVersion, bulkPublishLimit) { + if (pendingItems.length === 0) return; + + // Deduplicate UIDs across locales — scan status is per-asset, not per-locale. + // Resolving once avoids redundant retry loops for multi-locale runs. + const allUids = [...new Set(pendingItems.map((a) => a.uid))]; + const resolvedUids = await resolveInQueueAssets(stack, allUids); + + if (resolvedUids.length === 0) { + console.log(chalk.yellow('No in-queue assets resolved after retries.')); + return; + } + + const resolvedSet = new Set(resolvedUids); + + // Group resolved items by locale for correct enqueue context + const byLocale = {}; + for (const item of pendingItems) { + if (!resolvedSet.has(item.uid)) continue; + if (!byLocale[item.locale]) byLocale[item.locale] = []; + byLocale[item.locale].push(item); + } + + for (const locale of Object.keys(byLocale)) { + const resolvedItems = byLocale[locale]; + + if (bulkPublish) { + let batchSet = []; + for (const item of resolvedItems) { + batchSet.push({ uid: item.uid, locale, publish_details: item.publish_details }); + if (batchSet.length === bulkPublishLimit) { + await queue.Enqueue({ + assets: batchSet, + Type: 'asset', + environments, + locale, + stack, + apiVersion, + }); + batchSet = []; + } + } + if (batchSet.length > 0) { + await queue.Enqueue({ + assets: batchSet, + Type: 'asset', + environments, + locale, + stack, + apiVersion, + }); + } + } else { + for (const item of resolvedItems) { + await queue.Enqueue({ + assetUid: item.uid, + publish_details: item.publish_details, + environments, + Type: 'asset', + locale, + stack, + }); + } + } + } +} + function setConfig(conf, bp) { if (bp) { queue.consumer = performBulkPublish; @@ -120,6 +238,8 @@ function setConfig(conf, bp) { config = conf; queue.config = conf; filePath = initializeLogger(logFileName); + pendingAssetsForRetry = []; + scanSummary = { clean: 0, quarantined: 0, inQueue: 0, noStatus: 0 }; } async function start({ retryFailed, bulkPublish, environments, folderUid, locales, apiVersion }, stack, config) { @@ -131,7 +251,7 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale } else if (!isSuccessLogEmpty) { console.log(`The success log for this session is stored at ${filePath}.success`); } - + // Generate and display the bulk publish status link if (bulkPublish && stack && config) { const statusUrl = generateBulkPublishStatusUrl(stack, config); @@ -142,11 +262,12 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale process.stdout.write('\n'); } } - + process.exit(0); }); if (retryFailed) { + console.log(chalk.yellow('Note: --retry-failed replays from log and skips asset scan status checks.')); if (!validateFile(retryFailed, ['publish-assets', 'bulk-publish-assets'])) { return false; } @@ -165,6 +286,14 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale for (const locale of locales) { await getAssets(stack, folderUid, bulkPublish, environments, locale, apiVersion, bulkPublishLimit); } + + printScanSummary(scanSummary); + + // Resolve in-queue assets with incremental retry; pass pendingAssetsForRetry explicitly + if (pendingAssetsForRetry.length > 0) { + await processPendingAssets(pendingAssetsForRetry, stack, bulkPublish, environments, apiVersion, bulkPublishLimit); + pendingAssetsForRetry = []; + } } } @@ -172,4 +301,5 @@ module.exports = { getAssets, setConfig, start, + processPendingAssets, }; diff --git a/packages/contentstack-bulk-publish/src/util/asset-scan.js b/packages/contentstack-bulk-publish/src/util/asset-scan.js new file mode 100644 index 000000000..9c9f3f0d1 --- /dev/null +++ b/packages/contentstack-bulk-publish/src/util/asset-scan.js @@ -0,0 +1,121 @@ +/* eslint-disable no-console */ +const chalk = require('chalk'); + +const ASSET_SCAN_STATUS = { + READY: 'clean', + QUARANTINE: 'quarantined', + IN_QUEUE: 'pending', +}; + +const SCAN_RETRY = { + MAX_RETRIES: 5, + INITIAL_WAIT_MS: 5000, + BACKOFF_FACTOR: 2, +}; + +function getIncrementalWaitMs(attempt) { + return SCAN_RETRY.INITIAL_WAIT_MS * Math.pow(SCAN_RETRY.BACKOFF_FACTOR, attempt); +} + +/** + * Batch-fetch asset scan statuses for a list of UIDs. + * Returns a Map. UIDs with no scan data map to undefined. + * Throws on API error — callers must not silently treat failures as "ready". + */ +async function fetchScanStatusBatch(stack, uids) { + const statusMap = new Map(); + if (!uids || uids.length === 0) return statusMap; + + const BATCH_SIZE = 100; + for (let i = 0; i < uids.length; i += BATCH_SIZE) { + const batch = uids.slice(i, i + BATCH_SIZE); + const response = await stack + .asset() + .query({ uid: { $in: batch }, include_asset_scan_status: true, limit: BATCH_SIZE }) + .find(); + for (const asset of response.items || []) { + statusMap.set(asset.uid, asset._asset_scan_status); + } + } + + return statusMap; +} + +/** + * Retry pending (in-queue) assets with incremental backoff until they become + * clean or max retries is reached. + * + * Wait series: 5s, 10s, 20s, 40s, 80s (5 attempts total, max 155s). + * + * @param {object} stack - Management SDK stack instance + * @param {string[]} pendingUids - UIDs currently in scan queue + * @returns {string[]} UIDs that became clean and are safe to publish + */ +async function resolveInQueueAssets(stack, pendingUids) { + if (!pendingUids || pendingUids.length === 0) return []; + + const totalWaitSec = + Array.from({ length: SCAN_RETRY.MAX_RETRIES }, (_, i) => getIncrementalWaitMs(i)).reduce( + (a, b) => a + b, + 0, + ) / 1000; + console.log( + chalk.yellow( + `Resolving ${pendingUids.length} in-queue asset(s). Max wait: ${totalWaitSec}s over ${SCAN_RETRY.MAX_RETRIES} retries.`, + ), + ); + + let remaining = [...pendingUids]; + const resolvedUids = []; + + for (let attempt = 0; attempt < SCAN_RETRY.MAX_RETRIES && remaining.length > 0; attempt++) { + const waitMs = getIncrementalWaitMs(attempt); + console.log( + chalk.yellow( + `Asset scan: ${remaining.length} asset(s) in queue. Waiting ${waitMs / 1000}s before retry ${attempt + 1}/${ + SCAN_RETRY.MAX_RETRIES + }...`, + ), + ); + + await new Promise((resolve) => setTimeout(resolve, waitMs)); + + const statusMap = await fetchScanStatusBatch(stack, remaining); + const stillPending = []; + + for (const uid of remaining) { + const status = statusMap.get(uid); + if (status === ASSET_SCAN_STATUS.QUARANTINE) { + console.log(chalk.red(`Skipped (quarantined after retry): Asset UID '${uid}'`)); + } else if (status === ASSET_SCAN_STATUS.IN_QUEUE) { + stillPending.push(uid); + } else { + // clean or undefined (scanning disabled) — publishable + resolvedUids.push(uid); + } + } + + remaining = stillPending; + } + + if (remaining.length > 0) { + console.warn( + chalk.red( + `Asset scan: ${remaining.length} asset(s) remained in queue after ${SCAN_RETRY.MAX_RETRIES} retries and will be skipped.`, + ), + ); + for (const uid of remaining) { + console.warn(chalk.red(`Skipped (max retries exceeded): Asset UID '${uid}'`)); + } + } + + return resolvedUids; +} + +module.exports = { + ASSET_SCAN_STATUS, + SCAN_RETRY, + getIncrementalWaitMs, + fetchScanStatusBatch, + resolveInQueueAssets, +}; diff --git a/packages/contentstack-bulk-publish/test/unit/util/asset-scan.test.js b/packages/contentstack-bulk-publish/test/unit/util/asset-scan.test.js new file mode 100644 index 000000000..83b430bde --- /dev/null +++ b/packages/contentstack-bulk-publish/test/unit/util/asset-scan.test.js @@ -0,0 +1,162 @@ +'use strict'; + +const { describe, it, beforeEach, afterEach } = require('mocha'); +const { expect } = require('chai'); + +const { + ASSET_SCAN_STATUS, + SCAN_RETRY, + getIncrementalWaitMs, + fetchScanStatusBatch, + resolveInQueueAssets, +} = require('../../../src/util/asset-scan'); + +// Minimal mock stack factory +function makeStack(items) { + return { + asset() { + return { + query() { + return { + find: async () => ({ items: items || [] }), + }; + }, + }; + }, + }; +} + +// Stack that throws on query +function makeErrorStack(errorMsg) { + return { + asset() { + return { + query() { + return { + find: async () => { + throw new Error(errorMsg); + }, + }; + }, + }; + }, + }; +} + +describe('asset-scan utilities', () => { + // ─── getIncrementalWaitMs ──────────────────────────────────────────────── + + describe('getIncrementalWaitMs', () => { + it('returns INITIAL_WAIT_MS for attempt 0', () => { + expect(getIncrementalWaitMs(0)).to.equal(SCAN_RETRY.INITIAL_WAIT_MS); + }); + + it('doubles on each subsequent attempt', () => { + const seq = [0, 1, 2, 3, 4].map(getIncrementalWaitMs); + for (let i = 1; i < seq.length; i++) { + expect(seq[i]).to.equal(seq[i - 1] * SCAN_RETRY.BACKOFF_FACTOR); + } + }); + + it('produces the correct 5-attempt sequence', () => { + const expected = [5000, 10000, 20000, 40000, 80000]; + expected.forEach((ms, attempt) => { + expect(getIncrementalWaitMs(attempt)).to.equal(ms); + }); + }); + }); + + // ─── fetchScanStatusBatch ─────────────────────────────────────────────── + + describe('fetchScanStatusBatch', () => { + it('returns empty Map when called with empty uid array', async () => { + const map = await fetchScanStatusBatch(makeStack([]), []); + expect(map.size).to.equal(0); + }); + + it('maps UIDs to their scan statuses', async () => { + const items = [ + { uid: 'a1', _asset_scan_status: 'clean' }, + { uid: 'a2', _asset_scan_status: 'quarantined' }, + { uid: 'a3', _asset_scan_status: 'pending' }, + ]; + const map = await fetchScanStatusBatch(makeStack(items), ['a1', 'a2', 'a3']); + expect(map.get('a1')).to.equal(ASSET_SCAN_STATUS.READY); + expect(map.get('a2')).to.equal(ASSET_SCAN_STATUS.QUARANTINE); + expect(map.get('a3')).to.equal(ASSET_SCAN_STATUS.IN_QUEUE); + }); + + it('maps UIDs with no scan field to undefined', async () => { + const items = [{ uid: 'a1' }]; + const map = await fetchScanStatusBatch(makeStack(items), ['a1']); + expect(map.get('a1')).to.equal(undefined); + }); + + it('throws on API error (fail fast — do not silently treat as ready)', async () => { + try { + await fetchScanStatusBatch(makeErrorStack('Network error'), ['a1']); + expect.fail('Expected fetchScanStatusBatch to throw'); + } catch (error) { + expect(error.message).to.equal('Network error'); + } + }); + }); + + // ─── resolveInQueueAssets ─────────────────────────────────────────────── + + describe('resolveInQueueAssets', () => { + let originalSetTimeout; + + beforeEach(() => { + // Replace setTimeout with an immediate resolver to avoid real waits + originalSetTimeout = global.setTimeout; + global.setTimeout = (fn) => fn(); + }); + + afterEach(() => { + global.setTimeout = originalSetTimeout; + }); + + it('returns empty array for empty input without calling stack', async () => { + const result = await resolveInQueueAssets(makeStack([]), []); + expect(result).to.deep.equal([]); + }); + + it('resolves UIDs that become clean on the first retry', async () => { + const items = [{ uid: 'a1', _asset_scan_status: 'clean' }]; + const result = await resolveInQueueAssets(makeStack(items), ['a1']); + expect(result).to.include('a1'); + }); + + it('excludes UIDs that become quarantined during retry', async () => { + const items = [{ uid: 'a1', _asset_scan_status: 'quarantined' }]; + const result = await resolveInQueueAssets(makeStack(items), ['a1']); + expect(result).to.not.include('a1'); + }); + + it('resolves UIDs with no scan status (scanning disabled)', async () => { + const items = [{ uid: 'a1' }]; // no _asset_scan_status field + const result = await resolveInQueueAssets(makeStack(items), ['a1']); + expect(result).to.include('a1'); + }); + + it('drops UIDs still pending after MAX_RETRIES', async () => { + // Always returns pending status + const items = [{ uid: 'a1', _asset_scan_status: 'pending' }]; + const result = await resolveInQueueAssets(makeStack(items), ['a1']); + expect(result).to.deep.equal([]); + }); + + it('handles mixed outcomes: clean, quarantined, and pending exhausted', async () => { + const items = [ + { uid: 'clean1', _asset_scan_status: 'clean' }, + { uid: 'quar1', _asset_scan_status: 'quarantined' }, + { uid: 'pend1', _asset_scan_status: 'pending' }, + ]; + const result = await resolveInQueueAssets(makeStack(items), ['clean1', 'quar1', 'pend1']); + expect(result).to.include('clean1'); + expect(result).to.not.include('quar1'); + expect(result).to.not.include('pend1'); + }); + }); +}); From 420c32e34f1df0a78bdca70ea4560bc4db92fe2a Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 12 Jun 2026 01:29:42 +0530 Subject: [PATCH 14/44] feat: enhance asset publishing with data-dir support for post-import flow --- .talismanrc | 4 +- .../src/commands/cm/assets/publish.js | 20 +- .../src/producer/publish-assets.js | 226 +++++++++++++++++- .../src/import/modules/assets.ts | 5 +- 4 files changed, 247 insertions(+), 8 deletions(-) diff --git a/.talismanrc b/.talismanrc index 51f9d046d..5354972f8 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,4 @@ fileignoreconfig: -- filename: packages/contentstack-import/src/import/modules/assets.ts - checksum: 85cac8ac469ccb8ac47f4430df5bf6cd0a5f8f4c2d165baabc8121d4ad63919d +- filename: packages/contentstack-bulk-publish/src/producer/publish-assets.js + checksum: 584bed451d8a916fd2629e93583206d3a39d40a7ff05b43a7b9a0e78c688fa2f version: '1.0' diff --git a/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js b/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js index a032678c0..3aecb2c8e 100644 --- a/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js +++ b/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js @@ -15,10 +15,12 @@ class AssetsPublishCommand extends Command { assetsFlags.folderUid = assetsFlags['folder-uid'] || assetsFlags.folderUid; assetsFlags.bulkPublish = assetsFlags['bulk-publish'] || assetsFlags.bulkPublish; assetsFlags.apiVersion = assetsFlags['api-version'] || '3'; // setting default value for apiVersion + assetsFlags.dataDir = assetsFlags['data-dir'] || assetsFlags.dataDir; delete assetsFlags['api-version']; delete assetsFlags['retry-failed']; delete assetsFlags['folder-uid']; delete assetsFlags['bulk-publish']; + delete assetsFlags['data-dir']; let updatedFlags; try { @@ -111,12 +113,18 @@ class AssetsPublishCommand extends Command { } } - validate({ environments, retryFailed, locales, 'source-env': sourceEnv, 'delivery-token': deliveryToken }) { + validate({ environments, retryFailed, locales, dataDir, 'source-env': sourceEnv, 'delivery-token': deliveryToken }) { let missing = []; if (retryFailed) { return true; } + // In data-dir mode, environments and locales are derived per-asset from the + // backup publish_details, so they are not required on the command line. + if (dataDir) { + return true; + } + if (sourceEnv && !deliveryToken) { this.error('Specify the source environment delivery token. Run --help for more details.', { exit: 2 }); } @@ -181,6 +189,11 @@ AssetsPublishCommand.flags = { '(optional) The UID of the Assets’ folder from which the assets need to be published. The default value is cs_root.', exclusive: ['source-env'], }), + 'data-dir': flags.string({ + description: + '(optional) Path to the import backup directory. When set, each imported asset is published only to the environments and locales it was published to in the source stack (read from the backup’s publish details and asset UID mapping), with asset-scan gating applied. Intended for the post-import publish flow.', + exclusive: ['source-env', 'folder-uid'], + }), 'bulk-publish': flags.string({ description: 'Set this flag to use Contentstack’s Bulk Publish APIs. It is true, by default.', default: 'true', @@ -259,11 +272,14 @@ AssetsPublishCommand.examples = [ '', 'Using --stack-api-key flag', 'csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY]', + '', + 'Using --data-dir flag (publish imported assets to their original environments after asset scanning)', + 'csdx cm:assets:publish --data-dir [PATH TO IMPORT BACKUP DIR] --stack-api-key [STACK API KEY]', ]; AssetsPublishCommand.aliases = ['cm:bulk-publish:assets']; AssetsPublishCommand.usage = - 'cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]'; + 'cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--data-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]'; module.exports = AssetsPublishCommand; diff --git a/packages/contentstack-bulk-publish/src/producer/publish-assets.js b/packages/contentstack-bulk-publish/src/producer/publish-assets.js index 777ed31d4..edee00ed1 100644 --- a/packages/contentstack-bulk-publish/src/producer/publish-assets.js +++ b/packages/contentstack-bulk-publish/src/producer/publish-assets.js @@ -1,8 +1,10 @@ /* eslint-disable no-console */ /* eslint-disable new-cap */ /* eslint-disable camelcase */ +const path = require('path'); +const { existsSync } = require('fs'); const chalk = require('chalk'); -const { cliux } = require('@contentstack/cli-utilities'); +const { cliux, FsUtility } = require('@contentstack/cli-utilities'); const { getQueue } = require('../util/queue'); const { performBulkPublish, publishAsset, initializeLogger } = require('../consumer/publish'); const retryFailedLogs = require('../util/retryfailed'); @@ -10,7 +12,7 @@ const { validateFile } = require('../util/fs'); const { isEmpty } = require('../util'); const { fetchBulkPublishLimit } = require('../util/common-utility'); const { generateBulkPublishStatusUrl } = require('../util/generate-bulk-publish-url'); -const { resolveInQueueAssets, ASSET_SCAN_STATUS } = require('../util/asset-scan'); +const { resolveInQueueAssets, fetchScanStatusBatch, ASSET_SCAN_STATUS } = require('../util/asset-scan'); const queue = getQueue(); let logFileName; @@ -227,6 +229,216 @@ async function processPendingAssets(pendingItems, stack, bulkPublish, environmen } } +/** + * Publish assets from an import backup directory (post-import flow). + * + * Unlike getAssets (live folder scan), this drives publishing from the backup: + * each imported asset is published ONLY to the environments/locales it was + * published to in the source stack (from its publish_details), remapped to the + * target stack. Scan-status gating is applied to the target asset UIDs. + * + * Mirrors the publish_details/env-name resolution of contentstack-import's + * assets `publish()` (the bulk publish API resolves environment NAMES against + * the target stack, and import preserves env names, so source name == target + * name), and adds the clean/quarantined/in-queue scan gating that import skips. + * + * Source of truth split: + * - publish_details + environments come from the BACKUP (post-import flow): an + * asset's target environments are its source publish_details, gated by the + * environment uid-mapping (only environments actually imported into the target + * are publishable) — avoids doomed publish calls to envs never created there. + * - scan status comes from the LIVE target API (it is a runtime property of the + * freshly-imported assets and cannot exist in the backup). + * + * Streaming: asset chunks are processed and released one at a time and scan-gated + * per chunk, so memory does not scale with total asset count. The only structures + * retained across chunks are bounded (partial publish batches + the in-queue + * subset). The single in-memory floor is the asset uid-mapping file itself (same + * as import's publish()); for very large stacks raise Node's --max-old-space-size. + */ +async function getAssetsFromBackup(stack, dataDir, bulkPublish, apiVersion, bulkPublishLimit) { + const assetsPath = path.join(dataDir, 'assets'); + const assetsIndexPath = path.join(assetsPath, 'assets.json'); + const assetUidMapperPath = path.join(dataDir, 'mapper', 'assets', 'uid-mapping.json'); + const envUidMapperPath = path.join(dataDir, 'mapper', 'environments', 'uid-mapping.json'); + const environmentsPath = path.join(dataDir, 'environments', 'environments.json'); + + // Fail fast with actionable errors when the backup is incomplete. + if (!existsSync(assetsPath) || !existsSync(assetsIndexPath)) { + throw new Error(`No assets found in backup. Expected '${assetsIndexPath}'. Check the --data-dir path.`); + } + if (!existsSync(assetUidMapperPath)) { + throw new Error( + `Asset UID mapping not found at '${assetUidMapperPath}'. Run import against this data dir before publishing.`, + ); + } + if (!existsSync(environmentsPath)) { + throw new Error(`Environments not found at '${environmentsPath}'. Cannot resolve target environments.`); + } + + const fsUtil = new FsUtility({ basePath: assetsPath, indexFileName: 'assets.json' }); + const assetUidMap = fsUtil.readFile(assetUidMapperPath, true) || {}; + // environments.json: { [sourceEnvUid]: { name, ... } } — source env definitions. + const environments = fsUtil.readFile(environmentsPath, true) || {}; + // uid-mapping.json: { [sourceEnvUid]: targetEnvUid } — only environments actually + // imported into the target. Used as the "is publishable" gate. Optional: older + // backups (or runs with no imported environments) may not have it. + const envUidMapping = existsSync(envUidMapperPath) ? fsUtil.readFile(envUidMapperPath, true) || {} : null; + if (!envUidMapping) { + console.log( + chalk.yellow( + `Environment UID mapping not found at '${envUidMapperPath}'. Falling back to environment names from ` + + `environments.json — ensure the target stack has environments with matching names.`, + ), + ); + } + const isEnvImported = (sourceEnvUid) => + !envUidMapping || Object.prototype.hasOwnProperty.call(envUidMapping, sourceEnvUid); + + // Resolve an asset's deduped, env-gated target (envName, locale) pairs from its + // publish_details. Env name comes from the backup; only environments actually + // imported into the target (per the env uid-mapping) are publishable. + const resolvePairs = (asset) => { + const seen = new Set(); + const pairs = []; + for (const pd of asset.publish_details) { + const env = environments[pd.environment]; + if (!env || !env.name) continue; // env not in the data dir — cannot resolve a name + if (!isEnvImported(pd.environment)) continue; // env not imported into target — skip + const key = `${env.name}||${pd.locale}`; + if (seen.has(key)) continue; + seen.add(key); + pairs.push({ envName: env.name, locale: pd.locale }); + } + return pairs; + }; + + // Bounded cross-chunk state only — nothing scales with total asset count: + // - `buffers`: partial publish batches, capped at envCount x localeCount x bulkPublishLimit. + // - `pending`: the in-queue (scanning) subset awaiting retry. + // The full asset universe is never held in memory; chunks are processed and + // released one at a time (same streaming shape as contentstack-import's publish()). + const buffers = new Map(); // "envName||locale" -> { envName, locale, uids: [] } + const pending = []; // { targetUid, pairs } for assets whose scan is still in queue + let skippedNoUidMapping = 0; // source asset was not imported (no asset uid mapping) + let skippedNoMappableEnv = 0; // asset has publish details, but none of its envs were imported + let publishableAssets = 0; // assets enqueued for publish (across all env/locale pairs) + + const enqueueBatch = async (envName, locale, uids) => { + if (uids.length === 0) return; + if (bulkPublish) { + const assets = uids.map((uid) => ({ uid, locale })); + await queue.Enqueue({ assets, Type: 'asset', environments: [envName], locale, stack, apiVersion }); + } else { + for (const uid of uids) { + await queue.Enqueue({ assetUid: uid, environments: [envName], Type: 'asset', locale, stack }); + } + } + }; + + // Add a publishable asset to its (env, locale) buffers, flushing any that fill up. + // Grouping by the exact pair keeps the bulk API from publishing an asset to a + // combo it was not published to in source. + const bufferAsset = async (targetUid, pairs) => { + publishableAssets++; + for (const { envName, locale } of pairs) { + const key = `${envName}||${locale}`; + let buf = buffers.get(key); + if (!buf) { + buf = { envName, locale, uids: [] }; + buffers.set(key, buf); + } + buf.uids.push(targetUid); + if (buf.uids.length >= bulkPublishLimit) { + await enqueueBatch(envName, locale, buf.uids); + buf.uids = []; + } + } + }; + + const indexer = fsUtil.indexFileContent; + + // NOTE: one readChunkFiles.next() call per index entry — the iteration count must + // equal the number of chunk files (same contract as contentstack-import's publish()). + for (const _index in indexer) { + const chunk = await fsUtil.readChunkFiles.next(); + const assetsArr = Object.values(chunk || {}); + + // Resolve this chunk's assets to publish targets (bounded by chunk size). + const resolved = []; + for (const asset of assetsArr) { + if (!asset || !Array.isArray(asset.publish_details) || asset.publish_details.length === 0) { + continue; + } + const targetUid = assetUidMap[asset.uid]; + if (!targetUid) { + skippedNoUidMapping++; + continue; + } + const pairs = resolvePairs(asset); + if (pairs.length === 0) { + skippedNoMappableEnv++; + continue; + } + resolved.push({ targetUid, pairs }); + } + if (resolved.length === 0) continue; + + // Scan status is a target-stack property of the freshly-imported assets, so it + // is fetched live (one batched read per chunk) — it is not in the backup. + const statusMap = await fetchScanStatusBatch( + stack, + resolved.map((r) => r.targetUid), + ); + + for (const { targetUid, pairs } of resolved) { + const status = statusMap.get(targetUid); + if (status === ASSET_SCAN_STATUS.QUARANTINE) { + scanSummary.quarantined++; + console.log(chalk.yellow(`Skipped (quarantined): Asset UID '${targetUid}'`)); + } else if (status === ASSET_SCAN_STATUS.IN_QUEUE) { + scanSummary.inQueue++; + pending.push({ targetUid, pairs }); + } else { + if (status === ASSET_SCAN_STATUS.READY) scanSummary.clean++; + else scanSummary.noStatus++; + await bufferAsset(targetUid, pairs); + } + } + } + + // Resolve in-queue assets once (incremental backoff); publish those that turn clean. + if (pending.length > 0) { + const resolvedUids = await resolveInQueueAssets( + stack, + pending.map((p) => p.targetUid), + ); + const resolvedSet = new Set(resolvedUids); + for (const { targetUid, pairs } of pending) { + if (resolvedSet.has(targetUid)) await bufferAsset(targetUid, pairs); + } + } + + // Flush remaining partial (env, locale) batches. + for (const { envName, locale, uids } of buffers.values()) { + await enqueueBatch(envName, locale, uids); + } + + if (skippedNoUidMapping > 0) { + console.log(chalk.yellow(`Skipped ${skippedNoUidMapping} asset(s): no UID mapping (not imported into target).`)); + } + if (skippedNoMappableEnv > 0) { + console.log( + chalk.yellow( + `Skipped ${skippedNoMappableEnv} asset(s): none of their published environments were imported into the target.`, + ), + ); + } + if (publishableAssets === 0) { + console.log(chalk.yellow('No publishable assets found in backup (no mapped assets with publishable environments).')); + } +} + function setConfig(conf, bp) { if (bp) { queue.consumer = performBulkPublish; @@ -242,7 +454,7 @@ function setConfig(conf, bp) { scanSummary = { clean: 0, quarantined: 0, inQueue: 0, noStatus: 0 }; } -async function start({ retryFailed, bulkPublish, environments, folderUid, locales, apiVersion }, stack, config) { +async function start({ retryFailed, bulkPublish, environments, folderUid, locales, apiVersion, dataDir }, stack, config) { process.on('beforeExit', async () => { const isErrorLogEmpty = await isEmpty(`${filePath}.error`); const isSuccessLogEmpty = await isEmpty(`${filePath}.success`); @@ -280,6 +492,13 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale } else { await retryFailedLogs(retryFailed, { assetQueue: queue }, 'publish'); } + } else if (dataDir) { + // Post-import flow: publish each imported asset only to its original + // environments/locales (from backup publish_details), scan-gated. + setConfig(config, bulkPublish); + const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid); + await getAssetsFromBackup(stack, dataDir, bulkPublish, apiVersion, bulkPublishLimit); + printScanSummary(scanSummary); } else if (folderUid) { setConfig(config, bulkPublish); const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid); @@ -299,6 +518,7 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale module.exports = { getAssets, + getAssetsFromBackup, setConfig, start, processPendingAssets, diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index ebdd2bf89..ab21f419e 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -84,7 +84,10 @@ export default class ImportAssets extends BaseClass { log.info('Asset Scanning is enabled for this stack.', this.importConfig.context); log.info('Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); log.info('Once scanning is done, publish your assets using:', this.importConfig.context); - log.info('csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY]', this.importConfig.context); + log.info( + `csdx cm:assets:publish --data-dir ${this.importConfig.backupDir} --stack-api-key [STACK API KEY]`, + this.importConfig.context, + ); } } catch (error) { handleAndLogError(error, { ...this.importConfig.context }); From 8aaeebe0920cc75fe53085049077bd6e56688642 Mon Sep 17 00:00:00 2001 From: Naman Dembla Date: Tue, 16 Jun 2026 15:30:56 +0530 Subject: [PATCH 15/44] Set maximum scan retries to zero --- packages/contentstack-bulk-publish/src/util/asset-scan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-bulk-publish/src/util/asset-scan.js b/packages/contentstack-bulk-publish/src/util/asset-scan.js index 9c9f3f0d1..27c3ffe77 100644 --- a/packages/contentstack-bulk-publish/src/util/asset-scan.js +++ b/packages/contentstack-bulk-publish/src/util/asset-scan.js @@ -8,7 +8,7 @@ const ASSET_SCAN_STATUS = { }; const SCAN_RETRY = { - MAX_RETRIES: 5, + MAX_RETRIES: 0, INITIAL_WAIT_MS: 5000, BACKOFF_FACTOR: 2, }; From 194d42fce9203f326262515ad97925c7f3be260d Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 25 Jun 2026 17:54:41 +0530 Subject: [PATCH 16/44] fix: minor fixes in asset scanning flow --- .talismanrc | 6 ++-- .../src/commands/cm/stacks/bulk-assets.ts | 17 +--------- .../src/messages/index.ts | 5 --- .../src/utils/interactive.ts | 34 +++++-------------- .../src/commands/cm/stacks/import.ts | 2 +- .../src/import/modules/assets.ts | 2 +- 6 files changed, 16 insertions(+), 50 deletions(-) diff --git a/.talismanrc b/.talismanrc index b03f6eed4..54870602d 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,6 @@ fileignoreconfig: -- filename: pnpm-lock.yaml - checksum: 7ec6345eb15ed0be001753ee49733421a8a07096dc8a18465cdad1b82562fed8 +- filename: packages/contentstack-import/src/commands/cm/stacks/import.ts + checksum: bbf5ebdec2350c3b6d8118a25046e4e11b68c56434ac6c89be6aaab047a6ac4b +- filename: packages/contentstack-import/src/import/modules/assets.ts + checksum: ce46c32788ea908075873b4dee475bae75975eb58771d0da06a3debb6817bf91 version: '1.0' diff --git a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts index e8bfc9835..c50b12766 100644 --- a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts +++ b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts @@ -5,15 +5,7 @@ import { flags, handleAndLogError, log } from '@contentstack/cli-utilities'; import { AssetPublishData, BulkOperationResult, OperationType, ResourceType } from '../../../interfaces'; import { BaseBulkCommand } from '../../../base-bulk-command'; -import { - $t, - messages, - fetchAssets, - scanDataDirStats, - BATCH_CONSTANTS, - categorizeByScanStatus, - fillMissingFlags, -} from '../../../utils'; +import { $t, messages, fetchAssets, scanDataDirStats, BATCH_CONSTANTS, categorizeByScanStatus } from '../../../utils'; import type { DataDirScanStats } from '../../../utils'; import { AssetService } from '../../../services'; @@ -67,13 +59,6 @@ export default class BulkAssets extends BaseBulkCommand { protected resourceType: ResourceType = ResourceType.ASSET; - protected async resolveFlagsInteractively(flags: any): Promise { - if (flags['data-dir']) { - return flags; - } - return fillMissingFlags(flags, { promptDataDir: true }); - } - async run(): Promise { try { if (this.bulkOperationConfig.sourceEnv) { diff --git a/packages/contentstack-bulk-operations/src/messages/index.ts b/packages/contentstack-bulk-operations/src/messages/index.ts index c51fe6023..ab7e6f7d9 100644 --- a/packages/contentstack-bulk-operations/src/messages/index.ts +++ b/packages/contentstack-bulk-operations/src/messages/index.ts @@ -379,11 +379,6 @@ const interactiveMsg = { TAXONOMY_UNSUPPORTED_RETRY: 'Retry and revert are not supported for bulk-taxonomies.', TAXONOMY_UNSUPPORTED_CROSS_PUBLISH: 'Cross-publish is not supported for bulk-taxonomies.', - // Data-dir (backup folder) prompt - USE_DATA_DIR_PROMPT: 'Do you want to publish assets using publish details from an import backup folder (data-dir)?', - ENTER_DATA_DIR: 'Enter the path to the import backup folder (data-dir):', - DATA_DIR_REQUIRED: 'Backup folder path is required', - // Errors NO_DELIVERY_TOKENS_FOUND: 'No delivery token aliases found. Add one using: csdx auth:tokens:add -a --delivery-token --api-key --environment --type delivery', diff --git a/packages/contentstack-bulk-operations/src/utils/interactive.ts b/packages/contentstack-bulk-operations/src/utils/interactive.ts index a17485e9a..41e3d319a 100644 --- a/packages/contentstack-bulk-operations/src/utils/interactive.ts +++ b/packages/contentstack-bulk-operations/src/utils/interactive.ts @@ -151,7 +151,7 @@ async function promptForSourceAlias(): Promise { /** * Fills in missing required flags by prompting the user */ -export async function fillMissingFlags(flags: any, options?: { promptDataDir?: boolean }): Promise { +export async function fillMissingFlags(flags: any): Promise { const updatedFlags = { ...flags }; // Skip interactive mode for retry/revert operations @@ -162,17 +162,21 @@ export async function fillMissingFlags(flags: any, options?: { promptDataDir?: b // Track if we prompted for anything let didPrompt = false; + // The presence of --data-dir is what selects the import-backup publish flow: + // environments and locales are then derived per-asset from the backup, so we + // neither prompt for the data-dir path nor for environments/locales here. + const hasDataDir = !!updatedFlags['data-dir']; + // Check if any required fields are missing const needsCredentials = !updatedFlags.alias && !updatedFlags['stack-api-key']; const needsOperation = !updatedFlags.operation; - const needsEnvironments = !updatedFlags.environments || updatedFlags.environments.length === 0; // Check if non-localized filter is used const isNonLocalized = updatedFlags.filter === FilterType.NON_LOCALIZED; - const needsLocales = !isNonLocalized && (!updatedFlags.locales || updatedFlags.locales.length === 0); - const needsDataDir = options?.promptDataDir && !updatedFlags['data-dir']; + const needsEnvironments = !hasDataDir && (!updatedFlags.environments || updatedFlags.environments.length === 0); + const needsLocales = !hasDataDir && !isNonLocalized && (!updatedFlags.locales || updatedFlags.locales.length === 0); // Only show interactive mode header if we need to prompt - if (needsCredentials || needsOperation || needsEnvironments || needsLocales || needsDataDir) { + if (needsCredentials || needsOperation || needsEnvironments || needsLocales) { cliux.print(messages.INTERACTIVE_MODE_START, { color: 'cyan' }); didPrompt = true; } @@ -192,26 +196,6 @@ export async function fillMissingFlags(flags: any, options?: { promptDataDir?: b updatedFlags.operation = await promptForOperation(); } - // 2.5. Data-dir (import backup folder) — alternative to environments/locales for asset publish - if (needsDataDir) { - const useDataDir = await cliux.inquire({ - type: 'confirm', - name: 'useDataDir', - message: messages.USE_DATA_DIR_PROMPT, - default: false, - }); - if (useDataDir) { - updatedFlags['data-dir'] = await cliux.inquire({ - type: 'input', - name: 'dataDir', - message: messages.ENTER_DATA_DIR, - validate: (v: string) => (!v?.trim() ? messages.DATA_DIR_REQUIRED : true), - }); - cliux.print(messages.INTERACTIVE_MODE_COMPLETE, { color: 'green' }); - return updatedFlags; - } - } - // 3. Check for cross-publish mode const isCrossPublish = updatedFlags['source-env'] || updatedFlags['source-alias']; diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index b1aadbb72..fbd208892 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -162,7 +162,7 @@ export default class ImportCommand extends Command { if (importConfig.assetScanningEnabled) { cliux.print('\nAsset Scanning is enabled — assets were not published.', { color: 'yellow' }); cliux.print(' Once scanning completes, publish your assets using:', { color: 'yellow' }); - cliux.print(` csdx cm:stacks:bulk-assets --data-dir ${backupDir} --stack-api-key ${importConfig.apiKey}`, { color: 'cyan' }); + cliux.print(` csdx cm:stacks:bulk-assets --data-dir ${backupDir} --stack-api-key ${importConfig.apiKey} --operation publish`, { color: 'cyan' }); } this.logSuccessAndBackupMessages(backupDir, importConfig); // Clear progress module setting now that import is complete diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index fbce6e743..f6158d5a8 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -202,7 +202,7 @@ export default class ImportAssets extends BaseClass { log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); - log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key ', this.importConfig.context); + log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key --operation publish', this.importConfig.context); } } catch (error) { this.completeProgress(false, error?.message || 'Asset import failed'); From b51e1273ecd5e1e5c18b19e0f32fc4c3e5c4e4d0 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Sun, 28 Jun 2026 18:24:54 +0530 Subject: [PATCH 17/44] fix: minor fixes in bulk publish --- .../src/producer/publish-assets.js | 13 ++++++++----- .../src/import/modules/assets.ts | 6 +++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/contentstack-bulk-publish/src/producer/publish-assets.js b/packages/contentstack-bulk-publish/src/producer/publish-assets.js index edee00ed1..df5af5da4 100644 --- a/packages/contentstack-bulk-publish/src/producer/publish-assets.js +++ b/packages/contentstack-bulk-publish/src/producer/publish-assets.js @@ -263,9 +263,12 @@ async function getAssetsFromBackup(stack, dataDir, bulkPublish, apiVersion, bulk const envUidMapperPath = path.join(dataDir, 'mapper', 'environments', 'uid-mapping.json'); const environmentsPath = path.join(dataDir, 'environments', 'environments.json'); - // Fail fast with actionable errors when the backup is incomplete. + // A backup with no assets is a legitimate outcome of a successful import that + // had 0 assets (assets.json is never produced) — exit cleanly, not as a crash. + // A genuinely wrong --data-dir surfaces via the uid-mapping/environments guards below. if (!existsSync(assetsPath) || !existsSync(assetsIndexPath)) { - throw new Error(`No assets found in backup. Expected '${assetsIndexPath}'. Check the --data-dir path.`); + console.log(chalk.yellow('No assets found in backup — nothing to publish.')); + return; } if (!existsSync(assetUidMapperPath)) { throw new Error( @@ -456,6 +459,9 @@ function setConfig(conf, bp) { async function start({ retryFailed, bulkPublish, environments, folderUid, locales, apiVersion, dataDir }, stack, config) { process.on('beforeExit', async () => { + // Print the scan summary here (not inline after enqueueing): + printScanSummary(scanSummary); + const isErrorLogEmpty = await isEmpty(`${filePath}.error`); const isSuccessLogEmpty = await isEmpty(`${filePath}.success`); if (!isErrorLogEmpty) { @@ -498,7 +504,6 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale setConfig(config, bulkPublish); const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid); await getAssetsFromBackup(stack, dataDir, bulkPublish, apiVersion, bulkPublishLimit); - printScanSummary(scanSummary); } else if (folderUid) { setConfig(config, bulkPublish); const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid); @@ -506,8 +511,6 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale await getAssets(stack, folderUid, bulkPublish, environments, locale, apiVersion, bulkPublishLimit); } - printScanSummary(scanSummary); - // Resolve in-queue assets with incremental retry; pass pendingAssetsForRetry explicitly if (pendingAssetsForRetry.length > 0) { await processPendingAssets(pendingAssetsForRetry, stack, bulkPublish, environments, apiVersion, bulkPublishLimit); diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index ab21f419e..4d23c0524 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -80,7 +80,11 @@ export default class ImportAssets extends BaseClass { log.success('Assets imported successfully!', this.importConfig.context); - if (this.importConfig.assetScanningEnabled) { + // Only surface the "publish later" guidance when assets were actually + // imported. With 0 assets, assetsUidMap is empty and the backup has no + // assets to publish — printing the guidance would send the user to run + // cm:assets:publish against an empty backup. + if (this.importConfig.assetScanningEnabled && !isEmpty(this.assetsUidMap)) { log.info('Asset Scanning is enabled for this stack.', this.importConfig.context); log.info('Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); log.info('Once scanning is done, publish your assets using:', this.importConfig.context); From 560e9c054c1a40858d3bf163d8c3c885bdff65e9 Mon Sep 17 00:00:00 2001 From: aniket-shikhare-cstk Date: Tue, 30 Jun 2026 15:15:59 +0530 Subject: [PATCH 18/44] fix(bulk-publish): add null guard on asset.publish_details before forEach Assets loaded from --data-dir backup may not have a publish_details field if they were never published. The optional chain only guarded `asset`, not `publish_details`, causing a TypeError in displayAssetsDetails(). --- packages/contentstack-bulk-publish/src/consumer/publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-bulk-publish/src/consumer/publish.js b/packages/contentstack-bulk-publish/src/consumer/publish.js index f466b250c..ad25da96f 100644 --- a/packages/contentstack-bulk-publish/src/consumer/publish.js +++ b/packages/contentstack-bulk-publish/src/consumer/publish.js @@ -61,7 +61,7 @@ function displayEntriesDetails(sanitizedData, action, mapping = []) { function displayAssetsDetails(sanitizedData, action, mapping) { if (action === 'bulk_publish') { sanitizedData.forEach((asset) => { - asset?.publish_details.forEach((pd) => { + asset?.publish_details?.forEach((pd) => { if (Object.keys(mapping).includes(pd.environment)) { console.log( chalk.green( From 1eb074a6ea38ffecda28f1733ea6cfc0a31cacde Mon Sep 17 00:00:00 2001 From: aniket-shikhare-cstk Date: Tue, 30 Jun 2026 15:37:10 +0530 Subject: [PATCH 19/44] fix(bulk-publish): declare module-level config variable in publish-assets.js setConfig() assigned to `config` at module scope but the variable was never declared, causing a ReferenceError on any cm:assets:publish run that goes through the data-dir flow. --- .../contentstack-bulk-publish/src/producer/publish-assets.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/contentstack-bulk-publish/src/producer/publish-assets.js b/packages/contentstack-bulk-publish/src/producer/publish-assets.js index df5af5da4..07c58a7d3 100644 --- a/packages/contentstack-bulk-publish/src/producer/publish-assets.js +++ b/packages/contentstack-bulk-publish/src/producer/publish-assets.js @@ -15,6 +15,7 @@ const { generateBulkPublishStatusUrl } = require('../util/generate-bulk-publish- const { resolveInQueueAssets, fetchScanStatusBatch, ASSET_SCAN_STATUS } = require('../util/asset-scan'); const queue = getQueue(); +let config; let logFileName; let bulkPublishSet = []; let pendingAssetsForRetry = []; From e047d2aa7395bceb52a30f435c3196d1b70d8a5d Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 1 Jul 2026 11:16:44 +0530 Subject: [PATCH 20/44] fixed org plan check feature --- .talismanrc | 8 +++- packages/contentstack-export/package.json | 4 +- .../src/commands/cm/stacks/export.ts | 7 ++- .../src/utils/export-config-handler.ts | 44 ++++++++++++++----- .../tsconfig.tsbuildinfo | 2 +- .../src/commands/cm/stacks/import.ts | 4 +- .../src/utils/import-config-handler.ts | 23 +++++++++- 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/.talismanrc b/.talismanrc index 2db24759d..0e9b7a11f 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,8 @@ fileignoreconfig: -- filename: pnpm-lock.yaml - checksum: 24619b075664a197c8f648b04dd86ee79d653fbb583b33e4a3768f02378912ef + - filename: pnpm-lock.yaml + checksum: 24619b075664a197c8f648b04dd86ee79d653fbb583b33e4a3768f02378912ef + - filename: packages/contentstack-import/src/utils/import-config-handler.ts + checksum: 25b986edf20dfd555f9ffc6f124d7d6eb7ac1134a5a67224a49ba48aa50b86f3 + - filename: packages/contentstack-export/src/utils/export-config-handler.ts + checksum: a024cdb82e21496794f49fd905f983c0d6677ac9d6761f2e46266fea9932041d version: '1.0' diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index c77307173..a733060c3 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -6,7 +6,7 @@ "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~2.0.0-beta.8", - "@contentstack/cli-utilities": "~2.0.0-beta.9", + "@contentstack/cli-utilities": "~2.0.0-beta.10", "@contentstack/cli-variants": "~2.0.0-beta.16", "@contentstack/cli-asset-management": "~1.0.0-beta.4", "@oclif/core": "^4.11.4", @@ -99,4 +99,4 @@ } }, "repository": "https://github.com/contentstack/cli" -} +} \ No newline at end of file diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 97f596f7f..97474435f 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -22,6 +22,8 @@ import { Context, ExportConfig } from '../../../types'; import { setupExportConfig } from '../../../utils'; export default class ExportCommand extends Command { + static planProtectedFeatures = ['assetsScan']; + static description: string = messageHandler.parse('Export content from a stack'); static examples: string[] = [ @@ -91,8 +93,11 @@ export default class ExportCommand extends Command { await loadChalk(); let exportDir: string = pathValidator('logs'); try { + console.log('context', this.context); + const { flags } = await this.parse(ExportCommand); - const exportConfig = await setupExportConfig(flags); + const exportConfig = await setupExportConfig(flags, this.context); + // Prepare the context object const context = this.createExportContext(exportConfig.apiKey, exportConfig.authenticationMethod); exportConfig.context = { ...context }; diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index 3b1d559ff..e81611cef 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -1,6 +1,15 @@ import merge from 'merge'; import * as path from 'path'; -import { configHandler, isAuthenticated, cliux, sanitizePath, log } from '@contentstack/cli-utilities'; +import { + configHandler, + isAuthenticated, + cliux, + sanitizePath, + log, + assertFeatureEnabled, + FeatureCtx, + isFeatureEnabled, +} from '@contentstack/cli-utilities'; import defaultConfig from '../config'; import { readFile, isDirectoryNonEmpty } from './file-helper'; import { askExportDir, askAPIKey } from './interactive'; @@ -8,7 +17,7 @@ import login from './basic-login'; import { filter, includes } from 'lodash'; import { ExportConfig } from '../types'; -const setupConfig = async (exportCmdFlags: any): Promise => { +const setupConfig = async (exportCmdFlags: any, context: any): Promise => { // Set progress supported module FIRST, before any log calls // This ensures the logger respects the showConsoleLogs setting correctly configHandler.set('log.progressSupportedModule', 'export'); @@ -29,12 +38,9 @@ const setupConfig = async (exportCmdFlags: any): Promise => { if (legacyCsAssetsConfig) { externalConfig.modules['cs-assets'] = externalConfig.modules['cs-assets'] || legacyCsAssetsConfig; delete externalConfig.modules['asset-management']; - log.warn( - 'Config key "modules.asset-management" is deprecated. Please rename it to "modules.cs-assets".', - ); + log.warn('Config key "modules.asset-management" is deprecated. Please rename it to "modules.cs-assets".'); } - config = merge.recursive(config, externalConfig); } config.exportDir = sanitizePath( @@ -52,10 +58,9 @@ const setupConfig = async (exportCmdFlags: any): Promise => { config.exportDir = path.resolve(config.exportDir); if (isDirectoryNonEmpty(config.exportDir)) { - cliux.print( - '\nThe export directory is not empty. Existing files in this folder may be overwritten.', - { color: 'yellow' }, - ); + cliux.print('\nThe export directory is not empty. Existing files in this folder may be overwritten.', { + color: 'yellow', + }); } const managementTokenAlias = exportCmdFlags['management-token-alias'] || exportCmdFlags['alias']; @@ -152,6 +157,25 @@ const setupConfig = async (exportCmdFlags: any): Promise => { config.authenticationMethod = authenticationMethod; log.debug('Export configuration setup completed.', { ...config }); + // Deferred plan check — credentials now available after setupExportConfig + const deferredFeatures: string[] = context?.planCheckRequired ?? []; + if (deferredFeatures.length > 0) { + const planCtx: FeatureCtx = { + apiKey: config.apiKey, + managementToken: config.management_token, + authToken: config.auth_token, + }; + for (const featureUid of deferredFeatures) { + try { + const status = await isFeatureEnabled(featureUid, planCtx); + if (context) context.planStatus[featureUid] = status; + log.debug(`[export] Deferred plan status fetched for "${featureUid}".`); + } catch (error) { + log.warn(`[export] Could not fetch deferred plan status for "${featureUid}": ${(error as Error).message}`); + } + } + } + return config; }; diff --git a/packages/contentstack-external-migrate/tsconfig.tsbuildinfo b/packages/contentstack-external-migrate/tsconfig.tsbuildinfo index 06e254b83..07e9c07fa 100644 --- a/packages/contentstack-external-migrate/tsconfig.tsbuildinfo +++ b/packages/contentstack-external-migrate/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/index.ts","./src/adapters/registry.ts","./src/adapters/types.ts","./src/adapters/contentful/convert.ts","./src/adapters/contentful/export.ts","./src/adapters/contentful/index.ts","./src/adapters/contentful/validator.ts","./src/commands/external-migrate/audit.ts","./src/commands/external-migrate/convert.ts","./src/commands/external-migrate/create.ts","./src/commands/external-migrate/export.ts","./src/commands/external-migrate/import.ts","./src/commands/external-migrate/status.ts","./src/lib/bundle.ts","./src/lib/clear-import-state.ts","./src/lib/contentful-cli-spawn.ts","./src/lib/conversion-summary.ts","./src/lib/create-stack.ts","./src/lib/csdx-spawn.ts","./src/lib/local-date.ts","./src/lib/log.ts","./src/lib/manifest.ts","./src/lib/parse-json-loose.ts","./src/services/contentful/config.ts","./src/services/contentful/constants.ts","./src/services/contentful/content-type-creator.ts","./src/services/contentful/contentful.service.ts","./src/services/contentful/extension.service.ts","./src/services/contentful/market-app.utils.ts","./src/services/contentful/marketplace.service.ts","./src/services/contentful/releases.ts","./src/services/contentful/scheduled.ts","./src/services/contentful/tasks.ts","./src/services/contentful/types.ts","./src/services/contentful/users.ts","./src/services/contentful/workflows.ts","./src/services/contentful/contentful/jsonrte.ts","./src/services/contentful/contentful/markdown.ts","./src/services/contentful/contentful/roles.ts","./src/services/contentful/contentful/taxonomy.service.ts","./src/services/contentful/mapper/write.ts","./src/services/contentful/migration-contentful/index.js","./src/services/contentful/migration-contentful/libs/contenttypemapper.js","./src/services/contentful/migration-contentful/libs/createinitialmapper.js","./src/services/contentful/migration-contentful/libs/extractcontenttypes.js","./src/services/contentful/migration-contentful/libs/extractlocale.js","./src/services/contentful/migration-contentful/libs/extracttaxonomy.js","./src/services/contentful/migration-contentful/utils/helper.js","./src/services/contentful/prompts/master-locale.ts","./src/services/contentful/utils/custom-logger.utils.ts","./src/services/contentful/utils/index.ts"],"version":"5.9.3"} \ No newline at end of file +{"root":["./src/index.ts","./src/adapters/registry.ts","./src/adapters/types.ts","./src/adapters/contentful/convert.ts","./src/adapters/contentful/export.ts","./src/adapters/contentful/index.ts","./src/adapters/contentful/validator.ts","./src/commands/migrate/audit.ts","./src/commands/migrate/convert.ts","./src/commands/migrate/create.ts","./src/commands/migrate/export.ts","./src/commands/migrate/import.ts","./src/commands/migrate/status.ts","./src/lib/bundle.ts","./src/lib/clear-import-state.ts","./src/lib/contentful-cli-spawn.ts","./src/lib/conversion-summary.ts","./src/lib/create-stack.ts","./src/lib/csdx-spawn.ts","./src/lib/local-date.ts","./src/lib/log.ts","./src/lib/manifest.ts","./src/lib/parse-json-loose.ts","./src/services/contentful/config.ts","./src/services/contentful/constants.ts","./src/services/contentful/content-type-creator.ts","./src/services/contentful/contentful.service.ts","./src/services/contentful/extension.service.ts","./src/services/contentful/market-app.utils.ts","./src/services/contentful/marketplace.service.ts","./src/services/contentful/releases.ts","./src/services/contentful/scheduled.ts","./src/services/contentful/tasks.ts","./src/services/contentful/types.ts","./src/services/contentful/users.ts","./src/services/contentful/workflows.ts","./src/services/contentful/contentful/jsonrte.ts","./src/services/contentful/contentful/markdown.ts","./src/services/contentful/contentful/roles.ts","./src/services/contentful/contentful/taxonomy.service.ts","./src/services/contentful/mapper/write.ts","./src/services/contentful/migration-contentful/index.js","./src/services/contentful/migration-contentful/libs/contenttypemapper.js","./src/services/contentful/migration-contentful/libs/createinitialmapper.js","./src/services/contentful/migration-contentful/libs/extractcontenttypes.js","./src/services/contentful/migration-contentful/libs/extractlocale.js","./src/services/contentful/migration-contentful/libs/extracttaxonomy.js","./src/services/contentful/migration-contentful/utils/helper.js","./src/services/contentful/prompts/master-locale.ts","./src/services/contentful/utils/custom-logger.utils.ts","./src/services/contentful/utils/index.ts"],"version":"5.9.3"} \ No newline at end of file diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 1d56aca9a..209b0e6c2 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -20,6 +20,8 @@ import { ModuleImporter } from '../../../import'; import { setupImportConfig } from '../../../utils'; export default class ImportCommand extends Command { + static planProtectedFeatures = ['assetsScan']; + static description = messageHandler.parse('Import content from a stack'); static examples: string[] = [ @@ -124,7 +126,7 @@ export default class ImportCommand extends Command { let importConfig: ImportConfig; try { const { flags } = await this.parse(ImportCommand); - importConfig = await setupImportConfig(flags); + importConfig = await setupImportConfig(flags, this.context); // Prepare the context object createLogContext( this.context?.info?.command || 'cm:stacks:import', diff --git a/packages/contentstack-import/src/utils/import-config-handler.ts b/packages/contentstack-import/src/utils/import-config-handler.ts index abcacecb9..6bdff3e8a 100644 --- a/packages/contentstack-import/src/utils/import-config-handler.ts +++ b/packages/contentstack-import/src/utils/import-config-handler.ts @@ -1,7 +1,7 @@ import merge from 'merge'; import * as path from 'path'; import { omit, filter, includes, isArray } from 'lodash'; -import { configHandler, isAuthenticated, cliux, sanitizePath, log } from '@contentstack/cli-utilities'; +import { configHandler, isAuthenticated, cliux, sanitizePath, log, isFeatureEnabled, FeatureCtx } from '@contentstack/cli-utilities'; import defaultConfig from '../config'; import { readFile, readFileSync } from './file-helper'; import { askContentDir, askAPIKey } from './interactive'; @@ -9,7 +9,7 @@ import login from './login-handler'; import { ImportConfig } from '../types'; import { existsSync } from 'fs'; -const setupConfig = async (importCmdFlags: any): Promise => { +const setupConfig = async (importCmdFlags: any, context?: any): Promise => { // Set progress supported module FIRST, before any log calls // This ensures the logger respects the showConsoleLogs setting correctly configHandler.set('log.progressSupportedModule', 'import'); @@ -166,6 +166,25 @@ const setupConfig = async (importCmdFlags: any): Promise => { config.authenticationMethod = authenticationMethod; log.debug('Import configuration setup completed.', { ...config }); + // Deferred plan check — credentials now available after setupImportConfig + const deferredFeatures: string[] = context?.planCheckRequired ?? []; + if (deferredFeatures.length > 0) { + const planCtx: FeatureCtx = { + apiKey: config.apiKey, + managementToken: config.management_token, + authToken: config.auth_token, + }; + for (const featureUid of deferredFeatures) { + try { + const status = await isFeatureEnabled(featureUid, planCtx); + if (context) context.planStatus[featureUid] = status; + log.debug(`[import] Deferred plan status fetched for "${featureUid}".`); + } catch (error) { + log.warn(`[import] Could not fetch deferred plan status for "${featureUid}": ${(error as Error).message}`); + } + } + } + return config; }; From e6285c718718c56873ffbb9edfb8847f3380400c Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 1 Jul 2026 11:18:45 +0530 Subject: [PATCH 21/44] removed console logs --- packages/contentstack-export/src/commands/cm/stacks/export.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 97474435f..afe844ac1 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -93,8 +93,6 @@ export default class ExportCommand extends Command { await loadChalk(); let exportDir: string = pathValidator('logs'); try { - console.log('context', this.context); - const { flags } = await this.parse(ExportCommand); const exportConfig = await setupExportConfig(flags, this.context); From 3d7772511e6a9e288f6ef429bfa14d165da31d8b Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 1 Jul 2026 19:43:31 +0530 Subject: [PATCH 22/44] added asset scanning plan check --- packages/contentstack-export/package.json | 3 ++- .../src/commands/cm/stacks/export.ts | 3 +-- .../src/types/export-config.ts | 1 + .../src/utils/export-config-handler.ts | 9 ++++++++- packages/contentstack-import/package.json | 6 ++++-- .../src/commands/cm/stacks/import.ts | 6 +++--- .../src/import/module-importer.ts | 6 ------ .../src/import/modules/assets.ts | 11 ++++++++++- .../src/types/import-config.ts | 1 + .../src/utils/import-config-handler.ts | 18 +++++++++++++++++- 10 files changed, 47 insertions(+), 17 deletions(-) diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index a733060c3..e6ea7a0a9 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -96,7 +96,8 @@ "csdxConfig": { "shortCommandName": { "cm:stacks:export": "EXPRT" - } + }, + "planProtectedFeatures": ["assetsScan"] }, "repository": "https://github.com/contentstack/cli" } \ No newline at end of file diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index afe844ac1..6fd15b4c8 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -22,8 +22,6 @@ import { Context, ExportConfig } from '../../../types'; import { setupExportConfig } from '../../../utils'; export default class ExportCommand extends Command { - static planProtectedFeatures = ['assetsScan']; - static description: string = messageHandler.parse('Export content from a stack'); static examples: string[] = [ @@ -96,6 +94,7 @@ export default class ExportCommand extends Command { const { flags } = await this.parse(ExportCommand); const exportConfig = await setupExportConfig(flags, this.context); + console.log('Context', this.context); // Prepare the context object const context = this.createExportContext(exportConfig.apiKey, exportConfig.authenticationMethod); exportConfig.context = { ...context }; diff --git a/packages/contentstack-export/src/types/export-config.ts b/packages/contentstack-export/src/types/export-config.ts index 893e2dc8e..acf43724c 100644 --- a/packages/contentstack-export/src/types/export-config.ts +++ b/packages/contentstack-export/src/types/export-config.ts @@ -36,6 +36,7 @@ export default interface ExportConfig extends DefaultConfig { skipDependencies?: boolean; authenticationMethod?: string; linkedWorkspaces?: Array<{ uid: string; space_uid: string; is_default: boolean }>; + planStatus: any; } type branch = { diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index e81611cef..e7bb25838 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -168,7 +168,10 @@ const setupConfig = async (exportCmdFlags: any, context: any): Promise = await this.stackAPIClient.fetch(); this.importConfig.stackName = stackDetails.name as string; this.importConfig.org_uid = stackDetails.org_uid as string; - - const assetScanningEnabled = await this.detectAssetScanning(this.importConfig.org_uid); - if (assetScanningEnabled) { - this.importConfig.assetScanningEnabled = true; - this.importConfig.skipAssetsPublish = true; - } } await this.resolveImportPath(); diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index fbce6e743..541f6f0eb 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -39,11 +39,13 @@ export default class ImportAssets extends BaseClass { private assetsUrlMap: Record = {}; private assetsFolderMap: Record = {}; private rootFolder: { uid: string; name: string; parent_uid: string; created_at: string }; + private planStatus: Record = {}; constructor({ importConfig, stackAPIClient }: ModuleClassParams) { super({ importConfig, stackAPIClient }); this.importConfig.context.module = MODULE_CONTEXTS.ASSETS; this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.ASSETS]; + this.planStatus = this.importConfig.planStatus; this.assetsPath = join(this.importConfig.backupDir, PATH_CONSTANTS.CONTENT_DIRS.ASSETS); this.mapperDirPath = join(this.importConfig.backupDir, PATH_CONSTANTS.MAPPER, PATH_CONSTANTS.MAPPER_MODULES.ASSETS); @@ -66,6 +68,10 @@ export default class ImportAssets extends BaseClass { try { log.debug('Starting assets import process...', this.importConfig.context); + if (this.planStatus['assetsScan']?.is_part_of_plan) { + log.info('Assets Scanning is enabled in this stack', this.importConfig.context); + log.warn('Assets publishing will be skipped', this.importConfig.context); + } // CS Assets: csAssetsEnabled is set in the config handler when spaces/ + am_v2 are detected. if (this.importConfig.csAssetsEnabled) { if (!this.importConfig.csAssetsUrl) { @@ -200,7 +206,10 @@ export default class ImportAssets extends BaseClass { if (this.importConfig.assetScanningEnabled) { log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); - log.info(' Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); + log.info( + ' Assets cannot be published immediately — scanning must complete first.', + this.importConfig.context, + ); log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key ', this.importConfig.context); } diff --git a/packages/contentstack-import/src/types/import-config.ts b/packages/contentstack-import/src/types/import-config.ts index 90db2ca08..6f8e06515 100644 --- a/packages/contentstack-import/src/types/import-config.ts +++ b/packages/contentstack-import/src/types/import-config.ts @@ -61,6 +61,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig { context: Context; csAssetsUrl?: string; csAssetsEnabled?: boolean; + planStatus: any; } type branch = { diff --git a/packages/contentstack-import/src/utils/import-config-handler.ts b/packages/contentstack-import/src/utils/import-config-handler.ts index 6bdff3e8a..65f9a08dd 100644 --- a/packages/contentstack-import/src/utils/import-config-handler.ts +++ b/packages/contentstack-import/src/utils/import-config-handler.ts @@ -1,7 +1,15 @@ import merge from 'merge'; import * as path from 'path'; import { omit, filter, includes, isArray } from 'lodash'; -import { configHandler, isAuthenticated, cliux, sanitizePath, log, isFeatureEnabled, FeatureCtx } from '@contentstack/cli-utilities'; +import { + configHandler, + isAuthenticated, + cliux, + sanitizePath, + log, + isFeatureEnabled, + FeatureCtx, +} from '@contentstack/cli-utilities'; import defaultConfig from '../config'; import { readFile, readFileSync } from './file-helper'; import { askContentDir, askAPIKey } from './interactive'; @@ -185,6 +193,14 @@ const setupConfig = async (importCmdFlags: any, context?: any): Promise Date: Wed, 8 Jul 2026 15:35:07 +0530 Subject: [PATCH 23/44] fixed snyk --- .talismanrc | 2 + packages/contentstack-apps-cli/package.json | 2 +- pnpm-lock.yaml | 534 ++++++++++++++------ pnpm-workspace.yaml | 1 + 4 files changed, 374 insertions(+), 165 deletions(-) diff --git a/.talismanrc b/.talismanrc index 73151fc22..33631a9a5 100644 --- a/.talismanrc +++ b/.talismanrc @@ -4,4 +4,6 @@ fileignoreconfig: checksum: bbf5ebdec2350c3b6d8118a25046e4e11b68c56434ac6c89be6aaab047a6ac4b - filename: packages/contentstack-import/src/import/modules/assets.ts checksum: 9441f294d8eca1397a988fefec148b20dbe25c1138f6119cf5c573770de43895 +- filename: pnpm-lock.yaml + checksum: cee37c1d5b89d422e6ab3c84678ea3d71e42f8d5ff9cb2c22a29c25d18dddf08 version: '1.0' diff --git a/packages/contentstack-apps-cli/package.json b/packages/contentstack-apps-cli/package.json index d35386080..d6854b533 100644 --- a/packages/contentstack-apps-cli/package.json +++ b/packages/contentstack-apps-cli/package.json @@ -23,7 +23,7 @@ "dependencies": { "@apollo/client": "^3.14.1", "@contentstack/cli-command": "~2.0.0-beta.8", - "@contentstack/cli-launch": "^1.10.0", + "@contentstack/cli-launch": "^1.11.1", "@contentstack/cli-utilities": "~2.0.0-beta.9", "adm-zip": "^0.5.17", "chalk": "^5.6.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b8ea1339..a9710f21b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,7 @@ overrides: follow-redirects: 1.16.0 uuid: 14.0.0 lodash: 4.18.1 + brace-expansion: 5.0.7 importers: @@ -30,8 +31,8 @@ importers: specifier: ~2.0.0-beta.8 version: 2.0.0-beta.8(@types/node@20.19.43) '@contentstack/cli-launch': - specifier: ^1.10.0 - version: 1.11.0(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3) + specifier: ^1.11.1 + version: 1.11.1(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3) '@contentstack/cli-utilities': specifier: ~2.0.0-beta.9 version: 2.0.0-beta.9(@types/node@20.19.43) @@ -56,7 +57,7 @@ importers: devDependencies: '@oclif/test': specifier: ^4.1.18 - version: 4.1.20(@oclif/core@4.11.11) + version: 4.1.20(@oclif/core@4.11.14) '@types/adm-zip': specifier: ^0.5.8 version: 0.5.8 @@ -512,7 +513,7 @@ importers: version: 6.2.52 '@oclif/test': specifier: ^4.1.18 - version: 4.1.20(@oclif/core@4.11.11) + version: 4.1.20(@oclif/core@4.11.14) '@types/chai': specifier: ^4.3.20 version: 4.3.20 @@ -585,7 +586,7 @@ importers: version: 6.2.52 '@oclif/test': specifier: ^4.1.18 - version: 4.1.20(@oclif/core@4.11.11) + version: 4.1.20(@oclif/core@4.11.14) '@types/jest': specifier: ^29.5.14 version: 29.5.14 @@ -808,8 +809,8 @@ importers: specifier: ~2.0.0-beta.8 version: 2.0.0-beta.8(@types/node@22.20.0) '@contentstack/cli-utilities': - specifier: ~2.0.0-beta.9 - version: 2.0.0-beta.9(@types/node@22.20.0) + specifier: ~2.0.0-beta.10 + version: 2.0.0-beta.10(@types/node@22.20.0) '@contentstack/cli-variants': specifier: ~2.0.0-beta.16 version: link:../contentstack-variants @@ -2362,6 +2363,10 @@ packages: resolution: {integrity: sha512-UYnIkO4B3k/qhz4snI6UFVkKcbseyXXreXzKM4T8d/fzMl0Ra6cNGeIMiGgo1RZ2rYlNRfZ2HdfhsPw6e3hlHA==} engines: {node: '>=14.0.0'} + '@contentstack/cli-command@1.8.4': + resolution: {integrity: sha512-xo6d+KrwqGZakUKz6Uw9I3CsW6HC+NqwsMd5kc9IN5j/UhzLZujLAj6fotQY+cyJYG/Dz9D+tSIaL8ZAMRTkLg==} + engines: {node: '>=22.0.0'} + '@contentstack/cli-command@2.0.0-beta.8': resolution: {integrity: sha512-LZMiD3geKqc9zyzdpEktrzrvG1v/YyTVc5n5GF5iE17llnM9Ts5WfGKjhQX49ZavWbJYI0Qk06BF2ncomHQhvg==} engines: {node: '>=14.0.0'} @@ -2376,14 +2381,20 @@ packages: '@contentstack/cli-dev-dependencies@2.0.0-beta.0': resolution: {integrity: sha512-tLP05taIeepvp5Xte2LKDTKeYtDjCxOLlNWzwMFhMFYU1Z7oOgiCu8RVHNz+EkAm5xScKORx1OyEgyNLFoTLBw==} - '@contentstack/cli-launch@1.11.0': - resolution: {integrity: sha512-W/TXIo6odfnPe+qHgoxAts5KahnMRBURGwf4olkoZFYGXoEQ6ZjPXuI2tHUvC0gmWcQOV0z6LDNK+99xJ0aBjg==} + '@contentstack/cli-launch@1.11.1': + resolution: {integrity: sha512-sInkejRj3BQY2P4EsAzkSy9OIWBFS5rFwP7v9sC9mMMo7UGuasF7hZUJHiIDCcwEnRTIRPQ41qX6NBlIr3steA==} engines: {node: '>=22.0.0'} hasBin: true '@contentstack/cli-utilities@1.18.4': resolution: {integrity: sha512-6Q+zge0WP8e5FXRXH1mmsbzAy3xHluUsDdUHO2w8/1w5wyG1rifCi2YcP3GdZJPAoHTq21X9fL9i2KCPZ1GsXg==} + '@contentstack/cli-utilities@1.18.5': + resolution: {integrity: sha512-0qRZznIiU8jqYl7BTs84w9Ke2fVGRDCY22PSUg0DABR1nzrnTVwTTne/gjhuQUoQjMU7GG4rvAScY0SU/0mHAg==} + + '@contentstack/cli-utilities@2.0.0-beta.10': + resolution: {integrity: sha512-u2fhvYR+P5AateT4+AaUHsdEDxeP/eJZUQvfA0xHZhrwOqN/WVkkXDu96j/g7U0hqdMKRHtXzrYpmdfjEeMtMA==} + '@contentstack/cli-utilities@2.0.0-beta.9': resolution: {integrity: sha512-OWL1ZDl4e1/hCt2+CS+zvFSQuEs0WOfe1HpGNTZzUETj8/gULPhb2wdvTS3vOOcpA55d0rbTt4JjYBa83BpzcA==} @@ -2401,9 +2412,16 @@ packages: resolution: {integrity: sha512-jeOnYw3g/14IdIKjmkzNEb21a5K1SJnDUNwFNBeZyU+Z5aGY4FoPOv98b3quWaMMCtoShW4v2lFHcUPpjVP5Mg==} engines: {node: '>=8.0.0'} + '@contentstack/management@1.30.4': + resolution: {integrity: sha512-wFmHxf2WfPVXD8uvFpaxdY882ELqYhdPu1aQM9VM/UYUtJg+7uCj9k785ujYfgbSKgxfY6APgwI++n59v3Entg==} + engines: {node: '>=8.0.0'} + '@contentstack/marketplace-sdk@1.5.3': resolution: {integrity: sha512-Hj/V7M+C8oazmSZ8/h6dNNKNqPczUiv+gzTaZDFDDW9XqzmbzwZxdoNzOBzpi6IuENsojqqjBP5K4WjKddPzfQ==} + '@contentstack/marketplace-sdk@1.5.4': + resolution: {integrity: sha512-rqsL/FvYTqF1a1MK/AZLdWCGf7WY48f4pT/iLkwt6wxh7apxaAwWSWy9ZWRtDu7EIV9FDDTHZ33iYWKH41fnlw==} + '@contentstack/types-generator@3.10.2': resolution: {integrity: sha512-UAzJH8SMX9xVrQOPyiaq/4jBvqy9a5sRbnBlTCEZBnUcMsGI8TyVjvVp+IlD0M5MsMJmPjygrKKOrIgLHSu+VQ==} @@ -2994,6 +3012,12 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3018,10 +3042,18 @@ packages: resolution: {integrity: sha512-LoGzrvkH9I8dwhxuLafcf90MAp+fYfAiAhpyixaVAWaclIgs+vXeMMQwBG90/wqjdygIKcFAqNnNJrfl3s3X8Q==} engines: {node: '>=18.0.0'} + '@oclif/core@4.11.14': + resolution: {integrity: sha512-cZ5Ktd+rT0PO+o7KBH4vRFTgg+xMLf8F41WK39p8MkXEViZA/Qqe+4lzZT6102zgUxMORET1HtF9t5w8CB3tnQ==} + engines: {node: '>=18.0.0'} + '@oclif/plugin-help@6.2.52': resolution: {integrity: sha512-qtrVz41wHDqG2rvx7xToYHVgJVBRcxE8aPSla/d5wNuHPZsDLm56Nl07pI+DNLA42Xbt9a70POl08qZgBH6FgA==} engines: {node: '>=18.0.0'} + '@oclif/plugin-help@6.2.53': + resolution: {integrity: sha512-njx2nTH87EQEEuz4ShNtL0gzzN981MRkDPqScbu+Tkd7NpIv30OHdTjQK1GzGtkf+V2RvSYIrX+LrLsUVh9DJw==} + engines: {node: '>=18.0.0'} + '@oclif/plugin-not-found@3.2.88': resolution: {integrity: sha512-5YTKSpuV77910/iGnGsj0fr9kOazCy/h1brki1CocbfawdvaVPedcwCH25wMcdRfo8mFD656bG9/kdki/+Wb9A==} engines: {node: '>=18.0.0'} @@ -3058,8 +3090,8 @@ packages: '@otplib/preset-v11@12.0.1': resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==} - '@oxc-project/types@0.137.0': - resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} + '@oxc-project/types@0.138.0': + resolution: {integrity: sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -3089,91 +3121,91 @@ packages: resolution: {integrity: sha512-pmNVGuooS30Mm7YbZd5T7E5zYVO6D5Ct91sn4T39mUvMUc3sCGridcnhAufL1/Bz2QzAtzEn0agNrdk3+5yWzw==} hasBin: true - '@rolldown/binding-android-arm64@1.1.2': - resolution: {integrity: sha512-2cZ+7xRS+DBcuJBJKnfzsbleumJhBqSlJVpuzHC0nTqfd3QQ7Vx2/x5YR/D7cBamKSeWplwo82Fn9lqYUDEMfA==} + '@rolldown/binding-android-arm64@1.1.4': + resolution: {integrity: sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.1.2': - resolution: {integrity: sha512-RkPMJnygxsgOYdkfqgpwY0/Fzm8d0VQe6HGU2/B00Xa9eqdLbrII+DOKAodbJAn3ZL1AJxGHkZRPYazgGY6Ljw==} + '@rolldown/binding-darwin-arm64@1.1.4': + resolution: {integrity: sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.1.2': - resolution: {integrity: sha512-Uiczh6vFhwyfd7WNe7Q7mCA4KxAiLdz7jPE/WGizfRpIieoyFuNVMmM8HqZ9HwudTkY6/AeMQwlNJ9NJijguWw==} + '@rolldown/binding-darwin-x64@1.1.4': + resolution: {integrity: sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.1.2': - resolution: {integrity: sha512-+TpdtTRgHiJFjCVFbw311SuLk3KfytPOQQn+VlAEv+gBxYPtL7E6JS9e/tk+8CwxhIZvemJKo4rTKgfWNsKkkA==} + '@rolldown/binding-freebsd-x64@1.1.4': + resolution: {integrity: sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.1.2': - resolution: {integrity: sha512-4lv1/tkmi7ueIVHnyreaOeUpiZP26BH9rRy6hoYfR9310A2B9nUEVRDvBx69vx64Nr3eTPPRkyciqJJs+j9Jmw==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.4': + resolution: {integrity: sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.1.2': - resolution: {integrity: sha512-gBSUVO0eaWgw1JMjK3gB8BMlX2Mk148s2lTiVT3e9vjVxbl7UDfMWWY8CfIaaqiXuM9fVTMxIpUz6CAo/B6Vlw==} + '@rolldown/binding-linux-arm64-gnu@1.1.4': + resolution: {integrity: sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.1.2': - resolution: {integrity: sha512-LjQP/iZLBu8o8PjIfk4x3At0/mT6h282pvz8Z5LAyhGbu/kDezyO7ea62rF5uoqmgnIYqbN/MqJ3Si3Aymi7xQ==} + '@rolldown/binding-linux-arm64-musl@1.1.4': + resolution: {integrity: sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-ppc64-gnu@1.1.2': - resolution: {integrity: sha512-X/7bVLWelEsbyWDUSXt7zVsTniLLPIY2n1rH58qr78l9i7MNbbxBWD8gI2vRfBWf4NUXJCUuQnfZDsp32LqsfQ==} + '@rolldown/binding-linux-ppc64-gnu@1.1.4': + resolution: {integrity: sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@rolldown/binding-linux-s390x-gnu@1.1.2': - resolution: {integrity: sha512-gb6dYKW/1KDorGXyy48glEBJs/sxVSC5pcVrox/pFGV4mvwSFeg2sK5L2tRkVsVlh7kueqOgg4GEcuipJcGuKg==} + '@rolldown/binding-linux-s390x-gnu@1.1.4': + resolution: {integrity: sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.1.2': - resolution: {integrity: sha512-JY4w85pU3iAiJVMh5nuk4/Mh9GjMsupe8MrIN53rwxAZW64GKrWeJBuN6SxQg9QTU5uB1cxyhDzW8jqRn1EABw==} + '@rolldown/binding-linux-x64-gnu@1.1.4': + resolution: {integrity: sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.1.2': - resolution: {integrity: sha512-xvpA7o5KCYLB0Rwscmuylb1/zHHSUx4g4xilm4prC5jP76pEUlzBmMbgpbh7bVDbId4NcfT96gN5i6mE6UDaiw==} + '@rolldown/binding-linux-x64-musl@1.1.4': + resolution: {integrity: sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.1.2': - resolution: {integrity: sha512-p/ts6KBLjuk49Bp21XH77poQGt02iNz7ChgHep7tudPOaLinR/De/RHdxF8w8Yj4r/bF/bqXwH6PZrB2sA+Nvw==} + '@rolldown/binding-openharmony-arm64@1.1.4': + resolution: {integrity: sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.1.2': - resolution: {integrity: sha512-VMu/wmrZ9hJzYlRhbw7jK5PODlugyKZ5mOdX78+lS8OvuFkWNQdz1pFLrI2p3P0pjXOmUZ7B48o5VnMH9QOGtg==} + '@rolldown/binding-wasm32-wasi@1.1.4': + resolution: {integrity: sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.1.2': - resolution: {integrity: sha512-xtUJqs8qEkuSviS0n1tsohaPuz3a1SPhZywOji4Oo+sgrJs8daEDMZ0QtqL0OS7dx8PoVpg2J/ZZycPY5I2+Zg==} + '@rolldown/binding-win32-arm64-msvc@1.1.4': + resolution: {integrity: sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.1.2': - resolution: {integrity: sha512-85YiLQqjUKgSO/Zjnf9e0XIn5Ymrh1fLDWBeAkZqpuBR/3R8TpfoHXuyblqyQrftSSgWO9qpcHN8mkyKsLraoA==} + '@rolldown/binding-win32-x64-msvc@1.1.4': + resolution: {integrity: sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3534,8 +3566,8 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - '@types/express-serve-static-core@4.19.8': - resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + '@types/express-serve-static-core@4.19.9': + resolution: {integrity: sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg==} '@types/express@4.17.25': resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} @@ -4104,6 +4136,10 @@ packages: resolution: {integrity: sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==} engines: {node: '>=12.0'} + adm-zip@0.5.18: + resolution: {integrity: sha512-ufJnssQGbxzLNS1Ho9bCtX4rQKCCvoVuDLHoJyc3F9dOGDB4BkWs2Ci0kv53lqocAEQ/Cbi+I2XCsNYGqVYqng==} + engines: {node: '>=12.0'} + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -4410,9 +4446,6 @@ packages: peerDependencies: '@babel/core': ^7.11.0 || ^8.0.0-beta.1 - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -4451,14 +4484,8 @@ packages: bowser@2.14.1: resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} - brace-expansion@1.1.15: - resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} - - brace-expansion@2.1.1: - resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} - - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -4787,9 +4814,6 @@ packages: compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@2.0.0: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} @@ -5792,10 +5816,6 @@ packages: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} - engines: {node: '>= 6'} - form-data@4.0.6: resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} @@ -6765,6 +6785,10 @@ packages: resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + hasBin: true + js2xmlparser@4.0.2: resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} @@ -7704,6 +7728,10 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -7729,8 +7757,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + postcss@8.5.16: + resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -7821,6 +7849,10 @@ packages: resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + engines: {node: '>=0.6'} + querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} engines: {node: '>=0.4.x'} @@ -8119,8 +8151,8 @@ packages: engines: {node: 20 || >=22} hasBin: true - rolldown@1.1.2: - resolution: {integrity: sha512-x0CrQQqCXWGeI8dTvFfN/Dnv3yMKT9hv5jFjlOreKAx9wqLq9wz7VvLLHyaAXC90/CpggTu9SisSbsJJTPSjNQ==} + rolldown@1.1.4: + resolution: {integrity: sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -10366,7 +10398,7 @@ snapshots: '@contentstack/cli-auth@2.0.0-beta.13(@types/node@22.20.0)': dependencies: '@contentstack/cli-command': 2.0.0-beta.8(@types/node@22.20.0) - '@contentstack/cli-utilities': 2.0.0-beta.9(@types/node@22.20.0) + '@contentstack/cli-utilities': 2.0.0-beta.10(@types/node@22.20.0) '@oclif/core': 4.11.11 otplib: 12.0.1 transitivePeerDependencies: @@ -10384,6 +10416,16 @@ snapshots: - debug - supports-color + '@contentstack/cli-command@1.8.4(@types/node@20.19.43)': + dependencies: + '@contentstack/cli-utilities': 1.18.5(@types/node@20.19.43) + '@oclif/core': 4.11.14 + contentstack: 3.27.0 + transitivePeerDependencies: + - '@types/node' + - debug + - supports-color + '@contentstack/cli-command@2.0.0-beta.8(@types/node@14.18.63)': dependencies: '@contentstack/cli-utilities': 2.0.0-beta.9(@types/node@14.18.63) @@ -10437,7 +10479,7 @@ snapshots: '@contentstack/cli-config@2.0.0-beta.11(@types/node@18.19.130)': dependencies: '@contentstack/cli-command': 2.0.0-beta.8(@types/node@18.19.130) - '@contentstack/cli-utilities': 2.0.0-beta.9(@types/node@18.19.130) + '@contentstack/cli-utilities': 2.0.0-beta.10(@types/node@18.19.130) '@contentstack/utils': 1.9.1 '@oclif/core': 4.11.11 transitivePeerDependencies: @@ -10448,7 +10490,7 @@ snapshots: '@contentstack/cli-config@2.0.0-beta.11(@types/node@22.20.0)': dependencies: '@contentstack/cli-command': 2.0.0-beta.8(@types/node@22.20.0) - '@contentstack/cli-utilities': 2.0.0-beta.9(@types/node@22.20.0) + '@contentstack/cli-utilities': 2.0.0-beta.10(@types/node@22.20.0) '@contentstack/utils': 1.9.1 '@oclif/core': 4.11.11 transitivePeerDependencies: @@ -10474,25 +10516,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@contentstack/cli-launch@1.11.0(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3)': + '@contentstack/cli-launch@1.11.1(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3)': dependencies: '@apollo/client': 3.14.1(graphql@16.14.2) - '@contentstack/cli-command': 1.8.3(@types/node@20.19.43) - '@contentstack/cli-utilities': 1.18.4(@types/node@20.19.43) - '@oclif/core': 4.11.11 - '@oclif/plugin-help': 6.2.52 + '@contentstack/cli-command': 1.8.4(@types/node@20.19.43) + '@contentstack/cli-utilities': 1.18.5(@types/node@20.19.43) + '@oclif/core': 4.11.14 + '@oclif/plugin-help': 6.2.53 '@rollup/plugin-commonjs': 28.0.9(rollup@4.62.2) '@rollup/plugin-json': 6.1.0(rollup@4.62.2) '@rollup/plugin-node-resolve': 16.0.3(rollup@4.62.2) '@rollup/plugin-typescript': 12.3.0(rollup@4.62.2)(tslib@2.8.1)(typescript@5.9.3) '@types/express': 4.17.25 - '@types/express-serve-static-core': 4.19.8 - adm-zip: 0.5.17 + '@types/express-serve-static-core': 4.19.9 + adm-zip: 0.5.18 chalk: 4.1.2 cross-fetch: 4.1.0 dotenv: 16.6.1 express: 4.22.2 - form-data: 4.0.4 + form-data: 4.0.6 graphql: 16.14.2 ini: 3.0.1 lodash: 4.18.1 @@ -10549,6 +10591,117 @@ snapshots: - debug - supports-color + '@contentstack/cli-utilities@1.18.5(@types/node@20.19.43)': + dependencies: + '@contentstack/management': 1.30.4 + '@contentstack/marketplace-sdk': 1.5.4 + '@oclif/core': 4.11.14 + axios: 1.18.1(debug@4.4.3) + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-progress: 3.12.0 + cli-table: 0.3.11 + conf: 10.2.0 + dotenv: 16.6.1 + figures: 3.2.0 + inquirer: 8.2.7(@types/node@20.19.43) + inquirer-search-checkbox: 1.0.0 + inquirer-search-list: 1.2.6 + js-yaml: 4.3.0 + klona: 2.0.6 + lodash: 4.18.1 + mkdirp: 1.0.4 + open: 8.4.2 + ora: 5.4.1 + papaparse: 5.5.4 + recheck: 4.4.5 + rxjs: 6.6.7 + short-uuid: 6.0.3 + traverse: 0.6.11 + tty-table: 4.2.3 + unique-string: 2.0.0 + uuid: 14.0.0 + winston: 3.19.0 + xdg-basedir: 4.0.0 + transitivePeerDependencies: + - '@types/node' + - debug + - supports-color + + '@contentstack/cli-utilities@2.0.0-beta.10(@types/node@18.19.130)': + dependencies: + '@contentstack/management': 1.30.4 + '@contentstack/marketplace-sdk': 1.5.4 + '@oclif/core': 4.11.11 + axios: 1.18.1(debug@4.4.3) + chalk: 5.6.2 + cli-cursor: 3.1.0 + cli-progress: 3.12.0 + cli-table: 0.3.11 + conf: 10.2.0 + dotenv: 16.6.1 + figures: 3.2.0 + inquirer: 12.11.1(@types/node@18.19.130) + inquirer-search-checkbox: 1.0.0 + inquirer-search-list: 1.2.6 + js-yaml: 4.3.0 + klona: 2.0.6 + lodash: 4.18.1 + mkdirp: 1.0.4 + open: 8.4.2 + ora: 5.4.1 + papaparse: 5.5.4 + recheck: 4.5.0 + rxjs: 6.6.7 + short-uuid: 6.0.3 + traverse: 0.6.11 + tty-table: 4.2.3 + unique-string: 2.0.0 + uuid: 14.0.0 + winston: 3.19.0 + xdg-basedir: 4.0.0 + transitivePeerDependencies: + - '@types/node' + - debug + - supports-color + + '@contentstack/cli-utilities@2.0.0-beta.10(@types/node@22.20.0)': + dependencies: + '@contentstack/management': 1.30.4 + '@contentstack/marketplace-sdk': 1.5.4 + '@oclif/core': 4.11.11 + axios: 1.18.1(debug@4.4.3) + chalk: 5.6.2 + cli-cursor: 3.1.0 + cli-progress: 3.12.0 + cli-table: 0.3.11 + conf: 10.2.0 + dotenv: 16.6.1 + figures: 3.2.0 + inquirer: 12.11.1(@types/node@22.20.0) + inquirer-search-checkbox: 1.0.0 + inquirer-search-list: 1.2.6 + js-yaml: 4.3.0 + klona: 2.0.6 + lodash: 4.18.1 + mkdirp: 1.0.4 + open: 8.4.2 + ora: 5.4.1 + papaparse: 5.5.4 + recheck: 4.5.0 + rxjs: 6.6.7 + short-uuid: 6.0.3 + traverse: 0.6.11 + tty-table: 4.2.3 + unique-string: 2.0.0 + uuid: 14.0.0 + winston: 3.19.0 + xdg-basedir: 4.0.0 + transitivePeerDependencies: + - '@types/node' + - debug + - supports-color + '@contentstack/cli-utilities@2.0.0-beta.9(@types/node@14.18.63)': dependencies: '@contentstack/management': 1.30.3(debug@4.4.3) @@ -10786,6 +10939,22 @@ snapshots: - debug - supports-color + '@contentstack/management@1.30.4': + dependencies: + '@contentstack/utils': 1.9.1 + assert: 2.1.0 + axios: 1.18.1(debug@4.4.3) + buffer: 6.0.3 + form-data: 4.0.6 + husky: 9.1.7 + lodash: 4.18.1 + otplib: 12.0.1 + qs: 6.15.3 + stream-browserify: 3.0.0 + transitivePeerDependencies: + - debug + - supports-color + '@contentstack/marketplace-sdk@1.5.3(debug@4.4.3)': dependencies: '@contentstack/utils': 1.9.1 @@ -10794,6 +10963,14 @@ snapshots: - debug - supports-color + '@contentstack/marketplace-sdk@1.5.4': + dependencies: + '@contentstack/utils': 1.9.1 + axios: 1.18.1(debug@4.4.3) + transitivePeerDependencies: + - debug + - supports-color + '@contentstack/types-generator@3.10.2(graphql@16.14.2)': dependencies: '@contentstack/delivery-sdk': 5.2.1 @@ -11785,14 +11962,14 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.43 + '@types/node': 22.20.0 jest-mock: 29.7.0 '@jest/environment@30.4.1': dependencies: '@jest/fake-timers': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 20.19.43 + '@types/node': 18.19.130 jest-mock: 30.4.1 '@jest/expect-utils@29.7.0': @@ -11821,7 +11998,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.19.43 + '@types/node': 22.20.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -11830,7 +12007,7 @@ snapshots: dependencies: '@jest/types': 30.4.1 '@sinonjs/fake-timers': 15.4.0 - '@types/node': 20.19.43 + '@types/node': 18.19.130 jest-message-util: 30.4.1 jest-mock: 30.4.1 jest-util: 30.4.1 @@ -12073,7 +12250,7 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true - '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: '@emnapi/core': 1.11.1 '@emnapi/runtime': 1.11.1 @@ -12146,10 +12323,35 @@ snapshots: wordwrap: 1.0.0 wrap-ansi: 7.0.0 + '@oclif/core@4.11.14': + dependencies: + ansi-escapes: 4.3.2 + ansis: 3.17.0 + clean-stack: 3.0.1 + cli-spinners: 2.9.2 + debug: 4.4.3(supports-color@8.1.1) + ejs: 3.1.10 + get-package-type: 0.1.0 + indent-string: 4.0.0 + is-wsl: 2.2.0 + lilconfig: 3.1.3 + minimatch: 10.2.5 + semver: 7.8.5 + string-width: 4.2.3 + supports-color: 8.1.1 + tinyglobby: 0.2.17 + widest-line: 3.1.0 + wordwrap: 1.0.0 + wrap-ansi: 7.0.0 + '@oclif/plugin-help@6.2.52': dependencies: '@oclif/core': 4.11.11 + '@oclif/plugin-help@6.2.53': + dependencies: + '@oclif/core': 4.11.14 + '@oclif/plugin-not-found@3.2.88(@types/node@14.18.63)': dependencies: '@inquirer/prompts': 7.10.1(@types/node@14.18.63) @@ -12213,6 +12415,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@oclif/test@4.1.20(@oclif/core@4.11.14)': + dependencies: + '@oclif/core': 4.11.14 + ansis: 3.17.0 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@otplib/core@12.0.1': {} '@otplib/plugin-crypto@12.0.1': @@ -12236,7 +12446,7 @@ snapshots: '@otplib/plugin-crypto': 12.0.1 '@otplib/plugin-thirty-two': 12.0.1 - '@oxc-project/types@0.137.0': {} + '@oxc-project/types@0.138.0': {} '@pkgjs/parseargs@0.11.0': optional: true @@ -12261,53 +12471,53 @@ snapshots: dependencies: nopt: 1.0.10 - '@rolldown/binding-android-arm64@1.1.2': + '@rolldown/binding-android-arm64@1.1.4': optional: true - '@rolldown/binding-darwin-arm64@1.1.2': + '@rolldown/binding-darwin-arm64@1.1.4': optional: true - '@rolldown/binding-darwin-x64@1.1.2': + '@rolldown/binding-darwin-x64@1.1.4': optional: true - '@rolldown/binding-freebsd-x64@1.1.2': + '@rolldown/binding-freebsd-x64@1.1.4': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.1.2': + '@rolldown/binding-linux-arm-gnueabihf@1.1.4': optional: true - '@rolldown/binding-linux-arm64-gnu@1.1.2': + '@rolldown/binding-linux-arm64-gnu@1.1.4': optional: true - '@rolldown/binding-linux-arm64-musl@1.1.2': + '@rolldown/binding-linux-arm64-musl@1.1.4': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.1.2': + '@rolldown/binding-linux-ppc64-gnu@1.1.4': optional: true - '@rolldown/binding-linux-s390x-gnu@1.1.2': + '@rolldown/binding-linux-s390x-gnu@1.1.4': optional: true - '@rolldown/binding-linux-x64-gnu@1.1.2': + '@rolldown/binding-linux-x64-gnu@1.1.4': optional: true - '@rolldown/binding-linux-x64-musl@1.1.2': + '@rolldown/binding-linux-x64-musl@1.1.4': optional: true - '@rolldown/binding-openharmony-arm64@1.1.2': + '@rolldown/binding-openharmony-arm64@1.1.4': optional: true - '@rolldown/binding-wasm32-wasi@1.1.2': + '@rolldown/binding-wasm32-wasi@1.1.4': dependencies: '@emnapi/core': 1.11.1 '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.1.2': + '@rolldown/binding-win32-arm64-msvc@1.1.4': optional: true - '@rolldown/binding-win32-x64-msvc@1.1.2': + '@rolldown/binding-win32-x64-msvc@1.1.4': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -12317,10 +12527,10 @@ snapshots: '@rollup/pluginutils': 5.4.0(rollup@4.62.2) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.4) + fdir: 6.5.0(picomatch@4.0.5) is-reference: 1.2.1 magic-string: 0.30.21 - picomatch: 4.0.4 + picomatch: 4.0.5 optionalDependencies: rollup: 4.62.2 @@ -12353,7 +12563,7 @@ snapshots: dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 - picomatch: 4.0.4 + picomatch: 4.0.5 optionalDependencies: rollup: 4.62.2 @@ -12617,7 +12827,7 @@ snapshots: eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.4 + picomatch: 4.0.5 '@stylistic/eslint-plugin@5.10.0(eslint@8.57.1)': dependencies: @@ -12627,7 +12837,7 @@ snapshots: eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.4 + picomatch: 4.0.5 '@stylistic/eslint-plugin@5.10.0(eslint@9.39.4)': dependencies: @@ -12637,7 +12847,7 @@ snapshots: eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.4 + picomatch: 4.0.5 '@szmarczak/http-timer@5.0.1': dependencies: @@ -12717,7 +12927,7 @@ snapshots: '@types/estree@1.0.9': {} - '@types/express-serve-static-core@4.19.8': + '@types/express-serve-static-core@4.19.9': dependencies: '@types/node': 20.19.43 '@types/qs': 6.15.1 @@ -12727,7 +12937,7 @@ snapshots: '@types/express@4.17.25': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.8 + '@types/express-serve-static-core': 4.19.9 '@types/qs': 6.15.1 '@types/serve-static': 1.15.10 @@ -12740,7 +12950,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.19.43 + '@types/node': 22.20.0 '@types/hogan.js@3.0.5': {} @@ -13907,6 +14117,8 @@ snapshots: adm-zip@0.5.17: {} + adm-zip@0.5.18: {} + agent-base@6.0.2: dependencies: debug: 4.4.3(supports-color@8.1.1) @@ -14257,8 +14469,6 @@ snapshots: babel-plugin-jest-hoist: 30.4.0 babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.7) - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} base64-js@1.5.1: {} @@ -14300,7 +14510,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.15.2 + qs: 6.15.3 raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 @@ -14309,16 +14519,7 @@ snapshots: bowser@2.14.1: {} - brace-expansion@1.1.15: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.1.1: - dependencies: - balanced-match: 1.0.2 - - brace-expansion@5.0.6: + brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 @@ -14688,8 +14889,6 @@ snapshots: array-ify: 1.0.0 dot-prop: 5.3.0 - concat-map@0.0.1: {} - concat-stream@2.0.0: dependencies: buffer-from: 1.1.2 @@ -16579,7 +16778,7 @@ snapshots: parseurl: 1.3.3 path-to-regexp: 0.1.13 proxy-addr: 2.0.7 - qs: 6.15.2 + qs: 6.15.3 range-parser: 1.2.1 safe-buffer: 5.2.1 send: 0.19.2 @@ -16668,6 +16867,10 @@ snapshots: optionalDependencies: picomatch: 4.0.4 + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + fecha@4.2.3: {} figures@1.7.0: @@ -16785,14 +16988,6 @@ snapshots: form-data-encoder@2.1.4: {} - form-data@4.0.4: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.4 - mime-types: 2.1.35 - form-data@4.0.6: dependencies: asynckit: 0.4.0 @@ -17617,7 +17812,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.43 + '@types/node': 22.20.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.2 @@ -17643,7 +17838,7 @@ snapshots: '@jest/expect': 30.4.1 '@jest/test-result': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 20.19.43 + '@types/node': 18.19.130 chalk: 4.1.2 co: 4.6.0 dedent: 1.7.2 @@ -17958,7 +18153,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.19.43 + '@types/node': 22.20.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -17967,7 +18162,7 @@ snapshots: '@jest/environment': 30.4.1 '@jest/fake-timers': 30.4.1 '@jest/types': 30.4.1 - '@types/node': 20.19.43 + '@types/node': 18.19.130 jest-mock: 30.4.1 jest-util: 30.4.1 jest-validate: 30.4.1 @@ -18059,7 +18254,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.43 + '@types/node': 22.20.0 jest-util: 29.7.0 jest-mock@30.4.1: @@ -18335,14 +18530,14 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 20.19.43 + '@types/node': 22.20.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@30.4.1: dependencies: - '@types/node': 20.19.43 + '@types/node': 18.19.130 '@ungap/structured-clone': 1.3.2 jest-util: 30.4.1 merge-stream: 2.0.0 @@ -18396,6 +18591,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.3.0: + dependencies: + argparse: 2.0.1 + js2xmlparser@4.0.2: dependencies: xmlcreate: 2.0.4 @@ -18863,23 +19062,23 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.6 + brace-expansion: 5.0.7 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.15 + brace-expansion: 5.0.7 minimatch@5.1.9: dependencies: - brace-expansion: 2.1.1 + brace-expansion: 5.0.7 minimatch@9.0.3: dependencies: - brace-expansion: 2.1.1 + brace-expansion: 5.0.7 minimatch@9.0.9: dependencies: - brace-expansion: 2.1.1 + brace-expansion: 5.0.7 minimist@1.2.8: {} @@ -19499,6 +19698,8 @@ snapshots: picomatch@4.0.4: {} + picomatch@4.0.5: {} + pirates@4.0.7: {} pkg-dir@4.2.0: @@ -19515,7 +19716,7 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss@8.5.15: + postcss@8.5.16: dependencies: nanoid: 3.3.15 picocolors: 1.1.1 @@ -19613,6 +19814,11 @@ snapshots: dependencies: side-channel: 1.1.1 + qs@6.15.3: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + querystring@0.2.1: {} querystringify@2.2.0: {} @@ -19904,26 +20110,26 @@ snapshots: glob: 13.0.6 package-json-from-dist: 1.0.1 - rolldown@1.1.2: + rolldown@1.1.4: dependencies: - '@oxc-project/types': 0.137.0 + '@oxc-project/types': 0.138.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.2 - '@rolldown/binding-darwin-arm64': 1.1.2 - '@rolldown/binding-darwin-x64': 1.1.2 - '@rolldown/binding-freebsd-x64': 1.1.2 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.2 - '@rolldown/binding-linux-arm64-gnu': 1.1.2 - '@rolldown/binding-linux-arm64-musl': 1.1.2 - '@rolldown/binding-linux-ppc64-gnu': 1.1.2 - '@rolldown/binding-linux-s390x-gnu': 1.1.2 - '@rolldown/binding-linux-x64-gnu': 1.1.2 - '@rolldown/binding-linux-x64-musl': 1.1.2 - '@rolldown/binding-openharmony-arm64': 1.1.2 - '@rolldown/binding-wasm32-wasi': 1.1.2 - '@rolldown/binding-win32-arm64-msvc': 1.1.2 - '@rolldown/binding-win32-x64-msvc': 1.1.2 + '@rolldown/binding-android-arm64': 1.1.4 + '@rolldown/binding-darwin-arm64': 1.1.4 + '@rolldown/binding-darwin-x64': 1.1.4 + '@rolldown/binding-freebsd-x64': 1.1.4 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.4 + '@rolldown/binding-linux-arm64-gnu': 1.1.4 + '@rolldown/binding-linux-arm64-musl': 1.1.4 + '@rolldown/binding-linux-ppc64-gnu': 1.1.4 + '@rolldown/binding-linux-s390x-gnu': 1.1.4 + '@rolldown/binding-linux-x64-gnu': 1.1.4 + '@rolldown/binding-linux-x64-musl': 1.1.4 + '@rolldown/binding-openharmony-arm64': 1.1.4 + '@rolldown/binding-wasm32-wasi': 1.1.4 + '@rolldown/binding-win32-arm64-msvc': 1.1.4 + '@rolldown/binding-win32-x64-msvc': 1.1.4 rollup@4.62.2: dependencies: @@ -21167,9 +21373,9 @@ snapshots: vite@8.1.0(@types/node@20.19.43)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.15 - rolldown: 1.1.2 + picomatch: 4.0.5 + postcss: 8.5.16 + rolldown: 1.1.4 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 20.19.43 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 09942b8ba..30d01492e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,3 +5,4 @@ overrides: follow-redirects: 1.16.0 uuid: 14.0.0 lodash: 4.18.1 + brace-expansion: 5.0.7 From e5260b7eddb1ccf1c00530ed7d37c45016ab7c72 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 10 Jul 2026 13:59:53 +0530 Subject: [PATCH 24/44] fix: Update flags in AssetsPublishCommand and add user reminder in ImportCommand for asset publishing --- .talismanrc | 2 ++ .../src/commands/cm/assets/publish.js | 2 +- .../src/commands/cm/stacks/import.ts | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.talismanrc b/.talismanrc index ae12936cd..76ff7e4b3 100644 --- a/.talismanrc +++ b/.talismanrc @@ -67,4 +67,6 @@ fileignoreconfig: checksum: 653a7e0443f6b9712ed91ad45aa4189864bee710ea4bd3ac40031225da4da5a5 - filename: pnpm-lock.yaml checksum: 07642e8dd04d580185a459e5b088d8a1bb4e91be4e04f4842bf4fe4775205bf6 +- filename: packages/contentstack-import/src/commands/cm/stacks/import.ts + checksum: 5ae9bf66f5b5b4ef2c5ec337f8f1a30b379ce984b1087508d368548fa6adbb0e version: '1.0' diff --git a/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js b/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js index 3aecb2c8e..22416e2e9 100644 --- a/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js +++ b/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js @@ -192,7 +192,7 @@ AssetsPublishCommand.flags = { 'data-dir': flags.string({ description: '(optional) Path to the import backup directory. When set, each imported asset is published only to the environments and locales it was published to in the source stack (read from the backup’s publish details and asset UID mapping), with asset-scan gating applied. Intended for the post-import publish flow.', - exclusive: ['source-env', 'folder-uid'], + exclusive: ['source-env', 'folder-uid', 'environments', 'locales'], }), 'bulk-publish': flags.string({ description: 'Set this flag to use Contentstack’s Bulk Publish APIs. It is true, by default.', diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 74217cf45..95387d15f 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -187,6 +187,23 @@ export default class ImportCommand extends Command { log.success(`The log has been stored at: ${getLogPath()}`, importConfig.context); log.info(`The backup content has been stored at: ${backupDir}`, importConfig.context); + + // Closing reminder: when assets were imported but not published inline + // (asset scanning enabled, or --skip-assets-publish), point the user to + // cm:assets:publish with the backup dir and stack pre-filled so the note + // isn't lost in the per-module logs above. + const assetsImported = importConfig.moduleName + ? importConfig.moduleName === 'assets' + : importConfig.modules?.types?.includes('assets'); + // Mirror the publish gate in assets.ts (`!skipAssetsPublish`): assets are + // left unpublished exactly when skipAssetsPublish is set — which also + // covers the scanning case, since detecting scanning sets skipAssetsPublish. + if (!result?.noSuccessMsg && assetsImported && importConfig.skipAssetsPublish) { + log.info( + `Note: assets were imported but not published asset scanning is enabled and must complete first. To publish them, run:\n csdx cm:assets:publish --data-dir ${backupDir} --stack-api-key ${importConfig.apiKey}`, + importConfig.context, + ); + } } catch (error) { handleAndLogError(error); log.info(`The log has been stored at '${getLogPath()}'`); From 32ba9c47d5ca8cea188556a19fe44af5bf67cafa Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Tue, 14 Jul 2026 15:53:02 +0530 Subject: [PATCH 25/44] fix: Rename 'data-dir' to 'backup-dir' in asset publishing commands and update related logic --- .../src/commands/cm/assets/publish.js | 18 +++++++++--------- .../src/consumer/publish.js | 4 ++-- .../src/producer/publish-assets.js | 18 +++++++++--------- .../src/commands/cm/stacks/import.ts | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js b/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js index 22416e2e9..b121906c9 100644 --- a/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js +++ b/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js @@ -15,12 +15,12 @@ class AssetsPublishCommand extends Command { assetsFlags.folderUid = assetsFlags['folder-uid'] || assetsFlags.folderUid; assetsFlags.bulkPublish = assetsFlags['bulk-publish'] || assetsFlags.bulkPublish; assetsFlags.apiVersion = assetsFlags['api-version'] || '3'; // setting default value for apiVersion - assetsFlags.dataDir = assetsFlags['data-dir'] || assetsFlags.dataDir; + assetsFlags.backupDir = assetsFlags['backup-dir'] || assetsFlags.backupDir; delete assetsFlags['api-version']; delete assetsFlags['retry-failed']; delete assetsFlags['folder-uid']; delete assetsFlags['bulk-publish']; - delete assetsFlags['data-dir']; + delete assetsFlags['backup-dir']; let updatedFlags; try { @@ -113,15 +113,15 @@ class AssetsPublishCommand extends Command { } } - validate({ environments, retryFailed, locales, dataDir, 'source-env': sourceEnv, 'delivery-token': deliveryToken }) { + validate({ environments, retryFailed, locales, backupDir, 'source-env': sourceEnv, 'delivery-token': deliveryToken }) { let missing = []; if (retryFailed) { return true; } - // In data-dir mode, environments and locales are derived per-asset from the + // In backup-dir mode, environments and locales are derived per-asset from the // backup publish_details, so they are not required on the command line. - if (dataDir) { + if (backupDir) { return true; } @@ -189,7 +189,7 @@ AssetsPublishCommand.flags = { '(optional) The UID of the Assets’ folder from which the assets need to be published. The default value is cs_root.', exclusive: ['source-env'], }), - 'data-dir': flags.string({ + 'backup-dir': flags.string({ description: '(optional) Path to the import backup directory. When set, each imported asset is published only to the environments and locales it was published to in the source stack (read from the backup’s publish details and asset UID mapping), with asset-scan gating applied. Intended for the post-import publish flow.', exclusive: ['source-env', 'folder-uid', 'environments', 'locales'], @@ -273,13 +273,13 @@ AssetsPublishCommand.examples = [ 'Using --stack-api-key flag', 'csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY]', '', - 'Using --data-dir flag (publish imported assets to their original environments after asset scanning)', - 'csdx cm:assets:publish --data-dir [PATH TO IMPORT BACKUP DIR] --stack-api-key [STACK API KEY]', + 'Using --backup-dir flag (publish imported assets to their original environments after asset scanning)', + 'csdx cm:assets:publish --backup-dir [PATH TO IMPORT BACKUP DIR] --stack-api-key [STACK API KEY]', ]; AssetsPublishCommand.aliases = ['cm:bulk-publish:assets']; AssetsPublishCommand.usage = - 'cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--data-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]'; + 'cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--backup-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]'; module.exports = AssetsPublishCommand; diff --git a/packages/contentstack-bulk-publish/src/consumer/publish.js b/packages/contentstack-bulk-publish/src/consumer/publish.js index f466b250c..cea6392fd 100644 --- a/packages/contentstack-bulk-publish/src/consumer/publish.js +++ b/packages/contentstack-bulk-publish/src/consumer/publish.js @@ -61,12 +61,12 @@ function displayEntriesDetails(sanitizedData, action, mapping = []) { function displayAssetsDetails(sanitizedData, action, mapping) { if (action === 'bulk_publish') { sanitizedData.forEach((asset) => { - asset?.publish_details.forEach((pd) => { + asset?.publish_details?.forEach((pd) => { if (Object.keys(mapping).includes(pd.environment)) { console.log( chalk.green( `Asset UID: '${asset.uid}'${pd.version ? `, Version: '${pd.version}'` : ''}${ - asset.locale ? `, Locale: '${asset.locale}'` : '' + asset.locale ? `, Locale: '${asset.locale}'` : ''} }, Environment: ${pd.environment}`, ), ); diff --git a/packages/contentstack-bulk-publish/src/producer/publish-assets.js b/packages/contentstack-bulk-publish/src/producer/publish-assets.js index df5af5da4..f35f2d751 100644 --- a/packages/contentstack-bulk-publish/src/producer/publish-assets.js +++ b/packages/contentstack-bulk-publish/src/producer/publish-assets.js @@ -256,16 +256,16 @@ async function processPendingAssets(pendingItems, stack, bulkPublish, environmen * subset). The single in-memory floor is the asset uid-mapping file itself (same * as import's publish()); for very large stacks raise Node's --max-old-space-size. */ -async function getAssetsFromBackup(stack, dataDir, bulkPublish, apiVersion, bulkPublishLimit) { - const assetsPath = path.join(dataDir, 'assets'); +async function getAssetsFromBackup(stack, backupDir, bulkPublish, apiVersion, bulkPublishLimit) { + const assetsPath = path.join(backupDir, 'assets'); const assetsIndexPath = path.join(assetsPath, 'assets.json'); - const assetUidMapperPath = path.join(dataDir, 'mapper', 'assets', 'uid-mapping.json'); - const envUidMapperPath = path.join(dataDir, 'mapper', 'environments', 'uid-mapping.json'); - const environmentsPath = path.join(dataDir, 'environments', 'environments.json'); + const assetUidMapperPath = path.join(backupDir, 'mapper', 'assets', 'uid-mapping.json'); + const envUidMapperPath = path.join(backupDir, 'mapper', 'environments', 'uid-mapping.json'); + const environmentsPath = path.join(backupDir, 'environments', 'environments.json'); // A backup with no assets is a legitimate outcome of a successful import that // had 0 assets (assets.json is never produced) — exit cleanly, not as a crash. - // A genuinely wrong --data-dir surfaces via the uid-mapping/environments guards below. + // A genuinely wrong --backup-dir surfaces via the uid-mapping/environments guards below. if (!existsSync(assetsPath) || !existsSync(assetsIndexPath)) { console.log(chalk.yellow('No assets found in backup — nothing to publish.')); return; @@ -457,7 +457,7 @@ function setConfig(conf, bp) { scanSummary = { clean: 0, quarantined: 0, inQueue: 0, noStatus: 0 }; } -async function start({ retryFailed, bulkPublish, environments, folderUid, locales, apiVersion, dataDir }, stack, config) { +async function start({ retryFailed, bulkPublish, environments, folderUid, locales, apiVersion, backupDir }, stack, config) { process.on('beforeExit', async () => { // Print the scan summary here (not inline after enqueueing): printScanSummary(scanSummary); @@ -498,12 +498,12 @@ async function start({ retryFailed, bulkPublish, environments, folderUid, locale } else { await retryFailedLogs(retryFailed, { assetQueue: queue }, 'publish'); } - } else if (dataDir) { + } else if (backupDir) { // Post-import flow: publish each imported asset only to its original // environments/locales (from backup publish_details), scan-gated. setConfig(config, bulkPublish); const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid); - await getAssetsFromBackup(stack, dataDir, bulkPublish, apiVersion, bulkPublishLimit); + await getAssetsFromBackup(stack, backupDir, bulkPublish, apiVersion, bulkPublishLimit); } else if (folderUid) { setConfig(config, bulkPublish); const bulkPublishLimit = fetchBulkPublishLimit(stack?.org_uid); diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 95387d15f..7cfc7f49a 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -200,7 +200,7 @@ export default class ImportCommand extends Command { // covers the scanning case, since detecting scanning sets skipAssetsPublish. if (!result?.noSuccessMsg && assetsImported && importConfig.skipAssetsPublish) { log.info( - `Note: assets were imported but not published asset scanning is enabled and must complete first. To publish them, run:\n csdx cm:assets:publish --data-dir ${backupDir} --stack-api-key ${importConfig.apiKey}`, + `Note: assets were imported but not published asset scanning is enabled and must complete first. To publish them, run:\n csdx cm:assets:publish --backup-dir ${backupDir} --stack-api-key ${importConfig.apiKey}`, importConfig.context, ); } From 8e4d6c48f673e772379a39ce2df67ec711d5df82 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 16 Jul 2026 14:35:11 +0530 Subject: [PATCH 26/44] updated logs --- .talismanrc | 2 ++ packages/contentstack-import/src/import/modules/assets.ts | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.talismanrc b/.talismanrc index e93a2ed36..a4c73f7b4 100644 --- a/.talismanrc +++ b/.talismanrc @@ -56,4 +56,6 @@ fileignoreconfig: checksum: 5b2050b283ea3d990e8ad3207b054c6932b76d2bd82a9f659b287ef11dec9f83 - filename: packages/contentstack-export/src/utils/export-config-handler.ts checksum: 39a5f63dab167c6ed442391ed0528a457ef9f32a7d9e9972d1f8cc54289d67b3 +- filename: packages/contentstack-import/src/import/modules/assets.ts + checksum: 828b9ea0418a4fdcffc41bc8391e851215eef9b6cdb14ef4e11ea3e5b2538f65 version: "" diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index 6117a145a..e401c3222 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -205,13 +205,13 @@ export default class ImportAssets extends BaseClass { log.success('Assets imported successfully!', this.importConfig.context); if (this.importConfig.assetScanningEnabled) { - log.info(' Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info('Asset Scanning is enabled for this stack.', this.importConfig.context); + log.info('Assets cannot be published immediately — scanning must complete first.', this.importConfig.context); + log.info('Once scanning is done, publish your assets using:', this.importConfig.context); log.info( - ' Assets cannot be published immediately — scanning must complete first.', + 'csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key --operation publish', this.importConfig.context, ); - log.info(' Once scanning is done, publish your assets using:', this.importConfig.context); - log.info(' csdx cm:stacks:bulk-assets --data-dir ./content --stack-api-key --operation publish', this.importConfig.context); } } catch (error) { this.completeProgress(false, error?.message || 'Asset import failed'); From c6d6e1eaa20ee0a96254fcc3f6552f038896e2e3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 16 Jul 2026 17:30:04 +0530 Subject: [PATCH 27/44] added type --- packages/contentstack-import/src/import/modules/assets.ts | 6 +++--- packages/contentstack-import/src/types/import-config.ts | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index e401c3222..93e6bbc2a 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -8,7 +8,7 @@ import uniq from 'lodash/uniq'; import { existsSync } from 'node:fs'; import includes from 'lodash/includes'; import { resolve as pResolve, join } from 'node:path'; -import { FsUtility, log, handleAndLogError, generateUid } from '@contentstack/cli-utilities'; +import { FsUtility, log, handleAndLogError, generateUid, FeatureStatus } from '@contentstack/cli-utilities'; import { ImportSpaces, type SpaceMapping } from '@contentstack/cli-asset-management'; import { PATH_CONSTANTS } from '../../constants'; @@ -39,13 +39,13 @@ export default class ImportAssets extends BaseClass { private assetsUrlMap: Record = {}; private assetsFolderMap: Record = {}; private rootFolder: { uid: string; name: string; parent_uid: string; created_at: string }; - private planStatus: Record = {}; + private planStatus: Record = {}; constructor({ importConfig, stackAPIClient }: ModuleClassParams) { super({ importConfig, stackAPIClient }); this.importConfig.context.module = MODULE_CONTEXTS.ASSETS; this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.ASSETS]; - this.planStatus = this.importConfig.planStatus; + this.planStatus = this.importConfig.planStatus || {}; this.assetsPath = join(this.importConfig.backupDir, PATH_CONSTANTS.CONTENT_DIRS.ASSETS); this.mapperDirPath = join(this.importConfig.backupDir, PATH_CONSTANTS.MAPPER, PATH_CONSTANTS.MAPPER_MODULES.ASSETS); diff --git a/packages/contentstack-import/src/types/import-config.ts b/packages/contentstack-import/src/types/import-config.ts index 6f8e06515..5fea67cce 100644 --- a/packages/contentstack-import/src/types/import-config.ts +++ b/packages/contentstack-import/src/types/import-config.ts @@ -1,3 +1,4 @@ +import { FeatureStatus } from '@contentstack/cli-utilities'; import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; @@ -61,7 +62,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig { context: Context; csAssetsUrl?: string; csAssetsEnabled?: boolean; - planStatus: any; + planStatus?: Record; } type branch = { From af9140c3dd06e362124a82c8a432214f028599e2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 16 Jul 2026 17:45:48 +0530 Subject: [PATCH 28/44] added type --- packages/contentstack-export/src/types/export-config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/contentstack-export/src/types/export-config.ts b/packages/contentstack-export/src/types/export-config.ts index acf43724c..33cf163c0 100644 --- a/packages/contentstack-export/src/types/export-config.ts +++ b/packages/contentstack-export/src/types/export-config.ts @@ -1,3 +1,4 @@ +import { FeatureStatus } from '@contentstack/cli-utilities'; import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; @@ -36,7 +37,7 @@ export default interface ExportConfig extends DefaultConfig { skipDependencies?: boolean; authenticationMethod?: string; linkedWorkspaces?: Array<{ uid: string; space_uid: string; is_default: boolean }>; - planStatus: any; + planStatus?: Record; } type branch = { From 53b9674fca902675d728e01aade2d0238b0c309e Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 23 Jul 2026 16:13:34 +0530 Subject: [PATCH 29/44] added support for orgplan check in export and import --- .talismanrc | 4 ++ packages/contentstack-export/package.json | 3 +- .../src/commands/cm/stacks/export.ts | 2 +- .../src/types/export-config.ts | 2 + .../src/utils/export-config-handler.ts | 42 +++++++++++++++++-- packages/contentstack-import/package.json | 3 +- .../src/commands/cm/stacks/import.ts | 2 +- .../src/import/module-importer.ts | 16 ------- .../src/import/modules/assets.ts | 12 ++++-- .../src/types/import-config.ts | 2 + .../src/utils/import-config-handler.ts | 31 +++++++++++++- 11 files changed, 90 insertions(+), 29 deletions(-) diff --git a/.talismanrc b/.talismanrc index 8577dbcbd..90ec9724b 100644 --- a/.talismanrc +++ b/.talismanrc @@ -12,4 +12,8 @@ fileignoreconfig: checksum: 8cafd5994d3ec13ba9af74c80b330bfd14721ea4e0359b456598964a6c2913ce - filename: packages/contentstack-seed/tests/contentstack.test.ts checksum: 04196568bf29f4693e968079867e87d96219b022bfee0f4697dce1b9bc161ac3 +- filename: packages/contentstack-export/src/utils/export-config-handler.ts + checksum: 362c1042a70958b52e73a7a3096152cf0259c55095c8b2c6f308b8f5fb90614e +- filename: packages/contentstack-import/src/utils/import-config-handler.ts + checksum: f310186b5ea1fc756bd200dbe01967bc07e5490dc5ed17018f0ca4b35f0fd86f version: '1.0' diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index ece2abd96..def2158fb 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -93,7 +93,8 @@ "shortCommandName": { "cm:stacks:export": "EXPRT", "cm:export": "O-EXPRT" - } + }, + "planProtectedFeatures": ["assetsScan"] }, "repository": "https://github.com/contentstack/cli" } diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 15f88c573..d7dd749e5 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -120,7 +120,7 @@ export default class ExportCommand extends Command { let exportDir: string = pathValidator('logs'); try { const { flags } = await this.parse(ExportCommand); - const exportConfig = await setupExportConfig(flags); + const exportConfig = await setupExportConfig(flags, this.context); // Store apiKey in configHandler for session.json (return value not needed) createLogContext( diff --git a/packages/contentstack-export/src/types/export-config.ts b/packages/contentstack-export/src/types/export-config.ts index 8b0e1b37b..a6fd5fe4c 100644 --- a/packages/contentstack-export/src/types/export-config.ts +++ b/packages/contentstack-export/src/types/export-config.ts @@ -1,3 +1,4 @@ +import { FeatureStatus } from '@contentstack/cli-utilities'; import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; @@ -36,6 +37,7 @@ export default interface ExportConfig extends DefaultConfig { skipStackSettings?: boolean; skipDependencies?: boolean; authenticationMethod?: string; + planStatus?: Record; } type branch = { diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index c67b6c12b..bf984f3da 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -1,6 +1,14 @@ import merge from 'merge'; import * as path from 'path'; -import { configHandler, isAuthenticated,cliux, sanitizePath, log } from '@contentstack/cli-utilities'; +import { + configHandler, + isAuthenticated, + cliux, + sanitizePath, + log, + FeatureCtx, + isFeatureEnabled, +} from '@contentstack/cli-utilities'; import defaultConfig from '../config'; import { readFile } from './file-helper'; import { askExportDir, askAPIKey } from './interactive'; @@ -8,7 +16,7 @@ import login from './basic-login'; import { filter, includes } from 'lodash'; import { ExportConfig } from '../types'; -const setupConfig = async (exportCmdFlags: any): Promise => { +const setupConfig = async (exportCmdFlags: any, context?: any): Promise => { let config = merge({}, defaultConfig); // Track authentication method @@ -97,7 +105,7 @@ const setupConfig = async (exportCmdFlags: any): Promise => { if (exportCmdFlags['branch-alias']) { config.branchAlias = exportCmdFlags['branch-alias']; - } + } if (exportCmdFlags['branch']) { config.branchName = exportCmdFlags['branch']; } @@ -133,10 +141,36 @@ const setupConfig = async (exportCmdFlags: any): Promise => { } } - // Add authentication details to config for context tracking + // Add authentication details to config for context tracking config.authenticationMethod = authenticationMethod; log.debug('Export configuration setup completed.', { ...config }); + // Deferred plan check — credentials now available after setupExportConfig + const deferredFeatures: string[] = context?.planCheckRequired ?? []; + if (deferredFeatures.length > 0) { + const planCtx: FeatureCtx = { + apiKey: config.apiKey, + managementToken: config.management_token, + authToken: config.auth_token, + }; + for (const featureUid of deferredFeatures) { + try { + const status = await isFeatureEnabled(featureUid, planCtx); + if (context) { + context.planStatus[featureUid] = status; + } + + log.debug(`[export] Deferred plan status fetched for "${featureUid}".`); + } catch (error) { + log.warn(`[export] Could not fetch deferred plan status for "${featureUid}": ${(error as Error).message}`); + } + } + } + + if (context?.planStatus) { + config.planStatus = context.planStatus; + } + return config; }; diff --git a/packages/contentstack-import/package.json b/packages/contentstack-import/package.json index d26a96032..9b72827aa 100644 --- a/packages/contentstack-import/package.json +++ b/packages/contentstack-import/package.json @@ -85,7 +85,8 @@ "shortCommandName": { "cm:stacks:import": "IMPRT", "cm:import": "O-IMPRT" - } + }, + "planProtectedFeatures": ["assetsScan"] }, "repository": "https://github.com/contentstack/cli" } diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 7cfc7f49a..0d795b66b 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -154,7 +154,7 @@ export default class ImportCommand extends Command { let importConfig: ImportConfig; try { const { flags } = await this.parse(ImportCommand); - importConfig = await setupImportConfig(flags); + importConfig = await setupImportConfig(flags, this.context); // Prepare the context object createLogContext( this.context?.info?.command || 'cm:stacks:export', diff --git a/packages/contentstack-import/src/import/module-importer.ts b/packages/contentstack-import/src/import/module-importer.ts index 6e9243fa2..2a6879c09 100755 --- a/packages/contentstack-import/src/import/module-importer.ts +++ b/packages/contentstack-import/src/import/module-importer.ts @@ -34,12 +34,6 @@ class ModuleImporter { const stackDetails: Record = await this.stackAPIClient.fetch(); this.importConfig.stackName = stackDetails.name as string; this.importConfig.org_uid = stackDetails.org_uid as string; - - const assetScanningEnabled = await this.detectAssetScanning(this.importConfig.org_uid); - if (assetScanningEnabled) { - this.importConfig.assetScanningEnabled = true; - this.importConfig.skipAssetsPublish = true; - } } await this.resolveImportPath(); @@ -215,16 +209,6 @@ class ModuleImporter { log.error(`Audit failed with following error. ${error}`, this.importConfig.context); } } - - private async detectAssetScanning(orgUid: string): Promise { - try { - const orgDetails = await this.managementAPIClient.organization(orgUid).fetch({ include_plan: true }); - const features: Array<{ uid: string; enabled?: boolean }> = orgDetails?.plan?.features || []; - return features.some((f) => (f.uid === 'assetsScan' || f.uid === 'amAssetsScan') && f.enabled === true); - } catch { - return false; - } - } } export default ModuleImporter; diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index 4d23c0524..7e4a13111 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -53,11 +53,15 @@ export default class ImportAssets extends BaseClass { */ async start(): Promise { try { - // NOTE Step 1: Import folders and create uid mapping file + if (this.importConfig.assetScanningEnabled) { + log.info('Assets Scanning is enabled in this stack', this.importConfig.context); + log.warn('Assets publishing will be skipped', this.importConfig.context); + } + // NOTE Step 1: Import folders and create uid mapping file log.debug('Starting folder import process...', this.importConfig.context); await this.importFolders(); - // NOTE Step 2: Import versioned assets and create it mapping files (uid, url) + // NOTE Step 2: Import versioned assets and create it mapping files (uid, url) if (this.assetConfig.includeVersionedAssets) { const versionsPath = `${this.assetsPath}/versions`; if (existsSync(versionsPath)) { @@ -68,11 +72,11 @@ export default class ImportAssets extends BaseClass { } } - // NOTE Step 3: Import Assets and create it mapping files (uid, url) + // NOTE Step 3: Import Assets and create it mapping files (uid, url) log.debug('Starting assets import...', this.importConfig.context); await this.importAssets(); - // NOTE Step 4: Publish assets + // NOTE Step 4: Publish assets if (!this.importConfig.skipAssetsPublish) { log.debug('Starting assets publishing...', this.importConfig.context); await this.publish(); diff --git a/packages/contentstack-import/src/types/import-config.ts b/packages/contentstack-import/src/types/import-config.ts index 70ca10a27..80805ae2c 100644 --- a/packages/contentstack-import/src/types/import-config.ts +++ b/packages/contentstack-import/src/types/import-config.ts @@ -1,3 +1,4 @@ +import { FeatureStatus } from '@contentstack/cli-utilities'; import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; @@ -60,6 +61,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig { personalizeProjectName?: string; 'exclude-global-modules': false; context: Context; + planStatus?: Record; } type branch = { diff --git a/packages/contentstack-import/src/utils/import-config-handler.ts b/packages/contentstack-import/src/utils/import-config-handler.ts index 9df8a1bbd..e25a93034 100644 --- a/packages/contentstack-import/src/utils/import-config-handler.ts +++ b/packages/contentstack-import/src/utils/import-config-handler.ts @@ -7,6 +7,8 @@ import { cliux, sanitizePath, log, + isFeatureEnabled, + FeatureCtx, } from '@contentstack/cli-utilities'; import defaultConfig from '../config'; import { readFile, fileExistsSync } from './file-helper'; @@ -14,7 +16,7 @@ import { askContentDir, askAPIKey } from './interactive'; import login from './login-handler'; import { ImportConfig } from '../types'; -const setupConfig = async (importCmdFlags: any): Promise => { +const setupConfig = async (importCmdFlags: any, context?: any): Promise => { let config: ImportConfig = merge({}, defaultConfig); // Track authentication method let authenticationMethod = 'unknown'; @@ -139,6 +141,33 @@ const setupConfig = async (importCmdFlags: any): Promise => { config.authenticationMethod = authenticationMethod; log.debug('Import configuration setup completed.', { ...config }); + // Deferred plan check — credentials now available after setupImportConfig + const deferredFeatures: string[] = context?.planCheckRequired ?? []; + if (deferredFeatures.length > 0) { + const planCtx: FeatureCtx = { + apiKey: config.apiKey, + managementToken: config.management_token, + authToken: config.auth_token, + }; + for (const featureUid of deferredFeatures) { + try { + const status = await isFeatureEnabled(featureUid, planCtx); + if (context) context.planStatus[featureUid] = status; + log.debug(`[import] Deferred plan status fetched for "${featureUid}".`); + } catch (error) { + log.warn(`[import] Could not fetch deferred plan status for "${featureUid}": ${(error as Error).message}`); + } + } + } + + if (context?.planStatus) { + config.planStatus = context.planStatus; + if (config.planStatus['assetsScan']?.is_part_of_plan) { + config.assetScanningEnabled = true; + config.skipAssetsPublish = true; + } + } + return config; }; From f537d43fc944abf661733d273514af47d461a1f1 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Fri, 24 Jul 2026 17:22:53 +0530 Subject: [PATCH 30/44] fix(import): preserve env-locale pairing for asset publish (DX-9772) publish() flattened each asset's publish_details into independent environments[] and locales[] arrays, so the CMA republished the cartesian product. For a ragged publish state (different locales on different environments) this over-published to env-locale pairs that never existed on the source stack. Add buildPublishGroups: group publish_details by environment, coalesce environments with an identical locale set, and emit one publish call per group so each call is a single rectangle the CMA reproduces exactly. A rectangular asset still collapses to one call (unchanged behavior). The DX-1656 invalid-environment guard is preserved (envs absent from the destination are still skipped). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/import/modules/assets.ts | 88 ++++++---- .../test/unit/import/modules/assets.test.ts | 162 +++++++++++------- 2 files changed, 158 insertions(+), 92 deletions(-) diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index e8b792f0b..38481d5eb 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -4,7 +4,6 @@ import filter from 'lodash/filter'; import unionBy from 'lodash/unionBy'; import orderBy from 'lodash/orderBy'; import isEmpty from 'lodash/isEmpty'; -import uniq from 'lodash/uniq'; import { existsSync } from 'node:fs'; import includes from 'lodash/includes'; import { resolve as pResolve, join } from 'node:path'; @@ -301,6 +300,47 @@ export default class ImportAssets extends BaseClass { return apiOptions; } + /** + * Groups already-filtered `publish_details` into publish payloads that preserve the source + * env↔locale pairing. Entries are grouped by environment, then environments sharing an + * identical locale set are coalesced into one payload. Each returned group is a rectangle + * (its environments × its locales), so the CMA env×locale cross-product reproduces exactly + * the source pairs — never a phantom combination (the DX-9772 over-publish). + * + * A fully-rectangular input (every env published to the same locales) collapses to a single + * group, so behavior is unchanged for the common case; a ragged input fans out into one group + * per distinct locale set. Only environments present in `this.environments` are kept, so the + * env-name lookup is always safe — this preserves the DX-1656 invalid-environment guard. + */ + private buildPublishGroups( + publishDetails: Record[], + ): { environments: string[]; locales: string[] }[] { + const localesByEnv = new Map>(); + for (const { environment, locale } of publishDetails || []) { + if (!locale || !this.environments?.hasOwnProperty(environment)) continue; + let set = localesByEnv.get(environment); + if (!set) { + set = new Set(); + localesByEnv.set(environment, set); + } + set.add(locale); + } + + // Coalesce environments with an identical locale set into a single payload. + const groups = new Map(); + for (const [envUid, localeSet] of localesByEnv) { + const locales = [...localeSet].sort(); + const signature = locales.join(' '); + const existing = groups.get(signature); + if (existing) { + existing.environments.push(this.environments[envUid].name); + } else { + groups.set(signature, { environments: [this.environments[envUid].name], locales }); + } + } + return [...groups.values()]; + } + /** * @method publish * @returns {Promise} Promise @@ -325,49 +365,31 @@ export default class ImportAssets extends BaseClass { handleAndLogError(error, { ...this.importConfig.context, uid, title }); }; + // apiData is a pre-expanded sub-item ({ uid, title, publishDetails }); one per env-locale-set + // group (see below). Pairing is already preserved, so this only resolves the destination UID. const serializeData = (apiOptions: ApiOptions) => { - const { apiData: asset } = apiOptions; - const publishDetails = filter(asset.publish_details, ({ environment }) => { - return this.environments?.hasOwnProperty(environment); - }); - - if (publishDetails.length) { - const environments = uniq(map(publishDetails, ({ environment }) => this.environments[environment].name)); - const locales = uniq(map(publishDetails, 'locale')); - - if (environments.length === 0 || locales.length === 0) { - log.debug( - `Skipping publish for asset ${asset.uid}: no valid environments/locales`, - this.importConfig.context, - ); - apiOptions.entity = undefined; - return apiOptions; - } - - asset.locales = locales; - asset.environments = environments; - apiOptions.apiData.publishDetails = { locales, environments }; - log.debug(`Prepared publish details for asset ${asset.uid}`, this.importConfig.context); - } - - apiOptions.uid = this.assetsUidMap[asset.uid] as string; - + const { apiData } = apiOptions; + apiOptions.uid = this.assetsUidMap[apiData.uid] as string; if (!apiOptions.uid) { - log.debug(`Skipping publish for asset ${asset.uid}: no UID mapping found.`, this.importConfig.context); + log.debug(`Skipping publish for asset ${apiData.uid}: no UID mapping found.`, this.importConfig.context); apiOptions.entity = undefined; } - return apiOptions; }; for (const index in indexer) { log.debug(`Processing publish chunk ${index} of ${indexerCount}`, this.importConfig.context); - const apiContent = filter( - values(await fs.readChunkFiles.next()), - ({ publish_details }) => !isEmpty(publish_details), + // Expand each asset into one sub-item per env-locale-set group, so each makeConcurrentCall + // item is a single-rectangle publish (preserves env↔locale pairing). + const apiContent = values(await fs.readChunkFiles.next()).flatMap((asset: Record) => + this.buildPublishGroups(asset.publish_details).map((publishDetails) => ({ + uid: asset.uid, + title: asset.title, + publishDetails, + })), ); - log.debug(`Found ${apiContent.length} publishable assets in chunk`, this.importConfig.context); + log.debug(`Found ${apiContent.length} asset publish calls in chunk`, this.importConfig.context); await this.makeConcurrentCall({ apiContent, diff --git a/packages/contentstack-import/test/unit/import/modules/assets.test.ts b/packages/contentstack-import/test/unit/import/modules/assets.test.ts index 9cb43df50..c171af5b3 100644 --- a/packages/contentstack-import/test/unit/import/modules/assets.test.ts +++ b/packages/contentstack-import/test/unit/import/modules/assets.test.ts @@ -651,101 +651,145 @@ describe('ImportAssets', () => { expect(makeConcurrentCallStub.called).to.be.true; }); - it('should filter publish_details by valid environments', async () => { - importAssets['environments'] = { 'env-1': { name: 'production' } }; + it('should skip publish when no UID mapping found', async () => { + importAssets['assetsUidMap'] = {}; makeConcurrentCallStub.callsFake(async (options: any) => { const serializeData = options.apiParams.serializeData; + // apiData is now a pre-grouped sub-item. const result = serializeData({ apiData: { - uid: 'asset-1', - publish_details: [ - { environment: 'env-1', locale: 'en-us' }, - { environment: 'env-invalid', locale: 'en-us' } - ] + uid: 'asset-unknown', + publishDetails: { environments: ['production'], locales: ['en-us'] } } }); - - expect(result.apiData.environments).to.deep.equal(['production']); - expect(result.apiData.locales).to.deep.equal(['en-us']); + + expect(result.entity).to.be.undefined; }); await (importAssets as any).publish(); }); - it('should skip publish when no valid environments', async () => { + it('should set correct UID from mapping and preserve the grouped payload', async () => { + importAssets['assetsUidMap'] = { 'asset-1': 'mapped-asset-1' }; + makeConcurrentCallStub.callsFake(async (options: any) => { const serializeData = options.apiParams.serializeData; const result = serializeData({ apiData: { uid: 'asset-1', - publish_details: [ - { environment: 'env-invalid', locale: 'en-us' } - ] + publishDetails: { environments: ['production'], locales: ['en-us'] } } }); - - expect(result.entity).to.be.undefined; + + expect(result.uid).to.equal('mapped-asset-1'); + // serializeData no longer flattens — it leaves the pre-grouped payload untouched. + expect(result.apiData.publishDetails).to.deep.equal({ environments: ['production'], locales: ['en-us'] }); }); await (importAssets as any).publish(); }); - it('should skip publish when no UID mapping found', async () => { - importAssets['assetsUidMap'] = {}; + it('preserves env-locale pairing for a RAGGED asset (DX-9772) — no phantom pairs', async () => { + // production published only in en-us; preview published only in fr-fr. + importAssets['assetsUidMap'] = { 'asset-1': 'new-asset-1' }; + importAssets['environments'] = { 'env-1': { name: 'production' }, 'env-2': { name: 'preview' } }; + Object.defineProperty(FsUtility.prototype, 'readChunkFiles', { + get: sinon.stub().returns({ + next: sinon.stub().resolves([ + { + uid: 'asset-1', + title: 'ragged.jpg', + publish_details: [ + { environment: 'env-1', locale: 'en-us' }, + { environment: 'env-2', locale: 'fr-fr' } + ] + } + ]) + }), + configurable: true + }); + let apiContent: any[] = []; makeConcurrentCallStub.callsFake(async (options: any) => { - const serializeData = options.apiParams.serializeData; - const result = serializeData({ - apiData: { - uid: 'asset-unknown', - publish_details: [{ environment: 'env-1', locale: 'en-us' }] - } - }); - - expect(result.entity).to.be.undefined; + apiContent = options.apiContent; }); await (importAssets as any).publish(); + + // Two separate publish calls, each a single-rectangle payload — never a cartesian. + expect(apiContent).to.have.lengthOf(2); + const payloads = apiContent.map((i) => i.publishDetails); + expect(payloads).to.deep.include.members([ + { environments: ['production'], locales: ['en-us'] }, + { environments: ['preview'], locales: ['fr-fr'] } + ]); + for (const p of payloads) { + const hasPhantom = + (p.environments.includes('production') && p.locales.includes('fr-fr')) || + (p.environments.includes('preview') && p.locales.includes('en-us')); + expect(hasPhantom, `phantom pair in ${JSON.stringify(p)}`).to.be.false; + } }); + }); - it('should set correct UID from mapping', async () => { - importAssets['assetsUidMap'] = { 'asset-1': 'mapped-asset-1' }; + describe('buildPublishGroups() method', () => { + it('collapses a RECTANGULAR asset to a single publish call (behavior-preserving)', () => { + importAssets['environments'] = { + 'e1': { name: 'production' }, + 'e2': { name: 'preview' }, + 'e3': { name: 'development' } + }; + const pd = ['e1', 'e2', 'e3'].flatMap((environment) => [ + { environment, locale: 'en-us' }, + { environment, locale: 'fr-fr' } + ]); - makeConcurrentCallStub.callsFake(async (options: any) => { - const serializeData = options.apiParams.serializeData; - const result = serializeData({ - apiData: { - uid: 'asset-1', - publish_details: [{ environment: 'env-1', locale: 'en-us' }] - } - }); - - expect(result.uid).to.equal('mapped-asset-1'); - }); + const groups = (importAssets as any).buildPublishGroups(pd); - await (importAssets as any).publish(); + expect(groups).to.have.lengthOf(1); + expect(groups[0].locales).to.deep.equal(['en-us', 'fr-fr']); + expect(groups[0].environments).to.have.members(['production', 'preview', 'development']); }); - it('should extract unique locales from publish_details', async () => { - makeConcurrentCallStub.callsFake(async (options: any) => { - const serializeData = options.apiParams.serializeData; - const result = serializeData({ - apiData: { - uid: 'asset-1', - publish_details: [ - { environment: 'env-1', locale: 'en-us' }, - { environment: 'env-1', locale: 'en-us' }, - { environment: 'env-1', locale: 'fr-fr' } - ] - } - }); - - expect(result.apiData.locales).to.have.lengthOf(2); - expect(result.apiData.locales).to.include.members(['en-us', 'fr-fr']); - }); + it('fans a RAGGED asset out into one group per distinct locale set (DX-9772)', () => { + importAssets['environments'] = { 'e1': { name: 'new' }, 'e2': { name: 'blt5795' } }; + const pd = [ + { environment: 'e2', locale: 'en-us' }, + { environment: 'e1', locale: 'en-us' }, + { environment: 'e1', locale: 'ar' } + ]; - await (importAssets as any).publish(); + const groups = (importAssets as any).buildPublishGroups(pd); + + expect(groups).to.have.lengthOf(2); + expect(groups).to.deep.include.members([ + { environments: ['new'], locales: ['ar', 'en-us'] }, + { environments: ['blt5795'], locales: ['en-us'] } + ]); + const blt5795 = groups.find((g: any) => g.environments.includes('blt5795')); + expect(blt5795.locales).to.not.include('ar'); + }); + + it('handles a single env-locale pair (1×1) as one group', () => { + importAssets['environments'] = { 'e1': { name: 'production' } }; + const groups = (importAssets as any).buildPublishGroups([{ environment: 'e1', locale: 'en-us' }]); + expect(groups).to.deep.equal([{ environments: ['production'], locales: ['en-us'] }]); + }); + + it('drops environments absent from the destination (preserves DX-1656 guard)', () => { + importAssets['environments'] = { 'e1': { name: 'production' } }; + const groups = (importAssets as any).buildPublishGroups([ + { environment: 'e1', locale: 'en-us' }, + { environment: 'gone', locale: 'en-us' } + ]); + expect(groups).to.deep.equal([{ environments: ['production'], locales: ['en-us'] }]); + }); + + it('returns [] for empty publish_details', () => { + importAssets['environments'] = { 'e1': { name: 'production' } }; + expect((importAssets as any).buildPublishGroups([])).to.deep.equal([]); + expect((importAssets as any).buildPublishGroups(undefined)).to.deep.equal([]); }); }); From 78da02ea3f9ff018ff92ee4a047a697678b0f015 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 28 Jul 2026 14:38:30 +0530 Subject: [PATCH 31/44] bumped dependencies version --- packages/contentstack-apps-cli/package.json | 4 ++-- packages/contentstack-audit/package.json | 4 ++-- packages/contentstack-bootstrap/package.json | 8 ++++---- packages/contentstack-branches/package.json | 4 ++-- packages/contentstack-bulk-operations/package.json | 4 ++-- packages/contentstack-bulk-publish/package.json | 6 +++--- packages/contentstack-cli-cm-regex-validate/package.json | 4 ++-- packages/contentstack-cli-tsgen/package.json | 4 ++-- packages/contentstack-clone/package.json | 4 ++-- packages/contentstack-content-type/package.json | 4 ++-- packages/contentstack-export-to-csv/package.json | 4 ++-- packages/contentstack-export/package.json | 8 ++++---- packages/contentstack-external-migrate/package.json | 4 ++-- packages/contentstack-import-setup/package.json | 4 ++-- packages/contentstack-import/package.json | 4 ++-- packages/contentstack-migrate-rte/package.json | 4 ++-- packages/contentstack-migration/package.json | 4 ++-- packages/contentstack-query-export/package.json | 4 ++-- packages/contentstack-seed/package.json | 4 ++-- packages/contentstack-variants/package.json | 2 +- 20 files changed, 44 insertions(+), 44 deletions(-) diff --git a/packages/contentstack-apps-cli/package.json b/packages/contentstack-apps-cli/package.json index cc5250fdf..f40f9a161 100644 --- a/packages/contentstack-apps-cli/package.json +++ b/packages/contentstack-apps-cli/package.json @@ -22,9 +22,9 @@ ], "dependencies": { "@apollo/client": "^3.14.1", - "@contentstack/cli-command": "~1.8.4", + "@contentstack/cli-command": "~1.8.5", "@contentstack/cli-launch": "^1.11.1", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-utilities": "~1.19.0", "adm-zip": "^0.5.17", "chalk": "^4.1.2", "lodash": "^4.18.1", diff --git a/packages/contentstack-audit/package.json b/packages/contentstack-audit/package.json index 92ff766e9..436784c44 100644 --- a/packages/contentstack-audit/package.json +++ b/packages/contentstack-audit/package.json @@ -18,8 +18,8 @@ "/oclif.manifest.json" ], "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "fast-csv": "^4.3.6", diff --git a/packages/contentstack-bootstrap/package.json b/packages/contentstack-bootstrap/package.json index 56fcd395e..7399f7157 100644 --- a/packages/contentstack-bootstrap/package.json +++ b/packages/contentstack-bootstrap/package.json @@ -17,10 +17,10 @@ "lint": "eslint \"src/**/*.ts\"" }, "dependencies": { - "@contentstack/cli-cm-seed": "~1.15.7", - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-config": "~1.20.5", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-cm-seed": "~1.15.8", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-config": "~1.21.0", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "inquirer": "8.2.7", "mkdirp": "^2.1.6", diff --git a/packages/contentstack-branches/package.json b/packages/contentstack-branches/package.json index 73543a1fc..87fbbf48b 100644 --- a/packages/contentstack-branches/package.json +++ b/packages/contentstack-branches/package.json @@ -5,8 +5,8 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "just-diff": "^6.0.2", diff --git a/packages/contentstack-bulk-operations/package.json b/packages/contentstack-bulk-operations/package.json index bc8dd1913..26b7d1394 100644 --- a/packages/contentstack-bulk-operations/package.json +++ b/packages/contentstack-bulk-operations/package.json @@ -20,8 +20,8 @@ "/oclif.manifest.json" ], "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@contentstack/delivery-sdk": "^5.4.0", "@contentstack/management": "^1.30.3", "lodash": "^4.18.1", diff --git a/packages/contentstack-bulk-publish/package.json b/packages/contentstack-bulk-publish/package.json index 8c656e3d6..4ac614168 100644 --- a/packages/contentstack-bulk-publish/package.json +++ b/packages/contentstack-bulk-publish/package.json @@ -5,9 +5,9 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-config": "~1.20.5", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-config": "~1.21.0", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "dotenv": "^16.6.1", diff --git a/packages/contentstack-cli-cm-regex-validate/package.json b/packages/contentstack-cli-cm-regex-validate/package.json index c279e4490..261450b68 100644 --- a/packages/contentstack-cli-cm-regex-validate/package.json +++ b/packages/contentstack-cli-cm-regex-validate/package.json @@ -65,8 +65,8 @@ "lint": "eslint \"src/**/*.ts\"" }, "dependencies": { - "@contentstack/cli-command": "^1.8.4", - "@contentstack/cli-utilities": "^1.18.5", + "@contentstack/cli-command": "^1.8.5", + "@contentstack/cli-utilities": "^1.19.0", "@contentstack/management": "^1.30.4", "cli-table3": "^0.6.5", "cli-ux": "^6.0.9", diff --git a/packages/contentstack-cli-tsgen/package.json b/packages/contentstack-cli-tsgen/package.json index dba64ae3c..151896e73 100644 --- a/packages/contentstack-cli-tsgen/package.json +++ b/packages/contentstack-cli-tsgen/package.json @@ -5,8 +5,8 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli-plugins/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@contentstack/types-generator": "^3.10.2" }, "devDependencies": { diff --git a/packages/contentstack-clone/package.json b/packages/contentstack-clone/package.json index 26ab0997e..8378bba79 100644 --- a/packages/contentstack-clone/package.json +++ b/packages/contentstack-clone/package.json @@ -8,8 +8,8 @@ "@colors/colors": "^1.6.0", "@contentstack/cli-cm-export": "~1.25.3", "@contentstack/cli-cm-import": "~1.33.5", - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "inquirer": "8.2.7", diff --git a/packages/contentstack-content-type/package.json b/packages/contentstack-content-type/package.json index dc29f6898..915991880 100644 --- a/packages/contentstack-content-type/package.json +++ b/packages/contentstack-content-type/package.json @@ -5,8 +5,8 @@ "author": "Contentstack Developer", "bugs": "https://github.com/contentstack/cli-plugins/issues", "dependencies": { - "@contentstack/cli-command": "^1.8.4", - "@contentstack/cli-utilities": "^1.18.5", + "@contentstack/cli-command": "^1.8.5", + "@contentstack/cli-utilities": "^1.19.0", "@types/diff2html": "^3.0.3", "@types/git-diff": "^2.0.7", "@types/hogan.js": "^3.0.5", diff --git a/packages/contentstack-export-to-csv/package.json b/packages/contentstack-export-to-csv/package.json index 375606421..a24caf394 100644 --- a/packages/contentstack-export-to-csv/package.json +++ b/packages/contentstack-export-to-csv/package.json @@ -5,8 +5,8 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "fast-csv": "^4.3.6", "inquirer": "8.2.7", diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index def2158fb..36a085043 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -5,8 +5,8 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@contentstack/cli-variants": "~1.6.0", "@oclif/core": "^4.11.4", "async": "^3.2.6", @@ -21,8 +21,8 @@ "winston": "^3.19.0" }, "devDependencies": { - "@contentstack/cli-auth": "~1.8.4", - "@contentstack/cli-config": "~1.20.5", + "@contentstack/cli-auth": "~1.8.5", + "@contentstack/cli-config": "~1.21.0", "@contentstack/cli-dev-dependencies": "^1.3.1", "@oclif/plugin-help": "^6.2.28", "@oclif/test": "^4.1.18", diff --git a/packages/contentstack-external-migrate/package.json b/packages/contentstack-external-migrate/package.json index cb2524533..1f0ee2df8 100644 --- a/packages/contentstack-external-migrate/package.json +++ b/packages/contentstack-external-migrate/package.json @@ -22,8 +22,8 @@ "version": "oclif readme && git add README.md" }, "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@contentstack/json-rte-serializer": "~2.1.0", "@contentstack/marketplace-sdk": "~1.5.3", "@oclif/core": "^4.8.0", diff --git a/packages/contentstack-import-setup/package.json b/packages/contentstack-import-setup/package.json index d139eb746..f3b384d45 100644 --- a/packages/contentstack-import-setup/package.json +++ b/packages/contentstack-import-setup/package.json @@ -5,8 +5,8 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "big-json": "^3.2.0", "chalk": "^4.1.2", diff --git a/packages/contentstack-import/package.json b/packages/contentstack-import/package.json index 9b72827aa..86a20562e 100644 --- a/packages/contentstack-import/package.json +++ b/packages/contentstack-import/package.json @@ -6,8 +6,8 @@ "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-audit": "~1.19.5", - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@contentstack/cli-variants": "~1.6.0", "@oclif/core": "^4.11.4", "big-json": "^3.2.0", diff --git a/packages/contentstack-migrate-rte/package.json b/packages/contentstack-migrate-rte/package.json index 1f791ad06..7d47817d5 100644 --- a/packages/contentstack-migrate-rte/package.json +++ b/packages/contentstack-migrate-rte/package.json @@ -7,8 +7,8 @@ "url": "https://github.com/contentstack/cli-plugins/issues" }, "dependencies": { - "@contentstack/cli-command": "1.8.4", - "@contentstack/cli-utilities": "1.18.5", + "@contentstack/cli-command": "1.8.5", + "@contentstack/cli-utilities": "1.19.0", "@contentstack/json-rte-serializer": "~2.1.0", "@oclif/core": "^4.12.0", "@oclif/plugin-help": "^6.2.53", diff --git a/packages/contentstack-migration/package.json b/packages/contentstack-migration/package.json index 2c19df8fa..53a60b368 100644 --- a/packages/contentstack-migration/package.json +++ b/packages/contentstack-migration/package.json @@ -4,8 +4,8 @@ "author": "@contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "async": "^3.2.6", "callsites": "^3.1.0", diff --git a/packages/contentstack-query-export/package.json b/packages/contentstack-query-export/package.json index b2191d177..e715d3c81 100644 --- a/packages/contentstack-query-export/package.json +++ b/packages/contentstack-query-export/package.json @@ -6,8 +6,8 @@ "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-cm-export": "~1.25.3", - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "@contentstack/cli-variants": "~1.6.0", "@oclif/core": "^4.11.4", "async": "^3.2.6", diff --git a/packages/contentstack-seed/package.json b/packages/contentstack-seed/package.json index 680e85e43..5327ac556 100644 --- a/packages/contentstack-seed/package.json +++ b/packages/contentstack-seed/package.json @@ -6,8 +6,8 @@ "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-cm-import": "~1.33.5", - "@contentstack/cli-command": "~1.8.4", - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-command": "~1.8.5", + "@contentstack/cli-utilities": "~1.19.0", "inquirer": "8.2.7", "mkdirp": "^1.0.4", "tar": "^7.5.19", diff --git a/packages/contentstack-variants/package.json b/packages/contentstack-variants/package.json index 6a32cb7e7..eb7ab7bc2 100644 --- a/packages/contentstack-variants/package.json +++ b/packages/contentstack-variants/package.json @@ -28,7 +28,7 @@ "typescript": "^5.8.3" }, "dependencies": { - "@contentstack/cli-utilities": "~1.18.5", + "@contentstack/cli-utilities": "~1.19.0", "@oclif/core": "^4.11.4", "lodash": "^4.18.1", "mkdirp": "^1.0.4", From 13b19557ab03e3c23b7330e9417d1b432c1ae6e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 10:23:51 +0000 Subject: [PATCH 32/44] chore(deps): bump adm-zip from 0.5.18 to 0.6.0 Bumps [adm-zip](https://github.com/cthackers/adm-zip) from 0.5.18 to 0.6.0. - [Release notes](https://github.com/cthackers/adm-zip/releases) - [Changelog](https://github.com/cthackers/adm-zip/blob/master/history.md) - [Commits](https://github.com/cthackers/adm-zip/compare/v0.5.18...v0.6.0) --- updated-dependencies: - dependency-name: adm-zip dependency-version: 0.6.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- packages/contentstack-apps-cli/package.json | 2 +- pnpm-lock.yaml | 43 ++++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/contentstack-apps-cli/package.json b/packages/contentstack-apps-cli/package.json index 59b265e12..f2b149371 100644 --- a/packages/contentstack-apps-cli/package.json +++ b/packages/contentstack-apps-cli/package.json @@ -25,7 +25,7 @@ "@contentstack/cli-command": "~1.8.5", "@contentstack/cli-launch": "^1.11.1", "@contentstack/cli-utilities": "~1.19.0", - "adm-zip": "^0.5.17", + "adm-zip": "^0.6.0", "chalk": "^4.1.2", "lodash": "^4.18.1", "shelljs": "^0.10.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c641a7a66..1b94f2cdf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,8 +39,8 @@ importers: specifier: ~1.19.0 version: 1.19.0(@types/node@20.19.43) adm-zip: - specifier: ^0.5.17 - version: 0.5.18 + specifier: ^0.6.0 + version: 0.6.0 chalk: specifier: ^4.1.2 version: 4.1.2 @@ -3063,36 +3063,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.1.5': resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.1.5': resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.1.5': resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.1.5': resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.1.5': resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.1.5': resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} @@ -3203,66 +3209,79 @@ packages: resolution: {integrity: sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.62.3': resolution: {integrity: sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.62.3': resolution: {integrity: sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.62.3': resolution: {integrity: sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.62.3': resolution: {integrity: sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.62.3': resolution: {integrity: sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.62.3': resolution: {integrity: sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.62.3': resolution: {integrity: sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.62.3': resolution: {integrity: sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.62.3': resolution: {integrity: sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.62.3': resolution: {integrity: sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.62.3': resolution: {integrity: sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.62.3': resolution: {integrity: sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.62.3': resolution: {integrity: sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==} @@ -3879,51 +3898,61 @@ packages: resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.12.2': resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} cpu: [loong64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-loong64-musl@1.12.2': resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} cpu: [loong64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.12.2': resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.12.2': resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-openharmony-arm64@1.12.2': resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} @@ -4027,6 +4056,10 @@ packages: resolution: {integrity: sha512-ufJnssQGbxzLNS1Ho9bCtX4rQKCCvoVuDLHoJyc3F9dOGDB4BkWs2Ci0kv53lqocAEQ/Cbi+I2XCsNYGqVYqng==} engines: {node: '>=12.0'} + adm-zip@0.6.0: + resolution: {integrity: sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==} + engines: {node: '>=14.0'} + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -6843,24 +6876,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.33.0: resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.33.0: resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.33.0: resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.33.0: resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} @@ -13430,6 +13467,8 @@ snapshots: adm-zip@0.5.18: {} + adm-zip@0.6.0: {} + agent-base@6.0.2: dependencies: debug: 4.4.3(supports-color@8.1.1) From 19c2a36b1e3cf3234082538bf2b123900436f132 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 30 Jul 2026 12:25:07 +0530 Subject: [PATCH 33/44] handled assets in pending or quarantine states export failure --- .../contentstack-export/messages/index.json | 2 + .../src/export/modules/assets.ts | 28 +++++++++- .../src/export/modules/base-class.ts | 56 +++++++++++++++---- .../test/unit/export/modules/assets.test.ts | 27 +++++++++ 4 files changed, 101 insertions(+), 12 deletions(-) diff --git a/packages/contentstack-export/messages/index.json b/packages/contentstack-export/messages/index.json index 21a72c884..73925c5fd 100644 --- a/packages/contentstack-export/messages/index.json +++ b/packages/contentstack-export/messages/index.json @@ -10,6 +10,8 @@ "ASSET_QUERY_FAILED": "Failed to query asset data from the API", "ASSET_VERSIONED_QUERY_FAILED": "Failed to query versioned asset data from the API", "ASSET_COUNT_QUERY_FAILED": "Failed to retrieve total asset count", + "ASSET_SCAN_SKIPPED": "Skipping download of asset '%s' (UID: %s) — scan status: %s", + "ASSET_SCAN_SKIP_SUMMARY": "%s asset(s) skipped due to a non-clean scan status (pending/quarantined). Re-run the export once scanning completes to download them.", "CONTENT_TYPE_EXPORT_COMPLETE": "Content types exported successfully", "CONTENT_TYPE_NO_TYPES": "No content types found", diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 1a95d5f25..eb0b23a02 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -135,6 +135,7 @@ export default class ExportAssets extends BaseClass { const queryParam = { ...this.commonQueryParam, include_publish_details: true, + include_asset_scan_status: true, except: { BASE: this.assetConfig.invalidKeys }, }; this.applyQueryFilters(queryParam, 'assets'); @@ -168,7 +169,10 @@ export default class ExportAssets extends BaseClass { indexFileName: 'assets.json', basePath: this.assetsRootPath, chunkFileSize: this.assetConfig.chunkFileSize, - metaPickKeys: merge(['uid', 'url', 'filename', 'parent_uid'], this.assetConfig.assetsMetaKeys), + metaPickKeys: merge( + ['uid', 'url', 'filename', 'parent_uid', '_asset_scan_status'], + this.assetConfig.assetsMetaKeys, + ), }); } if (!isEmpty(items)) { @@ -204,6 +208,7 @@ export default class ExportAssets extends BaseClass { const queryParam = { ...this.commonQueryParam, include_publish_details: true, + include_asset_scan_status: true, except: { BASE: this.assetConfig.invalidKeys }, }; @@ -243,7 +248,10 @@ export default class ExportAssets extends BaseClass { indexFileName: 'versioned-assets.json', chunkFileSize: this.assetConfig.chunkFileSize, basePath: pResolve(this.assetsRootPath, 'versions'), - metaPickKeys: merge(['uid', 'url', 'filename', '_version', 'parent_uid'], this.assetConfig.assetsMetaKeys), + metaPickKeys: merge( + ['uid', 'url', 'filename', '_version', 'parent_uid', '_asset_scan_status'], + this.assetConfig.assetsMetaKeys, + ), }); } if (!isEmpty(response)) { @@ -329,6 +337,19 @@ export default class ExportAssets extends BaseClass { listOfAssets = uniqBy(listOfAssets, 'url'); log.debug(`Total unique assets to download: ${listOfAssets.length}`, this.exportConfig.context); + const isNotClean = (asset: any) => asset._asset_scan_status && asset._asset_scan_status !== 'clean'; + const skippedAssets = filter(listOfAssets, isNotClean); + listOfAssets = filter(listOfAssets, (asset: any) => !isNotClean(asset)); + + if (!isEmpty(skippedAssets)) { + for (const asset of skippedAssets) { + log.warn( + messageHandler.parse('ASSET_SCAN_SKIPPED', asset.filename, asset.uid, asset._asset_scan_status), + this.exportConfig.context, + ); + } + } + const apiBatches: Array = chunk(listOfAssets, this.assetConfig.downloadLimit); const downloadedAssetsDirs = await getDirectories(pResolve(this.assetsRootPath, 'files')); @@ -413,6 +434,9 @@ export default class ExportAssets extends BaseClass { promisifyHandler, ).then(() => { log.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); + if (!isEmpty(skippedAssets)) { + log.warn(messageHandler.parse('ASSET_SCAN_SKIP_SUMMARY', skippedAssets.length), this.exportConfig.context); + } }); } } diff --git a/packages/contentstack-export/src/export/modules/base-class.ts b/packages/contentstack-export/src/export/modules/base-class.ts index 6379669e1..68fb1adb9 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -5,7 +5,7 @@ import chunk from 'lodash/chunk'; import isEmpty from 'lodash/isEmpty'; import entries from 'lodash/entries'; import isEqual from 'lodash/isEqual'; -import { log } from '@contentstack/cli-utilities'; +import { log, handleAndLogError } from '@contentstack/cli-utilities'; import { ExportConfig, ModuleClassParams } from '../../types'; @@ -115,7 +115,16 @@ export default abstract class BaseClass { } /* eslint-disable no-await-in-loop */ - await Promise.allSettled(allPromise); + const settledResults = await Promise.allSettled(allPromise); + settledResults.forEach((result) => { + if (result.status === 'rejected') { + handleAndLogError( + result.reason, + { ...this.exportConfig.context }, + `Unhandled rejection in '${module}' batch ${batchNo}`, + ); + } + }); /* eslint-disable no-await-in-loop */ await this.logMsgAndWaitIfRequired(module, start, batchNo); @@ -150,6 +159,30 @@ export default abstract class BaseClass { if (exeTime < 1000) await this.delay(1000 - exeTime); } + /** + * Wraps a caller-supplied resolve/reject callback so that if the callback itself throws + * (e.g. a bug while writing/logging the result), the failure is caught right here and + * always recorded via handleAndLogError, instead of turning into a rejected promise that + * a caller further up the chain may or may not notice. + */ + private guardCallback( + callback: (value: any) => void, + moduleName: ApiModuleType, + context: Record, + ): (value: any) => void { + return (value: any) => { + try { + callback(value); + } catch (error) { + handleAndLogError( + error, + { ...this.exportConfig.context, ...context }, + `Unhandled error while processing '${moduleName}' API result`, + ); + } + }; + } + /** * @method makeAPICall * @param {Record} options - Api related params @@ -160,32 +193,35 @@ export default abstract class BaseClass { { module: moduleName, reject, resolve, url = '', uid = '', additionalInfo, queryParam = {} }: ApiOptions, isLastRequest = false, ): Promise { + const safeResolve = this.guardCallback(resolve, moduleName, { uid, additionalInfo }); + const safeReject = this.guardCallback(reject, moduleName, { uid, additionalInfo }); + switch (moduleName) { case 'asset': return this.stack .asset(uid) .fetch(queryParam) - .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) - .catch((error: Error) => reject({ error, isLastRequest, additionalInfo })); + .then((response: any) => safeResolve({ response, isLastRequest, additionalInfo })) + .catch((error: Error) => safeReject({ error, isLastRequest, additionalInfo })); case 'assets': return this.stack .asset() .query(queryParam) .find() - .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) - .catch((error: Error) => reject({ error, isLastRequest, additionalInfo })); + .then((response: any) => safeResolve({ response, isLastRequest, additionalInfo })) + .catch((error: Error) => safeReject({ error, isLastRequest, additionalInfo })); case 'download-asset': return this.stack .asset() .download({ url, responseType: 'stream' }) - .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) - .catch((error: any) => reject({ error, isLastRequest, additionalInfo })); + .then((response: any) => safeResolve({ response, isLastRequest, additionalInfo })) + .catch((error: any) => safeReject({ error, isLastRequest, additionalInfo })); case 'export-taxonomy': return this.stack .taxonomy(uid) .export(queryParam) - .then((response: any) => resolve({ response, uid })) - .catch((error: any) => reject({ error, uid })); + .then((response: any) => safeResolve({ response, uid })) + .catch((error: any) => safeReject({ error, uid })); default: return Promise.resolve(); } diff --git a/packages/contentstack-export/test/unit/export/modules/assets.test.ts b/packages/contentstack-export/test/unit/export/modules/assets.test.ts index 5509682a4..e472ab13f 100644 --- a/packages/contentstack-export/test/unit/export/modules/assets.test.ts +++ b/packages/contentstack-export/test/unit/export/modules/assets.test.ts @@ -564,6 +564,33 @@ describe('ExportAssets', () => { expect(makeConcurrentCallStub.called).to.be.true; }); + + it('should skip assets with a non-clean scan status and download the rest', async () => { + getPlainMetaStub.returns({ + 'file-1': [ + { uid: 'clean-1', url: 'https://test.io/assets/clean-1.jpeg', filename: 'clean-1.jpeg', _asset_scan_status: 'clean' }, + { uid: 'pending-1', url: 'https://test.io/assets/pending-1.zip', filename: 'pending-1.zip', _asset_scan_status: 'pending' }, + { uid: 'quarantined-1', url: 'https://test.io/assets/quarantined-1.zip', filename: 'quarantined-1.zip', _asset_scan_status: 'quarantined' }, + ], + }); + + await exportAssets.downloadAssets(); + + expect(makeConcurrentCallStub.called).to.be.true; + // Only the 'clean' asset should be handed off for download; pending/quarantined are skipped. + expect(makeConcurrentCallStub.firstCall.args[0].totalCount).to.equal(1); + }); + + it('should download assets with no scan status field (stacks without asset scanning enabled)', async () => { + getPlainMetaStub.returns({ + 'file-1': [{ uid: 'legacy-1', url: 'https://test.io/assets/legacy-1.jpeg', filename: 'legacy-1.jpeg' }], + }); + + await exportAssets.downloadAssets(); + + // Missing _asset_scan_status must not be treated as non-clean, or every export would break. + expect(makeConcurrentCallStub.firstCall.args[0].totalCount).to.equal(1); + }); }); describe('Edge Cases', () => { From 601947fc8258e259ec400cb5b3ea212e9a0f6a39 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 30 Jul 2026 13:52:20 +0530 Subject: [PATCH 34/44] added audit check and fix for assets in pending or quarantined state --- .talismanrc | 6 + .../src/audit-base-command.ts | 41 ++- .../contentstack-audit/src/config/index.ts | 5 + .../contentstack-audit/src/messages/index.ts | 4 + .../contentstack-audit/src/modules/assets.ts | 30 ++- .../contentstack-audit/src/modules/entries.ts | 204 ++++++++++++++- .../src/types/content-types.ts | 2 + .../unit/mock/contents/assets/assets.json | 1 + .../mock/contents/assets/chunk1-assets.json | 33 +++ .../test/unit/modules/assets.test.ts | 74 ++++++ .../test/unit/modules/entries.test.ts | 235 ++++++++++++++++++ 11 files changed, 622 insertions(+), 13 deletions(-) create mode 100644 packages/contentstack-audit/test/unit/mock/contents/assets/assets.json create mode 100644 packages/contentstack-audit/test/unit/mock/contents/assets/chunk1-assets.json create mode 100644 packages/contentstack-audit/test/unit/modules/assets.test.ts diff --git a/.talismanrc b/.talismanrc index c61a19cba..ab42eb8cd 100644 --- a/.talismanrc +++ b/.talismanrc @@ -2,4 +2,10 @@ fileignoreconfig: - filename: pnpm-lock.yaml checksum: 31e333d6769adbaae042c92ea0930fab168a0e06fc1bda406d49fd1042a7a9c7 +- filename: packages/contentstack-audit/src/audit-base-command.ts + checksum: 14275f241e4a194cfd1fb33d277df194011eba4458ccaab7e0d0bd3a1c9ccfe7 +- filename: packages/contentstack-audit/src/modules/entries.ts + checksum: b0fa5f7b390ef2d64bd4834a5b848780b902373e2c644833842b42c6b767d54e +- filename: packages/contentstack-audit/test/unit/modules/entries.test.ts + checksum: ff448c79d436d5e8b141efcc76f19892bfe96039ea9a60fae4e995b5ccbc2960 version: '1.0' diff --git a/packages/contentstack-audit/src/audit-base-command.ts b/packages/contentstack-audit/src/audit-base-command.ts index b78650a31..d86efb057 100644 --- a/packages/contentstack-audit/src/audit-base-command.ts +++ b/packages/contentstack-audit/src/audit-base-command.ts @@ -94,6 +94,8 @@ export abstract class AuditBaseCommand extends BaseCommand; missingEnvLocale?: Record; missingMultipleFields?: Record; + missingAssetRefs?: Record; } = {}, missingMandatoryFields, missingTitleFields, @@ -215,6 +228,8 @@ export abstract class AuditBaseCommand extends BaseCommand, ): Promise { log.debug(`Preparing report for module: ${moduleName}`, this.auditContext); @@ -656,7 +682,8 @@ export abstract class AuditBaseCommand extends BaseCommand, ): Promise { if (Object.keys(config.moduleConfig).includes(moduleName) || config.feild_level_modules.includes(moduleName)) { diff --git a/packages/contentstack-audit/src/config/index.ts b/packages/contentstack-audit/src/config/index.ts index e291554fa..eb583c690 100644 --- a/packages/contentstack-audit/src/config/index.ts +++ b/packages/contentstack-audit/src/config/index.ts @@ -110,6 +110,8 @@ const config = { 'publish_locale', 'publish_environment', 'asset_uid', + 'scan_status', + 'mandatory', 'selectedValue', 'ct_uid', 'action', @@ -129,6 +131,7 @@ const config = { Entry_Missing_Locale_and_Env: 'Entry_Missing_Locale_and_Env', Entry_Missing_Locale_and_Env_in_Publish_Details: 'Entry_Missing_Locale_and_Env_in_Publish_Details', Entry_Multiple_Fields: 'Entry_Multiple_Fields', + Entries_Asset_field: 'Entries_Asset_field', }, feild_level_modules: [ 'Entries_Title_field', @@ -137,6 +140,8 @@ const config = { 'Entry_Missing_Locale_and_Env_in_Publish_Details', 'field-rules', 'Entry_Multiple_Fields', + 'Entries_Asset_field', + 'asset-scan-status', 'Summary', ], fixSelectField: false, diff --git a/packages/contentstack-audit/src/messages/index.ts b/packages/contentstack-audit/src/messages/index.ts index a2b654128..dac9136f9 100644 --- a/packages/contentstack-audit/src/messages/index.ts +++ b/packages/contentstack-audit/src/messages/index.ts @@ -49,6 +49,8 @@ const auditMsg = { FIELD_RULE_TARGET_ABSENT: `The target field '{target_field}' is not present in the schema of the content-type {ctUid}`, FIELD_RULE_CONDITION_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' condition of Content-type '{ctUid}'`, FIELD_RULE_TARGET_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' target of Content-type '{ctUid}'`, + SCAN_ASSET_QUARANTINE_MSG: `Asset with UID '{uid}' has a non-clean scan status ('{status}') and will be excluded from import.`, + ENTRY_ASSET_REF_WARN_MSG: `Entry '{uid}' field '{field}' references asset '{asset_uid}' with scan status '{status}'; it will be removed on fix.`, }; const auditFixMsg = { @@ -63,6 +65,8 @@ const auditFixMsg = { ENTRY_SELECT_FIELD_FIX: `Adding the value '{value}' in the select field of entry UID '{uid}'...`, ASSET_FIX: `Fixed publish detials for Asset with UID '{uid}'`, FIELD_RULE_FIX_MESSAGE: `Fixed Field Rule '{num}' target of Content-type '{ctUid}`, + ASSET_SCAN_STATUS_FIX: `Removed asset with UID '{uid}' (scan status: '{status}') from assets.json.`, + ENTRY_ASSET_REF_FIX: `Removed reference to asset '{asset_uid}' from entry '{uid}' field '{field}'.`, }; const messages: typeof errors & diff --git a/packages/contentstack-audit/src/modules/assets.ts b/packages/contentstack-audit/src/modules/assets.ts index af00aa5bb..14858cc4c 100644 --- a/packages/contentstack-audit/src/modules/assets.ts +++ b/packages/contentstack-audit/src/modules/assets.ts @@ -27,6 +27,7 @@ export default class Assets { public environments: string[] = []; protected schema: ContentTypeStruct[] = []; protected missingEnvLocales: Record = {}; + public missingScanStatusAssets: Record = {}; public moduleName: keyof typeof auditConfig.moduleConfig; constructor({ fix, config, moduleName }: ModuleConstructorParam & CtConstructorParam) { @@ -184,7 +185,24 @@ export default class Assets { for (const assetUid in assets) { log.debug(`Processing asset: ${assetUid}`, this.config.auditContext); - + + const scanStatus = this.assets[assetUid]?._asset_scan_status; + if (scanStatus && scanStatus !== 'clean') { + log.debug(`Asset ${assetUid} has a non-clean scan status: ${scanStatus}`, this.config.auditContext); + cliux.print($t(auditMsg.SCAN_ASSET_QUARANTINE_MSG, { uid: assetUid, status: scanStatus }), { + color: 'yellow', + }); + this.missingScanStatusAssets[assetUid] = [ + { asset_uid: assetUid, filename: this.assets[assetUid].filename, scan_status: scanStatus }, + ]; + + if (this.fix) { + log.info($t(auditFixMsg.ASSET_SCAN_STATUS_FIX, { uid: assetUid, status: scanStatus }), this.config.auditContext); + delete this.assets[assetUid]; + continue; + } + } + if (this.assets[assetUid]?.publish_details && !Array.isArray(this.assets[assetUid].publish_details)) { log.debug(`Asset ${assetUid} has invalid publish_details format`, this.config.auditContext); cliux.print($t(auditMsg.ASSET_NOT_EXIST, { uid: assetUid }), { color: 'red' }); @@ -226,15 +244,19 @@ export default class Assets { const remainingPublishDetails = this.assets[assetUid].publish_details?.length || 0; log.debug(`Asset ${assetUid} now has ${remainingPublishDetails} valid publish details`, this.config.auditContext); - + if (this.fix) { log.debug(`Fixing asset ${assetUid}`, this.config.auditContext); log.info($t(auditFixMsg.ASSET_FIX, { uid: assetUid }), this.config.auditContext); - await this.writeFixContent(`${basePath}/${indexer[fileIndex]}`, this.assets); } } + + if (this.fix) { + log.debug(`Writing fixed assets chunk to: ${basePath}/${indexer[fileIndex]}`, this.config.auditContext); + await this.writeFixContent(`${basePath}/${indexer[fileIndex]}`, this.assets); + } } - + log.debug(`Asset reference validation completed. Processed ${Object.keys(this.missingEnvLocales).length} assets with issues`, this.config.auditContext); } } diff --git a/packages/contentstack-audit/src/modules/entries.ts b/packages/contentstack-audit/src/modules/entries.ts index 02697d50b..e7a1257dd 100644 --- a/packages/contentstack-audit/src/modules/entries.ts +++ b/packages/contentstack-audit/src/modules/entries.ts @@ -58,8 +58,11 @@ export default class Entries { protected missingTitleFields: Record = {}; protected missingEnvLocale: Record = {}; protected missingMultipleField: Record = {}; + protected missingAssetRefs: Record = {}; public environments: string[] = []; public entryMetaData: Record[] = []; + public assetMetaData: Record = {}; + public assetsDataAvailable = false; public moduleName: keyof typeof auditConfig.moduleConfig = 'entries'; constructor({ fix, config, moduleName, ctSchema, gfSchema }: ModuleConstructorParam & CtConstructorParam) { @@ -154,6 +157,10 @@ export default class Entries { await this.prepareEntryMetaData(); log.debug(`Entry metadata prepared: ${this.entryMetaData.length} entries found`, this.config.auditContext); + log.debug('Preparing asset metadata', this.config.auditContext); + await this.prepareAssetMetaData(); + log.debug(`Asset metadata prepared: ${Object.keys(this.assetMetaData).length} assets found`, this.config.auditContext); + log.debug('Fixing prerequisite data', this.config.auditContext); await this.fixPrerequisiteData(); log.debug('Prerequisite data fix completed', this.config.auditContext); @@ -198,6 +205,10 @@ export default class Entries { if (!this.missingMandatoryFields[this.currentUid]) { this.missingMandatoryFields[this.currentUid] = []; } + + if (!this.missingAssetRefs[this.currentUid]) { + this.missingAssetRefs[this.currentUid] = []; + } if (this.fix) { log.debug(`Removing missing keys from entry ${uid}`, this.config.auditContext); this.removeMissingKeysOnEntry(ctSchema.schema as ContentTypeSchemaType[], this.entries[entryUid]); @@ -234,6 +245,14 @@ export default class Entries { }); } + if (this.missingAssetRefs[this.currentUid]?.length) { + log.debug(`Found ${this.missingAssetRefs[this.currentUid].length} missing/quarantined asset references for entry ${uid}`, this.config.auditContext); + this.missingAssetRefs[this.currentUid].forEach((entry: any) => { + entry.ct = ctSchema.uid; + entry.locale = code; + }); + } + const fields = this.missingMandatoryFields[uid]; const isPublished = entry.publish_details?.length > 0; log.debug(`Entry ${uid} published status: ${isPublished}, missing mandatory fields: ${fields?.length || 0}`, this.config.auditContext); @@ -343,6 +362,7 @@ export default class Entries { missingTitleFields: this.missingTitleFields, missingEnvLocale: this.missingEnvLocale, missingMultipleFields: this.missingMultipleField, + missingAssetRefs: this.missingAssetRefs, }; log.debug(`Entries audit completed. Found issues:`, this.config.auditContext); @@ -388,8 +408,17 @@ export default class Entries { removedMandatoryFields++; } } - - log.debug(`Cleanup completed: removed ${removedRefs} empty refs, ${removedSelectFields} empty select fields, ${removedMandatoryFields} empty mandatory fields`, this.config.auditContext); + + let removedAssetRefs = 0; + for (let propName in this.missingAssetRefs) { + if (!this.missingAssetRefs[propName].length) { + log.debug(`Removing empty missing asset references for entry: ${propName}`, this.config.auditContext); + delete this.missingAssetRefs[propName]; + removedAssetRefs++; + } + } + + log.debug(`Cleanup completed: removed ${removedRefs} empty refs, ${removedSelectFields} empty select fields, ${removedMandatoryFields} empty mandatory fields, ${removedAssetRefs} empty asset refs`, this.config.auditContext); } /** @@ -624,6 +653,16 @@ export default class Entries { entry[uid] as EntryGroupFieldDataType[], ); break; + case 'file': + log.debug(`Validating file/asset field: ${display_name}`, this.config.auditContext); + const assetRefResults = this.validateFileField( + [...tree, { uid: child.uid, name: child.display_name, field: uid }], + child, + entry[uid], + ); + this.missingAssetRefs[this.currentUid].push(...assetRefResults); + log.debug(`Found ${assetRefResults.length} quarantined/missing asset references in field: ${display_name}`, this.config.auditContext); + break; case 'text': case 'number': if (child.hasOwnProperty('display_type')) { @@ -888,6 +927,59 @@ export default class Entries { log.debug(`Group field validation completed for: ${fieldStructure.display_name}`); } + /** + * Returns true when the given asset uid should be treated as unusable — either it doesn't + * exist in the exported assets.json at all, or it exists but its scan status is present and + * not 'clean' (e.g. 'pending'/'quarantined'). Returns false (never flag) when asset metadata + * wasn't available at all, since we can't validate what we don't have data for. + */ + isAssetBad(uid?: string): boolean { + if (!this.assetsDataAvailable || !uid) return false; + const assetRecord = this.assetMetaData[uid]; + if (!assetRecord) return true; + const scanStatus = assetRecord._asset_scan_status; + return Boolean(scanStatus) && scanStatus !== 'clean'; + } + + /** + * The function `validateFileField` checks a `data_type: 'file'` (asset reference) field's + * value(s) against the asset metadata index and returns an issue when any referenced asset is + * missing or has a non-clean scan status. + */ + validateFileField( + tree: Record[], + fieldStructure: { uid: string; data_type: string; display_name: string; mandatory?: boolean }, + field: any, + ): EntryRefErrorReturnType[] { + log.debug(`Validating file/asset field: ${fieldStructure.display_name}`, this.config.auditContext); + + const values = Array.isArray(field) ? field : field ? [field] : []; + const missingRefs = values + .filter((ref: any) => this.isAssetBad(ref?.uid)) + .map((ref: any) => ({ asset_uid: ref?.uid, filename: ref?.filename })); + + if (isEmpty(missingRefs)) { + log.debug('File/asset field validation completed: no issues found', this.config.auditContext); + return []; + } + + return [ + { + tree, + missingRefs, + uid: this.currentUid, + name: this.currentTitle, + data_type: fieldStructure.data_type, + display_name: fieldStructure.display_name, + mandatory: fieldStructure.mandatory, + treeStr: tree + .map(({ name }) => name) + .filter((val) => val) + .join(' ➜ '), + } as unknown as EntryRefErrorReturnType, + ]; + } + /** * The function `validateReferenceValues` checks if the references in a given field exist in the * provided tree and returns any missing references. @@ -1125,6 +1217,14 @@ export default class Entries { entry[uid] as EntryGroupFieldDataType[], ) as EntryGroupFieldDataType; break; + case 'file': + log.debug(`Fixing file/asset field: ${uid}`); + this.fixFileFieldReferences( + [...tree, { uid: field.uid, name: field.display_name, data_type: field.data_type }], + field, + entry, + ); + break; case 'text': case 'number': if (field.hasOwnProperty('display_type')) { @@ -1574,6 +1674,65 @@ export default class Entries { return field; } + /** + * The function `fixFileFieldReferences` strips references to missing/quarantined/pending-scan + * assets from a `data_type: 'file'` field. A single-object value with a bad asset uid is deleted + * from the entry entirely; a `multiple: true` array value has its bad entries filtered out, and + * the key itself is deleted if the array becomes empty as a result. + */ + fixFileFieldReferences( + tree: Record[], + field: { uid: string; data_type: string; display_name: string; mandatory?: boolean }, + entry: Record, + ) { + log.debug(`Fixing file/asset field: ${field.display_name}`); + const { uid, display_name, data_type, mandatory } = field; + const value = entry[uid]; + + if (value == null) { + return entry; + } + + const missingRefs: Record[] = []; + + if (Array.isArray(value)) { + entry[uid] = value.filter((ref: any) => { + if (this.isAssetBad(ref?.uid)) { + missingRefs.push({ asset_uid: ref?.uid, filename: ref?.filename }); + return false; + } + return true; + }); + if (!entry[uid].length) { + delete entry[uid]; + } + } else if (this.isAssetBad(value?.uid)) { + missingRefs.push({ asset_uid: value?.uid, filename: value?.filename }); + delete entry[uid]; + } + + if (!isEmpty(missingRefs)) { + log.debug(`Recording asset reference fix for entry: ${this.currentUid}`); + this.missingAssetRefs[this.currentUid].push({ + tree, + data_type, + missingRefs, + display_name, + mandatory, + fixStatus: 'Fixed', + uid: this.currentUid, + name: this.currentTitle, + treeStr: tree + .map(({ name }) => name) + .filter((val) => val) + .join(' ➜ '), + }); + } + + log.debug(`File/asset fix completed for: ${field.display_name}`); + return entry; + } + /** * The function `fixGroupField` takes in a tree, a field, and an entry, and if the field has a * schema, it runs a fix on the schema and returns the updated entry, otherwise it returns the @@ -1991,4 +2150,45 @@ export default class Entries { log.debug(`Entry metadata preparation completed: ${this.entryMetaData.length} entries processed`, this.config.auditContext); log.debug(`Missing title fields found: ${Object.keys(this.missingTitleFields).length}`, this.config.auditContext); } + + /** + * Builds an index of asset uid -> { uid, filename, _asset_scan_status } from the exported + * assets/assets.json, mirroring the FsUtility chunk-read pattern used in the Assets module + * (src/modules/assets.ts). If the assets data isn't present in this export at all, + * `assetsDataAvailable` stays false and `isAssetBad()` never flags anything — absence of data + * must not be treated as every file-field reference being broken. + */ + async prepareAssetMetaData() { + log.debug('Starting asset metadata preparation', this.config.auditContext); + + const assetsBasePath = resolve( + sanitizePath(this.config.basePath), + sanitizePath(this.config.moduleConfig.assets.dirName), + ); + const assetsIndexPath = join(assetsBasePath, this.config.moduleConfig.assets.fileName); + + if (!existsSync(assetsIndexPath)) { + log.debug(`No assets data found at: ${assetsIndexPath}`, this.config.auditContext); + this.assetsDataAvailable = false; + return; + } + + this.assetsDataAvailable = true; + const fsUtility = new FsUtility({ basePath: assetsBasePath, indexFileName: 'assets.json' }); + const indexer = fsUtility.indexFileContent; + log.debug(`Found ${Object.keys(indexer).length} asset files to process`, this.config.auditContext); + + for (const _ in indexer) { + const assets = (await fsUtility.readChunkFiles.next()) as Record; + for (const assetUid in assets) { + this.assetMetaData[assetUid] = { + uid: assetUid, + filename: assets[assetUid]?.filename, + _asset_scan_status: assets[assetUid]?._asset_scan_status, + }; + } + } + + log.debug(`Asset metadata preparation completed: ${Object.keys(this.assetMetaData).length} assets processed`, this.config.auditContext); + } } diff --git a/packages/contentstack-audit/src/types/content-types.ts b/packages/contentstack-audit/src/types/content-types.ts index 2a27e92af..bd723c42e 100644 --- a/packages/contentstack-audit/src/types/content-types.ts +++ b/packages/contentstack-audit/src/types/content-types.ts @@ -162,6 +162,8 @@ enum OutputColumn { 'publish_locale' = 'publish_locale', 'publish_environment' = 'publish_environment', 'asset_uid' = 'asset_uid', + 'scan_status' = 'scan_status', + 'mandatory' = 'mandatory', 'selectedValue' = 'selectedValue', 'fixStatus' = 'fixStatus', 'Content_type_uid' = 'ct_uid', diff --git a/packages/contentstack-audit/test/unit/mock/contents/assets/assets.json b/packages/contentstack-audit/test/unit/mock/contents/assets/assets.json new file mode 100644 index 000000000..825a196ea --- /dev/null +++ b/packages/contentstack-audit/test/unit/mock/contents/assets/assets.json @@ -0,0 +1 @@ +{"1":"chunk1-assets.json"} diff --git a/packages/contentstack-audit/test/unit/mock/contents/assets/chunk1-assets.json b/packages/contentstack-audit/test/unit/mock/contents/assets/chunk1-assets.json new file mode 100644 index 000000000..a4fb857d4 --- /dev/null +++ b/packages/contentstack-audit/test/unit/mock/contents/assets/chunk1-assets.json @@ -0,0 +1,33 @@ +{ + "blt-clean-asset": { + "uid": "blt-clean-asset", + "filename": "clean.jpg", + "url": "https://images.contentstack.io/v3/assets/blt/blt-clean-asset/clean.jpg", + "_version": 1, + "_asset_scan_status": "clean", + "publish_details": [] + }, + "blt-pending-asset": { + "uid": "blt-pending-asset", + "filename": "pending.zip", + "url": "https://assets.contentstack.io/v3/assets/blt/blt-pending-asset/pending.zip", + "_version": 1, + "_asset_scan_status": "pending", + "publish_details": [] + }, + "blt-quarantined-asset": { + "uid": "blt-quarantined-asset", + "filename": "quarantined.zip", + "url": "https://assets.contentstack.io/v3/assets/blt/blt-quarantined-asset/quarantined.zip", + "_version": 1, + "_asset_scan_status": "quarantined", + "publish_details": [] + }, + "blt-no-status-asset": { + "uid": "blt-no-status-asset", + "filename": "no-status.png", + "url": "https://images.contentstack.io/v3/assets/blt/blt-no-status-asset/no-status.png", + "_version": 1, + "publish_details": [] + } +} diff --git a/packages/contentstack-audit/test/unit/modules/assets.test.ts b/packages/contentstack-audit/test/unit/modules/assets.test.ts new file mode 100644 index 000000000..f2d26a02c --- /dev/null +++ b/packages/contentstack-audit/test/unit/modules/assets.test.ts @@ -0,0 +1,74 @@ +import fs from 'fs'; +import { resolve } from 'path'; +import { expect } from 'chai'; +import fancy from 'fancy-test'; +import Sinon from 'sinon'; +import config from '../../../src/config'; +import { Assets } from '../../../src/modules'; +import { ModuleConstructorParam, CtConstructorParam } from '../../../src/types'; +import { mockLogger } from '../mock-logger'; + +describe('Assets module', () => { + let constructorParam: ModuleConstructorParam & CtConstructorParam; + + beforeEach(() => { + constructorParam = { + moduleName: 'assets', + ctSchema: [], + gfSchema: [], + config: Object.assign(config, { basePath: resolve(__dirname, '..', 'mock', 'contents'), flags: {} }), + }; + + Sinon.stub(require('@contentstack/cli-utilities'), 'log').value(mockLogger); + }); + + afterEach(() => { + Sinon.restore(); + }); + + describe('lookForReference method (scan status)', () => { + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('flags assets with a non-clean scan status and leaves clean/no-status assets alone', async () => { + const assetsInstance = new Assets(constructorParam); + await assetsInstance.prerequisiteData(); + await assetsInstance.lookForReference(); + + expect(Object.keys(assetsInstance.missingScanStatusAssets)).to.have.members([ + 'blt-pending-asset', + 'blt-quarantined-asset', + ]); + expect(assetsInstance.missingScanStatusAssets['blt-pending-asset'][0]).to.deep.include({ + asset_uid: 'blt-pending-asset', + scan_status: 'pending', + }); + expect(assetsInstance.missingScanStatusAssets['blt-quarantined-asset'][0]).to.deep.include({ + asset_uid: 'blt-quarantined-asset', + scan_status: 'quarantined', + }); + expect(assetsInstance.missingScanStatusAssets).to.not.have.property('blt-clean-asset'); + expect(assetsInstance.missingScanStatusAssets).to.not.have.property('blt-no-status-asset'); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .stub(fs, 'writeFileSync', () => {}) + .it('removes non-clean assets from the written-back chunk when fix mode is on', async () => { + const writeFileSyncStub = Sinon.spy(fs, 'writeFileSync'); + const assetsInstance = new Assets({ + ...constructorParam, + fix: true, + config: { ...constructorParam.config, flags: { yes: true } }, + }); + await assetsInstance.prerequisiteData(); + await assetsInstance.lookForReference(); + + expect(writeFileSyncStub.called).to.be.true; + const writtenContent = JSON.parse(writeFileSyncStub.firstCall.args[1] as string); + expect(writtenContent).to.not.have.property('blt-pending-asset'); + expect(writtenContent).to.not.have.property('blt-quarantined-asset'); + expect(writtenContent).to.have.property('blt-clean-asset'); + expect(writtenContent).to.have.property('blt-no-status-asset'); + }); + }); +}); diff --git a/packages/contentstack-audit/test/unit/modules/entries.test.ts b/packages/contentstack-audit/test/unit/modules/entries.test.ts index 911ba3316..49de8480a 100644 --- a/packages/contentstack-audit/test/unit/modules/entries.test.ts +++ b/packages/contentstack-audit/test/unit/modules/entries.test.ts @@ -1540,4 +1540,239 @@ describe('Entries module', () => { expect(callHelper('sys_assets', ['ct1'])).to.be.true; }); }); + + describe('prepareAssetMetaData method', () => { + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('builds an asset metadata index from assets/assets.json when it exists', async () => { + const ctInstance = new Entries(constructorParam); + await ctInstance.prepareAssetMetaData(); + + expect(ctInstance.assetsDataAvailable).to.be.true; + expect(ctInstance.assetMetaData['blt-clean-asset']).to.deep.include({ + uid: 'blt-clean-asset', + _asset_scan_status: 'clean', + }); + expect(ctInstance.assetMetaData['blt-pending-asset']).to.deep.include({ + uid: 'blt-pending-asset', + _asset_scan_status: 'pending', + }); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('leaves assetsDataAvailable false when no assets data exists in this export', async () => { + const ctInstance = new Entries({ + ...constructorParam, + config: { ...constructorParam.config, basePath: resolve(__dirname, '..', 'mock', 'contents-1') }, + }); + await ctInstance.prepareAssetMetaData(); + + expect(ctInstance.assetsDataAvailable).to.be.false; + expect(ctInstance.assetMetaData).to.deep.equal({}); + }); + }); + + describe('isAssetBad method', () => { + fancy.stdout({ print: process.env.PRINT === 'true' || false }).it('returns false when assets data is unavailable', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).assetsDataAvailable = false; + (ctInstance as any).assetMetaData = {}; + expect(ctInstance.isAssetBad('blt-unknown')).to.be.false; + }); + + fancy.stdout({ print: process.env.PRINT === 'true' || false }).it('returns false when uid is falsy', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).assetsDataAvailable = true; + expect(ctInstance.isAssetBad(undefined)).to.be.false; + }); + + fancy.stdout({ print: process.env.PRINT === 'true' || false }).it('returns true when the asset uid is not found in the index', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = {}; + expect(ctInstance.isAssetBad('blt-unknown')).to.be.true; + }); + + fancy.stdout({ print: process.env.PRINT === 'true' || false }).it('returns true when the asset scan status is non-clean', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { 'blt-1': { uid: 'blt-1', _asset_scan_status: 'quarantined' } }; + expect(ctInstance.isAssetBad('blt-1')).to.be.true; + }); + + fancy.stdout({ print: process.env.PRINT === 'true' || false }).it('returns false when the asset is clean or has no scan status', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { + 'blt-clean': { uid: 'blt-clean', _asset_scan_status: 'clean' }, + 'blt-legacy': { uid: 'blt-legacy' }, + }; + expect(ctInstance.isAssetBad('blt-clean')).to.be.false; + expect(ctInstance.isAssetBad('blt-legacy')).to.be.false; + }); + }); + + describe('validateFileField method', () => { + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('flags a single file-field value that references a quarantined asset', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).currentTitle = 'Test Entry'; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { + 'blt-quarantined': { uid: 'blt-quarantined', _asset_scan_status: 'quarantined' }, + }; + + const fieldStructure = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const value = { uid: 'blt-quarantined', filename: 'bad.zip' }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + const result = ctInstance.validateFileField(tree, fieldStructure, value); + + expect(result).to.have.length(1); + expect(result[0].missingRefs).to.deep.equal([{ asset_uid: 'blt-quarantined', filename: 'bad.zip' }]); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('does not flag a single file-field value that references a clean asset', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { 'blt-clean': { uid: 'blt-clean', _asset_scan_status: 'clean' } }; + + const fieldStructure = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const value = { uid: 'blt-clean', filename: 'ok.jpg' }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + const result = ctInstance.validateFileField(tree, fieldStructure, value); + + expect(result).to.have.length(0); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('flags only the bad entries within a multiple:true file-field array', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { 'blt-clean': { uid: 'blt-clean', _asset_scan_status: 'clean' } }; + + const fieldStructure = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const value = [ + { uid: 'blt-clean', filename: 'ok.jpg' }, + { uid: 'blt-pending', filename: 'bad.zip' }, + ]; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + const result = ctInstance.validateFileField(tree, fieldStructure, value); + + expect(result).to.have.length(1); + expect(result[0].missingRefs).to.deep.equal([{ asset_uid: 'blt-pending', filename: 'bad.zip' }]); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('does not flag anything when asset metadata is unavailable', () => { + const ctInstance = new Entries(constructorParam); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).assetsDataAvailable = false; + + const fieldStructure = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const value = { uid: 'blt-unknown', filename: 'unknown.jpg' }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + const result = ctInstance.validateFileField(tree, fieldStructure, value); + + expect(result).to.have.length(0); + }); + }); + + describe('fixFileFieldReferences method', () => { + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('deletes the field key when a single file-field value references a bad asset', () => { + const ctInstance = new Entries({ ...constructorParam, fix: true }); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).currentTitle = 'Test Entry'; + (ctInstance as any).missingAssetRefs = { 'test-entry': [] }; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { + 'blt-quarantined': { uid: 'blt-quarantined', _asset_scan_status: 'quarantined' }, + }; + + const field = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const entry: Record = { file_field: { uid: 'blt-quarantined', filename: 'bad.zip' } }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + const result = ctInstance.fixFileFieldReferences(tree, field, entry); + + expect(result).to.not.have.property('file_field'); + expect((ctInstance as any).missingAssetRefs['test-entry']).to.have.length(1); + expect((ctInstance as any).missingAssetRefs['test-entry'][0].fixStatus).to.equal('Fixed'); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('leaves a single file-field value referencing a clean asset untouched', () => { + const ctInstance = new Entries({ ...constructorParam, fix: true }); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).missingAssetRefs = { 'test-entry': [] }; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = { 'blt-clean': { uid: 'blt-clean', _asset_scan_status: 'clean' } }; + + const field = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const entry: Record = { file_field: { uid: 'blt-clean', filename: 'ok.jpg' } }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + ctInstance.fixFileFieldReferences(tree, field, entry); + + expect(entry).to.have.property('file_field'); + expect((ctInstance as any).missingAssetRefs['test-entry']).to.have.length(0); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('filters bad entries out of a multiple:true array and deletes the key if it empties out', () => { + const ctInstance = new Entries({ ...constructorParam, fix: true }); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).missingAssetRefs = { 'test-entry': [] }; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = {}; + + const field = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: false }; + const entry: Record = { + file_field: [ + { uid: 'blt-1', filename: 'one.zip' }, + { uid: 'blt-2', filename: 'two.zip' }, + ], + }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + const result = ctInstance.fixFileFieldReferences(tree, field, entry); + + expect(result).to.not.have.property('file_field'); + expect((ctInstance as any).missingAssetRefs['test-entry'][0].missingRefs).to.have.length(2); + }); + + fancy + .stdout({ print: process.env.PRINT === 'true' || false }) + .it('records mandatory:true on the fix issue so a stripped required field stays visible in the report', () => { + const ctInstance = new Entries({ ...constructorParam, fix: true }); + (ctInstance as any).currentUid = 'test-entry'; + (ctInstance as any).missingAssetRefs = { 'test-entry': [] }; + (ctInstance as any).assetsDataAvailable = true; + (ctInstance as any).assetMetaData = {}; + + const field = { uid: 'file_field', display_name: 'File Field', data_type: 'file', mandatory: true }; + const entry: Record = { file_field: { uid: 'blt-missing', filename: 'gone.zip' } }; + const tree = [{ uid: 'test-entry', name: 'Test Entry' }]; + + ctInstance.fixFileFieldReferences(tree, field, entry); + + expect((ctInstance as any).missingAssetRefs['test-entry'][0].mandatory).to.be.true; + }); + }); }); From 18bc7dc4c1c6bca8a1fa3d215124d47fa0dc040e Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 30 Jul 2026 14:40:44 +0530 Subject: [PATCH 35/44] fix(content-type): replace git-diff with jsdiff to clear Snyk issue git-diff@2.0.7 is unmaintained (last published 2018) and pulls in chalk@2, diff@3, loglevel, shelljs and shelljs.exec. Snyk flagged the only vulnerable path in the monorepo through that tree: Missing Release of Resource after Effective Lifetime [Medium] SNYK-JS-INFLIGHT-6095116 git-diff@2.0.7 > shelljs@0.8.5 > glob@7.2.3 > inflight@1.0.6 Snyk reports no direct upgrade or patch, since git-diff is abandoned. Replace it with diff@^9 (jsdiff): zero runtime dependencies, bundled TypeScript types, dual CJS/ESM. It also removes the dependency on a `git` binary and the temp-file/subprocess round trip git-diff used to shell out through shelljs. buildDiffString now calls createTwoFilesPatch, which emits the `---` and `+++` file headers itself, so the hand-rolled header concatenation is gone. Output was verified equivalent: both patch strings were run through Diff2html.parse and compared on file names, added/deleted line counts, hunk headers and every line type plus content - identical. Identical inputs are also handled better. git-diff returned undefined when both sides matched, which interpolated the literal string "undefined" into the patch; createTwoFilesPatch returns a well-formed patch with no hunks. Drop @types/git-diff, since diff ships its own types. Tests: the existing spec mocked diff2html, so the generated patch was never asserted. Add two cases covering the string handed to Diff2html.parse - one for headers, hunk and changed lines, one for the identical-input case. Both were mutation-checked against a corrupted buildDiffString. Suite: 78 passed, 16 suites, tsc clean, Snyk reports no vulnerable paths across the monorepo. Bump the pinned pnpm-lock.yaml checksum in .talismanrc, which the lockfile change invalidates. The finding is the usual sha512 integrity hashes, not a secret. Note: this commit also carries a pre-existing, uncommitted version bump to 1.5.4 that was already present in package.json. Co-Authored-By: Claude Opus 5 (1M context) --- .talismanrc | 2 +- .../contentstack-content-type/package.json | 5 +- .../skills/code-review/SKILL.md | 6 +- .../contentstack-cli-content-type/SKILL.md | 2 +- .../src/core/content-type/compare.ts | 13 +- .../tests/core/content-type/compare.test.ts | 24 +- pnpm-lock.yaml | 379 ++++-------------- 7 files changed, 117 insertions(+), 314 deletions(-) diff --git a/.talismanrc b/.talismanrc index 58ae8ba6b..3b8b7cf56 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,4 @@ fileignoreconfig: - filename: pnpm-lock.yaml - checksum: 31e333d6769adbaae042c92ea0930fab168a0e06fc1bda406d49fd1042a7a9c7 + checksum: 4dc4b2a0693ba40fd503cf52d6d69b577ec87018e4f9ab52415608c65c14f6aa version: '1.0' diff --git a/packages/contentstack-content-type/package.json b/packages/contentstack-content-type/package.json index 14c81f2ff..1f39206cc 100644 --- a/packages/contentstack-content-type/package.json +++ b/packages/contentstack-content-type/package.json @@ -1,21 +1,20 @@ { "name": "contentstack-cli-content-type", "description": "Retrieve information about Content Types in a Stack.", - "version": "1.5.3", + "version": "1.5.4", "author": "Contentstack Developer", "bugs": "https://github.com/contentstack/cli-plugins/issues", "dependencies": { "@contentstack/cli-command": "^1.8.5", "@contentstack/cli-utilities": "^1.19.0", "@types/diff2html": "^3.0.3", - "@types/git-diff": "^2.0.7", "@types/hogan.js": "^3.0.5", "@types/table": "^6.3.2", "@types/tmp": "^0.2.6", "axios": "^1.18.1", "cli-ux": "^6.0.9", + "diff": "^9.0.0", "diff2html": "^3.4.56", - "git-diff": "^2.0.7", "moment": "^2.30.1", "node-graphviz": "^0.1.1", "table": "^6.9.0", diff --git a/packages/contentstack-content-type/skills/code-review/SKILL.md b/packages/contentstack-content-type/skills/code-review/SKILL.md index 9d0809c5f..e5bc5316f 100644 --- a/packages/contentstack-content-type/skills/code-review/SKILL.md +++ b/packages/contentstack-content-type/skills/code-review/SKILL.md @@ -11,7 +11,7 @@ description: >- ## When to use - Reviewing a PR or diff before merge. -- Auditing dependency upgrades (axios, diff2html, git-diff, node-graphviz, tmp, cli-ux). +- Auditing dependency upgrades (axios, diff2html, diff, node-graphviz, tmp, cli-ux). - Changes touching compare HTML, temp files, diagram output, or `src/core/contentstack/`. ## Instructions @@ -24,7 +24,7 @@ Use **Critical** / **Important** / **Suggestion** when leaving feedback. - **Secrets**: Never approve logging of tokens, `authtoken` / `authorization` values, or raw management tokens. - **Compare / diagram**: Changes to [src/core/content-type/compare.ts](../../src/core/content-type/compare.ts) or [diagram.ts](../../src/core/content-type/diagram.ts) deserve extra scrutiny (temp files, browser open, paths, binary dependency). -- **Dependencies**: axios, diff2html, git-diff, node-graphviz, tmp, cli-ux—review changelog and supply-chain for version bumps. +- **Dependencies**: axios, diff2html, diff, node-graphviz, tmp, cli-ux—review changelog and supply-chain for version bumps. - **Quality**: TypeScript and **eslint-config-oclif-typescript** ([.eslintrc](../../.eslintrc)); behavioral changes should include or update **Jest** tests where appropriate. ### Security and privacy @@ -57,7 +57,7 @@ Use **Critical** / **Important** / **Suggestion** when leaving feedback. | Severity | Item | |----------|------| | Important | **axios**: security advisories; upgrade notes. | -| Important | **diff2html**, **git-diff**, **tmp**, **cli-ux**: behavior changes affecting compare UX. | +| Important | **diff2html**, **diff**, **tmp**, **cli-ux**: behavior changes affecting compare UX. | | Important | **node-graphviz**: compatibility with supported Node and system Graphviz. | | Suggestion | **moment** (if touched): prefer minimal churn; note maintenance status of dependencies. | diff --git a/packages/contentstack-content-type/skills/contentstack-cli-content-type/SKILL.md b/packages/contentstack-content-type/skills/contentstack-cli-content-type/SKILL.md index 4434d876d..aaf02cf86 100644 --- a/packages/contentstack-content-type/skills/contentstack-cli-content-type/SKILL.md +++ b/packages/contentstack-content-type/skills/contentstack-cli-content-type/SKILL.md @@ -100,7 +100,7 @@ Errors: response `data.errors` → `ContentstackError`; optional suffix with sta ### Compare and diagram pipelines -- **Compare**: `core/content-type/compare.ts` builds a unified diff from two JSON snapshots (`git-diff`), parses with **diff2html**, writes a **temporary HTML** file, opens it in the browser (`cli-ux` / `cli.open`). Not a terminal table. +- **Compare**: `core/content-type/compare.ts` builds a unified diff from two JSON snapshots (`diff`), parses with **diff2html**, writes a **temporary HTML** file, opens it in the browser (`cli-ux` / `cli.open`). Not a terminal table. - **Diagram**: `core/content-type/diagram.ts` builds a DOT graph, runs **node-graphviz** (`graphviz` binary must be available on the system for SVG rendering). Output path is sanitized where utilities apply. ### Commands (flags and behavior) diff --git a/packages/contentstack-content-type/src/core/content-type/compare.ts b/packages/contentstack-content-type/src/core/content-type/compare.ts index 696335191..a98028b2b 100644 --- a/packages/contentstack-content-type/src/core/content-type/compare.ts +++ b/packages/contentstack-content-type/src/core/content-type/compare.ts @@ -2,7 +2,7 @@ import cli from 'cli-ux' import * as fs from 'fs' import * as tmp from 'tmp' import * as Diff2html from 'diff2html' -import gitDiff from 'git-diff' +import {createTwoFilesPatch} from 'diff' import {BuildOutput} from '../../types' export default async function buildOutput(contentTypeName: string, previous: any, current: any): Promise { @@ -30,10 +30,13 @@ export default async function buildOutput(contentTypeName: string, previous: any } function buildDiffString(previous: any, current: any) { - return ( - `--- ${previous.uid}\t${current.updated_at}\n` + - `+++ ${current.uid}\t${current.updated_at}\n` + - gitDiff(JSON.stringify(previous, null, 2), JSON.stringify(current, null, 2)) + return createTwoFilesPatch( + previous.uid, + current.uid, + JSON.stringify(previous, null, 2), + JSON.stringify(current, null, 2), + current.updated_at, + current.updated_at, ) } diff --git a/packages/contentstack-content-type/tests/core/content-type/compare.test.ts b/packages/contentstack-content-type/tests/core/content-type/compare.test.ts index d092d9e72..746f4576e 100644 --- a/packages/contentstack-content-type/tests/core/content-type/compare.test.ts +++ b/packages/contentstack-content-type/tests/core/content-type/compare.test.ts @@ -25,11 +25,8 @@ jest.mock('diff2html', () => ({ html: jest.fn(() => '
diff-html
'), })) -jest.mock('git-diff', () => - jest.fn(() => '@@ -1 +1 @@\n+changed') -) - import fs from 'fs' +import * as Diff2html from 'diff2html' import buildOutput from '../../../src/core/content-type/compare' @@ -53,4 +50,23 @@ describe('compare buildOutput', () => { expect(written).toContain('diff-html') expect(written).toContain('diff2html') }) + + it('feeds diff2html a unified patch with file headers and the changed lines', async () => { + await buildOutput('my-ct', prev, curr) + + const patch = (Diff2html.parse as jest.Mock).mock.calls[0][0] as string + expect(patch).toContain(`--- ${prev.uid}\t${curr.updated_at}`) + expect(patch).toContain(`+++ ${curr.uid}\t${curr.updated_at}`) + expect(patch).toMatch(/^@@ .* @@$/m) + expect(patch).toContain('- "updated_at": "2020-01-01"') + expect(patch).toContain('+ "updated_at": "2021-01-01"') + }) + + it('produces a patch with no hunks when both versions are identical', async () => { + await buildOutput('my-ct', prev, prev) + + const patch = (Diff2html.parse as jest.Mock).mock.calls[0][0] as string + expect(patch).not.toContain('@@') + expect(patch).not.toContain('undefined') + }) }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c641a7a66..128246fdf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -335,7 +335,7 @@ importers: version: 5.5.0 '@contentstack/management': specifier: ^1.30.3 - version: 1.31.0 + version: 1.30.4(debug@4.4.3) lodash: specifier: 4.18.1 version: 4.18.1 @@ -487,7 +487,7 @@ importers: version: 1.19.0(@types/node@18.19.130) '@contentstack/management': specifier: ^1.30.4 - version: 1.31.0 + version: 1.30.4(debug@4.4.3) cli-table3: specifier: ^0.6.5 version: 0.6.5 @@ -624,13 +624,13 @@ importers: version: 3.1.14(eslint@10.8.0)(typescript@5.9.3) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + version: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) oclif: specifier: ^4.23.8 version: 4.23.29(@types/node@22.20.1) ts-jest: specifier: ^29.4.9 - version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))(typescript@5.9.3) + version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1))(typescript@5.9.3) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -734,9 +734,6 @@ importers: '@types/diff2html': specifier: ^3.0.3 version: 3.0.3 - '@types/git-diff': - specifier: ^2.0.7 - version: 2.0.7 '@types/hogan.js': specifier: ^3.0.5 version: 3.0.5 @@ -752,12 +749,12 @@ importers: cli-ux: specifier: ^6.0.9 version: 6.0.9 + diff: + specifier: ^9.0.0 + version: 9.0.0 diff2html: specifier: ^3.4.56 version: 3.4.56 - git-diff: - specifier: ^2.0.7 - version: 2.0.7 moment: specifier: ^2.30.1 version: 2.30.1 @@ -1246,10 +1243,10 @@ importers: dependencies: '@contentstack/cli-command': specifier: 1.8.5 - version: 1.8.5(@types/node@18.19.130) + version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-utilities': specifier: 1.19.0 - version: 1.19.0(@types/node@18.19.130) + version: 1.19.0(@types/node@22.20.1) '@contentstack/json-rte-serializer': specifier: ~2.1.0 version: 2.1.0 @@ -1304,7 +1301,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.23.8 - version: 4.23.29 + version: 4.23.29(@types/node@22.20.1) querystring: specifier: ^0.2.1 version: 0.2.1 @@ -2352,10 +2349,6 @@ packages: resolution: {integrity: sha512-wFmHxf2WfPVXD8uvFpaxdY882ELqYhdPu1aQM9VM/UYUtJg+7uCj9k785ujYfgbSKgxfY6APgwI++n59v3Entg==} engines: {node: '>=8.0.0'} - '@contentstack/management@1.31.0': - resolution: {integrity: sha512-Ejk7ozH0lDxa0Ozniii2hsNLr8u0XfBRNHYmLw7DFQZDuRopaIxCb+Udn2O+uP/4ffKSYVv/RVu6/GhACdtWFg==} - engines: {node: '>=8.0.0'} - '@contentstack/marketplace-sdk@1.5.4': resolution: {integrity: sha512-rqsL/FvYTqF1a1MK/AZLdWCGf7WY48f4pT/iLkwt6wxh7apxaAwWSWy9ZWRtDu7EIV9FDDTHZ33iYWKH41fnlw==} @@ -3473,9 +3466,6 @@ packages: '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - '@types/git-diff@2.0.7': - resolution: {integrity: sha512-hipFAUcmf3c+45+Y8+J/xk7gT+0HBuT3O8OTtrnoP6R9gI0r2xESZNdYiA0pj7kQyPCwmkgbnxmfwQ9Ld2lZLQ==} - '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -5013,10 +5003,6 @@ packages: resolution: {integrity: sha512-u9gfn+BlbHcyO7vItCIC4z49LJDUt31tODzOfAuJ5R1E7IdlRL6KjugcB9zOpejD+XiR+dDZbsnHSQ3g6A/u8A==} engines: {node: '>=12'} - diff@3.5.1: - resolution: {integrity: sha512-Z3u54A8qGyqFOSr2pk0ijYs8mOE9Qz8kTvtKeBI+upoG9j04Sq+oI7W8zAJiQybDcESET8/uIdHzs0p3k4fZlw==} - engines: {node: '>=0.3.1'} - diff@4.0.4: resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} @@ -5808,10 +5794,6 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} - git-diff@2.0.7: - resolution: {integrity: sha512-/+vyWaKNUJLcVT+tm5Hsly2xDcIs49EkZstxqW7ap1ZiZ0BECviLK1iv9/f4cGhlKBokeAf61QkTDnL88H+Uhg==} - engines: {node: '>= 4.8.0'} - git-raw-commits@5.0.1: resolution: {integrity: sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==} engines: {node: '>=18'} @@ -7007,10 +6989,6 @@ packages: resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} engines: {node: '>= 12.0.0'} - loglevel@1.9.2: - resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} - engines: {node: '>= 0.6.0'} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -7631,8 +7609,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.24: - resolution: {integrity: sha512-8RyVklq0owXUTa4xlpzu4l9AaVKIdQvAcOHZWaMh98HgySsUtxRVf/chRe3dsSLqb6i40BzGRzEUddRaI+9TSw==} + postcss@8.5.25: + resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -8124,19 +8102,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shelljs.exec@1.1.8: - resolution: {integrity: sha512-vFILCw+lzUtiwBAHV8/Ex8JsFjelFMdhONIsgKNLgTzeRckp2AOYRQtHJE/9LhNvdMmE27AGtzWx0+DHpwIwSw==} - engines: {node: '>= 4.0.0'} - shelljs@0.10.0: resolution: {integrity: sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw==} engines: {node: '>=18'} - shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - shelljs@0.9.2: resolution: {integrity: sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==} engines: {node: '>=18'} @@ -10518,22 +10487,6 @@ snapshots: - debug - supports-color - '@contentstack/management@1.31.0': - dependencies: - '@contentstack/utils': 1.9.1 - assert: 2.1.0 - axios: 1.18.1(debug@4.4.3) - buffer: 6.0.3 - form-data: 4.0.6 - husky: 9.1.7 - lodash: 4.18.1 - otplib: 12.0.1 - qs: 6.15.3 - stream-browserify: 3.0.0 - transitivePeerDependencies: - - debug - - supports-color - '@contentstack/marketplace-sdk@1.5.4(debug@4.4.3)': dependencies: '@contentstack/utils': 1.9.1 @@ -11113,19 +11066,6 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/prompts@7.10.1': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@18.19.130) - '@inquirer/confirm': 5.1.21(@types/node@18.19.130) - '@inquirer/editor': 4.2.23(@types/node@18.19.130) - '@inquirer/expand': 4.0.23(@types/node@18.19.130) - '@inquirer/input': 4.3.1(@types/node@18.19.130) - '@inquirer/number': 3.0.23(@types/node@18.19.130) - '@inquirer/password': 4.0.23(@types/node@18.19.130) - '@inquirer/rawlist': 4.1.11(@types/node@18.19.130) - '@inquirer/search': 3.2.2(@types/node@18.19.130) - '@inquirer/select': 4.4.2(@types/node@18.19.130) - '@inquirer/prompts@7.10.1(@types/node@14.18.63)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@14.18.63) @@ -11402,41 +11342,6 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.19.43 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - '@jest/core@29.7.0(ts-node@8.10.2(typescript@4.9.5))': dependencies: '@jest/console': 29.7.0 @@ -11916,15 +11821,6 @@ snapshots: dependencies: '@oclif/core': 4.13.2 - '@oclif/plugin-not-found@3.2.90': - dependencies: - '@inquirer/prompts': 7.10.1 - '@oclif/core': 4.13.2 - ansis: 3.17.0 - fast-levenshtein: 3.0.0 - transitivePeerDependencies: - - '@types/node' - '@oclif/plugin-not-found@3.2.90(@types/node@14.18.63)': dependencies: '@inquirer/prompts': 7.10.1(@types/node@14.18.63) @@ -12446,8 +12342,6 @@ snapshots: '@types/jsonfile': 6.1.4 '@types/node': 20.19.43 - '@types/git-diff@2.0.7': {} - '@types/graceful-fs@4.1.9': dependencies: '@types/node': 20.19.43 @@ -14388,21 +14282,6 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - create-require@1.1.1: {} cross-fetch@4.1.0: @@ -14564,8 +14443,6 @@ snapshots: optionalDependencies: highlight.js: 11.11.1 - diff@3.5.1: {} - diff@4.0.4: {} diff@5.2.2: {} @@ -14807,7 +14684,7 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo-space: 0.35.0(eslint@10.8.0) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 15.7.0(eslint@10.8.0) eslint-plugin-perfectionist: 2.11.0(eslint@10.8.0)(typescript@5.9.3) @@ -14863,8 +14740,8 @@ snapshots: '@typescript-eslint/parser': 8.65.0(eslint@10.8.0)(typescript@4.9.5) eslint-config-xo: 0.49.0(eslint@10.8.0) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) eslint-plugin-jsdoc: 50.8.0(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 17.24.0(eslint@10.8.0)(typescript@4.9.5) @@ -14969,6 +14846,21 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3(supports-color@8.1.1) + eslint: 10.8.0 + get-tsconfig: 4.14.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.17 + unrs-resolver: 1.12.2 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + transitivePeerDependencies: + - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0): dependencies: '@nolyfill/is-core-module': 1.0.39 @@ -14995,6 +14887,17 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) + eslint: 10.8.0 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: debug: 3.2.7 @@ -15006,14 +14909,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.65.0(eslint@10.8.0)(typescript@4.9.5) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -15087,6 +14990,35 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 10.8.0 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + hasown: 2.0.4 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.10 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 @@ -15116,7 +15048,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15127,7 +15059,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -15911,14 +15843,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - git-diff@2.0.7: - dependencies: - chalk: 2.4.2 - diff: 3.5.1 - loglevel: 1.9.2 - shelljs: 0.8.5 - shelljs.exec: 1.1.8 - git-raw-commits@5.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0): dependencies: '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) @@ -16746,25 +16670,6 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.3 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - jest-cli@30.4.2(@types/node@18.19.130)(ts-node@10.9.2(@types/node@18.19.130)(typescript@5.9.3)): dependencies: '@jest/core': 30.4.2(ts-node@10.9.2(@types/node@18.19.130)(typescript@5.9.3)) @@ -16846,37 +16751,6 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): - dependencies: - '@babel/core': 7.29.7 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.7) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 20.19.43 - ts-node: 10.9.2(@types/node@22.20.1)(typescript@5.9.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - jest-config@29.7.0(@types/node@20.19.43)(ts-node@8.10.2(typescript@4.9.5)): dependencies: '@babel/core': 7.29.7 @@ -16939,37 +16813,6 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): - dependencies: - '@babel/core': 7.29.7 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.7) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.20.1 - ts-node: 10.9.2(@types/node@22.20.1)(typescript@5.9.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - jest-config@30.4.2(@types/node@18.19.130)(ts-node@10.9.2(@types/node@18.19.130)(typescript@5.9.3)): dependencies: '@babel/core': 7.29.7 @@ -17486,7 +17329,7 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)): + jest@29.7.0(@types/node@22.20.1): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) '@jest/types': 29.6.3 @@ -17498,12 +17341,12 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): + jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + jest-cli: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -17868,8 +17711,6 @@ snapshots: safe-stable-stringify: 2.5.0 triple-beam: 1.4.1 - loglevel@1.9.2: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -18293,35 +18134,6 @@ snapshots: obug@2.1.4: {} - oclif@4.23.29: - dependencies: - '@aws-sdk/client-cloudfront': 3.1097.0 - '@aws-sdk/client-s3': 3.1097.0 - '@inquirer/confirm': 3.2.0 - '@inquirer/input': 2.3.0 - '@inquirer/select': 2.5.0 - '@oclif/core': 4.13.2 - '@oclif/plugin-help': 6.2.55 - '@oclif/plugin-not-found': 3.2.90 - '@oclif/plugin-warn-if-update-available': 3.1.70 - ansis: 3.17.0 - async-retry: 1.3.3 - change-case: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3(supports-color@8.1.1) - ejs: 3.1.10 - find-yarn-workspace-root: 2.0.0 - fs-extra: 8.1.0 - github-slugger: 2.0.0 - got: 13.0.0 - normalize-package-data: 6.0.2 - semver: 7.8.5 - tiny-jsonc: 1.0.2 - validate-npm-package-name: 5.0.1 - transitivePeerDependencies: - - '@types/node' - - supports-color - oclif@4.23.29(@types/node@14.18.63): dependencies: '@aws-sdk/client-cloudfront': 3.1097.0 @@ -18664,7 +18476,7 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss@8.5.24: + postcss@8.5.25: dependencies: nanoid: 3.3.16 picocolors: 1.1.1 @@ -19214,19 +19026,11 @@ snapshots: shebang-regex@3.0.0: {} - shelljs.exec@1.1.8: {} - shelljs@0.10.0: dependencies: execa: 5.1.1 fast-glob: 3.3.3 - shelljs@0.8.5: - dependencies: - glob: 7.2.3 - interpret: 1.4.0 - rechoir: 0.6.2 - shelljs@0.9.2: dependencies: execa: 1.0.0 @@ -19778,12 +19582,12 @@ snapshots: babel-jest: 30.4.1(@babel/core@7.29.7) jest-util: 30.4.1 - ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))(typescript@5.9.3): + ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.9 - jest: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + jest: 29.7.0(@types/node@22.20.1) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -19926,25 +19730,6 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.20.1 - acorn: 8.18.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.4 - make-error: 1.3.6 - typescript: 5.9.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optional: true - ts-node@8.10.2(typescript@4.9.5): dependencies: arg: 4.1.3 @@ -20232,7 +20017,7 @@ snapshots: dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 - postcss: 8.5.24 + postcss: 8.5.25 rolldown: 1.1.5 tinyglobby: 0.2.17 optionalDependencies: From c30a26026d66ac79ba1a246fceaae0beae2fbbac Mon Sep 17 00:00:00 2001 From: Netraj Patel Date: Wed, 5 Aug 2026 12:07:45 +0530 Subject: [PATCH 36/44] chore: repair pnpm-lock.yaml broken by development merge The merge of development into this branch left pnpm-lock.yaml internally inconsistent: an eslint-import-resolver-typescript@3.10.1 snapshot still referenced get-tsconfig@4.14.0 while the packages section had advanced to 4.14.1, and several peer-dependency snapshots (ts-node, @tsconfig/*, jest, eslint resolver permutations) had been dropped. This made `pnpm install --frozen-lockfile` fail with ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY, breaking the run-tests and tsgen-integration jobs at the install step before any test could run. Regenerated with `pnpm install --no-frozen-lockfile` using pnpm 10.28.0, matching the pinned packageManager. Lockfile-only change: no package.json or dependency versions altered. Refreshed the pnpm-lock.yaml checksum in .talismanrc to match, per existing repo practice. Co-Authored-By: Claude Opus 5 (1M context) --- .talismanrc | 2 +- pnpm-lock.yaml | 219 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 192 insertions(+), 29 deletions(-) diff --git a/.talismanrc b/.talismanrc index 3b8b7cf56..cda7f6c2c 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,4 @@ fileignoreconfig: - filename: pnpm-lock.yaml - checksum: 4dc4b2a0693ba40fd503cf52d6d69b577ec87018e4f9ab52415608c65c14f6aa + checksum: 94d134f1763796fc51f681977a5e151552b4ad7a441c0b4cfc63e1150881be0e version: '1.0' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2640316ad..528c9afd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -624,13 +624,13 @@ importers: version: 3.1.14(eslint@10.8.0)(typescript@5.9.3) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) oclif: specifier: ^4.23.8 version: 4.23.29(@types/node@22.20.1) ts-jest: specifier: ^29.4.9 - version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1))(typescript@5.9.3) + version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))(typescript@5.9.3) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -1243,10 +1243,10 @@ importers: dependencies: '@contentstack/cli-command': specifier: 1.8.5 - version: 1.8.5(@types/node@22.20.1) + version: 1.8.5(@types/node@18.19.130) '@contentstack/cli-utilities': specifier: 1.19.0 - version: 1.19.0(@types/node@22.20.1) + version: 1.19.0(@types/node@18.19.130) '@contentstack/json-rte-serializer': specifier: ~2.1.0 version: 2.1.0 @@ -1301,7 +1301,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.23.8 - version: 4.23.29(@types/node@22.20.1) + version: 4.23.29 querystring: specifier: ^0.2.1 version: 0.2.1 @@ -11062,6 +11062,19 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 + '@inquirer/prompts@7.10.1': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@18.19.130) + '@inquirer/confirm': 5.1.21(@types/node@18.19.130) + '@inquirer/editor': 4.2.23(@types/node@18.19.130) + '@inquirer/expand': 4.0.23(@types/node@18.19.130) + '@inquirer/input': 4.3.1(@types/node@18.19.130) + '@inquirer/number': 3.0.23(@types/node@18.19.130) + '@inquirer/password': 4.0.23(@types/node@18.19.130) + '@inquirer/rawlist': 4.1.11(@types/node@18.19.130) + '@inquirer/search': 3.2.2(@types/node@18.19.130) + '@inquirer/select': 4.4.2(@types/node@18.19.130) + '@inquirer/prompts@7.10.1(@types/node@14.18.63)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@14.18.63) @@ -11338,6 +11351,41 @@ snapshots: - supports-color - ts-node + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.43 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + '@jest/core@29.7.0(ts-node@8.10.2(typescript@4.9.5))': dependencies: '@jest/console': 29.7.0 @@ -14276,6 +14324,21 @@ snapshots: - supports-color - ts-node + create-jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-require@1.1.1: {} cross-fetch@4.1.0: @@ -14677,8 +14740,8 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0)(typescript@5.9.3) '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 15.7.0(eslint@10.8.0) eslint-plugin-perfectionist: 2.11.0(eslint@10.8.0)(typescript@5.9.3) @@ -14759,8 +14822,8 @@ snapshots: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo: 0.49.0(eslint@10.8.0) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) eslint-plugin-jsdoc: 50.8.0(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 17.24.0(eslint@10.8.0)(typescript@5.9.3) @@ -14840,18 +14903,18 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) eslint: 10.8.0 - get-tsconfig: 4.14.0 + get-tsconfig: 4.14.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14866,7 +14929,7 @@ snapshots: tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14881,14 +14944,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14910,18 +14973,18 @@ snapshots: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@4.9.5) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@10.8.0)(typescript@4.9.5))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14984,7 +15047,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -14995,7 +15058,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -15071,7 +15134,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15082,7 +15145,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -16664,6 +16727,25 @@ snapshots: - supports-color - ts-node + jest-cli@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.3 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@30.4.2(@types/node@18.19.130)(ts-node@10.9.2(@types/node@18.19.130)(typescript@5.9.3)): dependencies: '@jest/core': 30.4.2(ts-node@10.9.2(@types/node@18.19.130)(typescript@5.9.3)) @@ -16745,6 +16827,37 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.7.0(@types/node@20.19.43)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.29.7 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.7) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.19.43 + ts-node: 10.9.2(@types/node@22.20.1)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@20.19.43)(ts-node@8.10.2(typescript@4.9.5)): dependencies: '@babel/core': 7.29.7 @@ -16807,6 +16920,37 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.29.7 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.7) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.20.1 + ts-node: 10.9.2(@types/node@22.20.1)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@30.4.2(@types/node@18.19.130)(ts-node@10.9.2(@types/node@18.19.130)(typescript@5.9.3)): dependencies: '@babel/core': 7.29.7 @@ -17323,7 +17467,7 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@22.20.1): + jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) '@jest/types': 29.6.3 @@ -17335,12 +17479,12 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)): + jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@4.9.5)) + jest-cli: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -19605,12 +19749,12 @@ snapshots: babel-jest: 30.4.1(@babel/core@7.29.7) jest-util: 30.4.1 - ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1))(typescript@5.9.3): + ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.9 - jest: 29.7.0(@types/node@22.20.1) + jest: 29.7.0(@types/node@22.20.1)(ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -19753,6 +19897,25 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-node@10.9.2(@types/node@22.20.1)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.20.1 + acorn: 8.18.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + ts-node@8.10.2(typescript@4.9.5): dependencies: arg: 4.1.3 From 032819ac8518c9ded7b77497f40a31d9105efdc1 Mon Sep 17 00:00:00 2001 From: Netraj Patel Date: Wed, 5 Aug 2026 12:34:49 +0530 Subject: [PATCH 37/44] chore(content-type): move @types/* to devDependencies, drop unused hogan types Addresses Copilot review feedback on #324. contentstack-content-type was the only package of 20 declaring @types/* under dependencies; the other 19 keep them in devDependencies. Type packages are compile-time only and nothing here re-exports their types publicly, so shipping them as runtime deps only inflated the production install. Moved @types/diff2html, @types/table and @types/tmp to devDependencies. The runtime packages they describe (diff2html, table, tmp) stay in dependencies. Dropped @types/hogan.js entirely rather than moving it: hogan is referenced nowhere in this package's src or tests, and hogan.js is not a runtime dependency of any package in the repo, so the types were dead weight. Verified with `tsc -b --force` (clean, emits lib/) and the package suite (16 suites, 78 tests passing). Talisman checksum for pnpm-lock.yaml refreshed via `talisman --checksum`. Co-Authored-By: Claude Opus 5 (1M context) --- .talismanrc | 2 +- .../contentstack-content-type/package.json | 7 +++-- pnpm-lock.yaml | 26 +++++++------------ 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/.talismanrc b/.talismanrc index cda7f6c2c..3a0a0af19 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,4 @@ fileignoreconfig: - filename: pnpm-lock.yaml - checksum: 94d134f1763796fc51f681977a5e151552b4ad7a441c0b4cfc63e1150881be0e + checksum: e189b3ff17c005329a25e849555543e0cbdc5ea326d087e78b0a867b8978b308 version: '1.0' diff --git a/packages/contentstack-content-type/package.json b/packages/contentstack-content-type/package.json index 1f39206cc..13180fcac 100644 --- a/packages/contentstack-content-type/package.json +++ b/packages/contentstack-content-type/package.json @@ -7,10 +7,6 @@ "dependencies": { "@contentstack/cli-command": "^1.8.5", "@contentstack/cli-utilities": "^1.19.0", - "@types/diff2html": "^3.0.3", - "@types/hogan.js": "^3.0.5", - "@types/table": "^6.3.2", - "@types/tmp": "^0.2.6", "axios": "^1.18.1", "cli-ux": "^6.0.9", "diff": "^9.0.0", @@ -24,8 +20,11 @@ }, "devDependencies": { "@oclif/plugin-help": "^6.2.49", + "@types/diff2html": "^3.0.3", "@types/jest": "^29.5.14", "@types/node": "^22.19.19", + "@types/table": "^6.3.2", + "@types/tmp": "^0.2.6", "eslint": "^10.5.0", "eslint-config-oclif": "^6.0.162", "eslint-config-oclif-typescript": "^3.1.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 528c9afd2..564879518 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -731,18 +731,6 @@ importers: '@contentstack/cli-utilities': specifier: ^1.19.0 version: 1.19.0(@types/node@22.20.1) - '@types/diff2html': - specifier: ^3.0.3 - version: 3.0.3 - '@types/hogan.js': - specifier: ^3.0.5 - version: 3.0.5 - '@types/table': - specifier: ^6.3.2 - version: 6.3.2 - '@types/tmp': - specifier: ^0.2.6 - version: 0.2.6 axios: specifier: ^1.18.1 version: 1.19.0(debug@4.4.3) @@ -777,12 +765,21 @@ importers: '@oclif/plugin-help': specifier: ^6.2.49 version: 6.2.56 + '@types/diff2html': + specifier: ^3.0.3 + version: 3.0.3 '@types/jest': specifier: ^29.5.14 version: 29.5.14 '@types/node': specifier: ^22.19.19 version: 22.20.1 + '@types/table': + specifier: ^6.3.2 + version: 6.3.2 + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 eslint: specifier: ^10.5.0 version: 10.8.0 @@ -3465,9 +3462,6 @@ packages: '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - '@types/hogan.js@3.0.5': - resolution: {integrity: sha512-/uRaY3HGPWyLqOyhgvW9Aa43BNnLZrNeQxl2p8wqId4UHMfPKolSB+U7BlZyO1ng7MkLnyEAItsBzCG0SDhqrA==} - '@types/http-cache-semantics@4.2.0': resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} @@ -12388,8 +12382,6 @@ snapshots: dependencies: '@types/node': 20.19.43 - '@types/hogan.js@3.0.5': {} - '@types/http-cache-semantics@4.2.0': {} '@types/http-errors@2.0.5': {} From d4f8e72469c2e34467b35eea5763acdc03d33f6b Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 Aug 2026 17:12:53 +0530 Subject: [PATCH 38/44] bumped versions --- packages/contentstack-apps-cli/package.json | 4 +- packages/contentstack-audit/README.md | 2 +- packages/contentstack-audit/package.json | 4 +- packages/contentstack-bootstrap/README.md | 2 +- packages/contentstack-bootstrap/package.json | 8 ++-- packages/contentstack-branches/README.md | 2 +- packages/contentstack-branches/package.json | 4 +- .../contentstack-bulk-operations/package.json | 4 +- packages/contentstack-bulk-publish/README.md | 39 ++++++++++++++----- .../contentstack-bulk-publish/package.json | 6 +-- .../package.json | 4 +- packages/contentstack-cli-tsgen/package.json | 4 +- packages/contentstack-clone/README.md | 2 +- packages/contentstack-clone/package.json | 8 ++-- packages/contentstack-content-type/README.md | 2 +- .../contentstack-content-type/package.json | 2 +- packages/contentstack-export-to-csv/README.md | 2 +- .../contentstack-export-to-csv/package.json | 4 +- packages/contentstack-export/README.md | 2 +- packages/contentstack-export/package.json | 8 ++-- .../package.json | 4 +- packages/contentstack-import-setup/README.md | 2 +- .../contentstack-import-setup/package.json | 4 +- packages/contentstack-import/README.md | 2 +- packages/contentstack-import/package.json | 8 ++-- .../contentstack-migrate-rte/package.json | 4 +- packages/contentstack-migration/README.md | 2 +- packages/contentstack-migration/package.json | 4 +- .../contentstack-query-export/package.json | 8 ++-- packages/contentstack-seed/README.md | 2 +- packages/contentstack-seed/package.json | 6 +-- packages/contentstack-variants/package.json | 4 +- 32 files changed, 92 insertions(+), 71 deletions(-) diff --git a/packages/contentstack-apps-cli/package.json b/packages/contentstack-apps-cli/package.json index 59b265e12..4fb2988b1 100644 --- a/packages/contentstack-apps-cli/package.json +++ b/packages/contentstack-apps-cli/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/apps-cli", - "version": "1.7.3", + "version": "1.7.4", "description": "App ClI", "author": "Contentstack CLI", "homepage": "https://github.com/contentstack/cli-plugins/tree/main/packages/contentstack-apps-cli", @@ -24,7 +24,7 @@ "@apollo/client": "^3.14.1", "@contentstack/cli-command": "~1.8.5", "@contentstack/cli-launch": "^1.11.1", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "adm-zip": "^0.5.17", "chalk": "^4.1.2", "lodash": "^4.18.1", diff --git a/packages/contentstack-audit/README.md b/packages/contentstack-audit/README.md index 0cbcc1f20..43ba0ad3b 100644 --- a/packages/contentstack-audit/README.md +++ b/packages/contentstack-audit/README.md @@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-audit $ csdx COMMAND running command... $ csdx (--version|-v) -@contentstack/cli-audit/1.19.5 darwin-arm64 node-v22.21.1 +@contentstack/cli-audit/1.21.0 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-audit/package.json b/packages/contentstack-audit/package.json index dbcdf02e5..039441212 100644 --- a/packages/contentstack-audit/package.json +++ b/packages/contentstack-audit/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-audit", - "version": "1.20.0", + "version": "1.21.0", "description": "Contentstack audit plugin", "author": "Contentstack CLI", "homepage": "https://github.com/contentstack/cli", @@ -19,7 +19,7 @@ ], "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "fast-csv": "^4.3.6", diff --git a/packages/contentstack-bootstrap/README.md b/packages/contentstack-bootstrap/README.md index 2aadfdf45..c132a306a 100644 --- a/packages/contentstack-bootstrap/README.md +++ b/packages/contentstack-bootstrap/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-cm-bootstrap $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-bootstrap/1.19.7 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-bootstrap/1.19.9 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-bootstrap/package.json b/packages/contentstack-bootstrap/package.json index 3e736cf0e..3bbd5fa74 100644 --- a/packages/contentstack-bootstrap/package.json +++ b/packages/contentstack-bootstrap/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-bootstrap", "description": "Bootstrap contentstack apps", - "version": "1.19.8", + "version": "1.19.9", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "scripts": { @@ -17,10 +17,10 @@ "lint": "eslint \"src/**/*.ts\"" }, "dependencies": { - "@contentstack/cli-cm-seed": "~1.15.9", + "@contentstack/cli-cm-seed": "~1.15.10", "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-config": "~1.21.0", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-config": "~1.21.1", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "inquirer": "8.2.7", "mkdirp": "^2.1.6", diff --git a/packages/contentstack-branches/README.md b/packages/contentstack-branches/README.md index df8c50b78..087f61cc8 100755 --- a/packages/contentstack-branches/README.md +++ b/packages/contentstack-branches/README.md @@ -23,7 +23,7 @@ $ npm install -g @contentstack/cli-cm-branches $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-branches/1.8.3 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-branches/1.8.5 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-branches/package.json b/packages/contentstack-branches/package.json index 82ba544a2..0e62e6ac1 100644 --- a/packages/contentstack-branches/package.json +++ b/packages/contentstack-branches/package.json @@ -1,12 +1,12 @@ { "name": "@contentstack/cli-cm-branches", "description": "Contentstack CLI plugin to do branches operations", - "version": "1.8.4", + "version": "1.8.5", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "just-diff": "^6.0.2", diff --git a/packages/contentstack-bulk-operations/package.json b/packages/contentstack-bulk-operations/package.json index d38cabe92..54bddf2b3 100644 --- a/packages/contentstack-bulk-operations/package.json +++ b/packages/contentstack-bulk-operations/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-bulk-operations", - "version": "1.2.3", + "version": "1.2.4", "description": "Contentstack CLI plugin for bulk operations", "author": "Contentstack CLI", "homepage": "https://github.com/contentstack/cli-plugins/tree/main/packages/contentstack-bulk-operations", @@ -21,7 +21,7 @@ ], "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@contentstack/delivery-sdk": "^5.4.0", "@contentstack/management": "^1.30.3", "lodash": "^4.18.1", diff --git a/packages/contentstack-bulk-publish/README.md b/packages/contentstack-bulk-publish/README.md index 2f1726f24..a0604a625 100644 --- a/packages/contentstack-bulk-publish/README.md +++ b/packages/contentstack-bulk-publish/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-cm-bulk-publish $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-bulk-publish/1.12.1 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-bulk-publish/1.13.0 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -29,11 +29,11 @@ USAGE # Commands -* [`csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]`](#csdx-cmassetspublish--a-value---retry-failed-value--e-value---folder-uid-value---bulk-publish-value--c-value--y---locales-value---branch-value---delivery-token-value---source-env-value) +* [`csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--backup-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]`](#csdx-cmassetspublish--a-value---retry-failed-value--e-value---folder-uid-value---backup-dir-value---bulk-publish-value--c-value--y---locales-value---branch-value---delivery-token-value---source-env-value) * [`csdx cm:assets:unpublish`](#csdx-cmassetsunpublish) * [`csdx cm:bulk-publish`](#csdx-cmbulk-publish) * [`csdx cm:entries:update-and-publish [-a ] [--retry-failed ] [--bulk-publish ] [--content-types ] [-t ] [-e ] [-c ] [-y] [--locales ] [--branch ]`](#csdx-cmentriesupdate-and-publish--a-value---retry-failed-value---bulk-publish-value---content-types-value--t-value--e-value--c-value--y---locales-value---branch-value) -* [`csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]`](#csdx-cmassetspublish--a-value---retry-failed-value--e-value---folder-uid-value---bulk-publish-value--c-value--y---locales-value---branch-value---delivery-token-value---source-env-value) +* [`csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--backup-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]`](#csdx-cmassetspublish--a-value---retry-failed-value--e-value---folder-uid-value---backup-dir-value---bulk-publish-value--c-value--y---locales-value---branch-value---delivery-token-value---source-env-value) * [`csdx cm:bulk-publish:clear`](#csdx-cmbulk-publishclear) * [`csdx cm:bulk-publish:configure`](#csdx-cmbulk-publishconfigure) * [`csdx cm:bulk-publish:cross-publish [-a ] [--retry-failed ] [--bulk-publish ] [--content-type ] [--locales ] [--source-env ] [--environments ] [--delivery-token ] [-c ] [-y] [--branch ] [--onlyAssets] [--onlyEntries] [--include-variants]`](#csdx-cmbulk-publishcross-publish--a-value---retry-failed-value---bulk-publish-value---content-type-value---locales-value---source-env-value---environments-value---delivery-token-value--c-value--y---branch-value---onlyassets---onlyentries---include-variants) @@ -55,14 +55,15 @@ USAGE * [`csdx cm:stacks:publish-revert`](#csdx-cmstackspublish-revert) * [`csdx csdx cm:stacks:unpublish [-a ] [-e ] [-c ] [-y] [--locale ] [--branch ] [--retry-failed ] [--bulk-unpublish ] [--content-type ] [--delivery-token ] [--only-assets] [--only-entries]`](#csdx-csdx-cmstacksunpublish--a-value--e-value--c-value--y---locale-value---branch-value---retry-failed-value---bulk-unpublish-value---content-type-value---delivery-token-value---only-assets---only-entries) -## `csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]` +## `csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--backup-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]` Publish assets to the specified environments ``` USAGE - $ csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--bulk-publish - ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ] + $ csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--backup-dir + ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token + ] [--source-env ] FLAGS -B, --branch= [default: main] The name of the branch where you want to perform the bulk publish @@ -80,6 +81,10 @@ FLAGS locales, specify the codes separated by spaces. -y, --yes Set it to true to process the command with the current configuration. --api-version= API version to be used. Values [Default: 3, Nested Reference Publishing: 3.2]. + --backup-dir= (optional) Path to the import backup directory. When set, each imported asset is + published only to the environments and locales it was published to in the source stack + (read from the backup’s publish details and asset UID mapping), with asset-scan gating + applied. Intended for the post-import publish flow. --bulk-publish= [default: true] Set this flag to use Contentstack’s Bulk Publish APIs. It is true, by default. --delivery-token= The delivery token of the source environment. @@ -139,6 +144,12 @@ EXAMPLES Using --stack-api-key flag $ csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY] + + + + Using --backup-dir flag (publish imported assets to their original environments after asset scanning) + + $ csdx cm:assets:publish --backup-dir [PATH TO IMPORT BACKUP DIR] --stack-api-key [STACK API KEY] ``` _See code: [src/commands/cm/assets/publish.js](https://github.com/contentstack/cli/blob/main/packages/contentstack-bulk-publish/src/commands/cm/assets/publish.js)_ @@ -311,15 +322,15 @@ EXAMPLES $ csdx cm:entries:update-and-publish --content-types [CONTENT TYPE 1] [CONTENT TYPE 2] -e [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE 1] [LOCALE 2] --stack-api-key [STACK API KEY] ``` -## `csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]` +## `csdx cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] [--backup-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] [--source-env ]` Publish assets to the specified environments ``` USAGE $ csdx cm:bulk-publish:assets cm:assets:publish [-a ] [--retry-failed ] [-e ] [--folder-uid ] - [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] [--delivery-token ] - [--source-env ] + [--backup-dir ] [--bulk-publish ] [-c ] [-y] [--locales ] [--branch ] + [--delivery-token ] [--source-env ] FLAGS -B, --branch= [default: main] The name of the branch where you want to perform the bulk publish @@ -337,6 +348,10 @@ FLAGS locales, specify the codes separated by spaces. -y, --yes Set it to true to process the command with the current configuration. --api-version= API version to be used. Values [Default: 3, Nested Reference Publishing: 3.2]. + --backup-dir= (optional) Path to the import backup directory. When set, each imported asset is + published only to the environments and locales it was published to in the source stack + (read from the backup’s publish details and asset UID mapping), with asset-scan gating + applied. Intended for the post-import publish flow. --bulk-publish= [default: true] Set this flag to use Contentstack’s Bulk Publish APIs. It is true, by default. --delivery-token= The delivery token of the source environment. @@ -396,6 +411,12 @@ EXAMPLES Using --stack-api-key flag $ csdx cm:assets:publish --environments [ENVIRONMENT 1] [ENVIRONMENT 2] --locales [LOCALE] --stack-api-key [STACK API KEY] + + + + Using --backup-dir flag (publish imported assets to their original environments after asset scanning) + + $ csdx cm:assets:publish --backup-dir [PATH TO IMPORT BACKUP DIR] --stack-api-key [STACK API KEY] ``` ## `csdx cm:bulk-publish:clear` diff --git a/packages/contentstack-bulk-publish/package.json b/packages/contentstack-bulk-publish/package.json index 6c4f3bdb3..b67c31605 100644 --- a/packages/contentstack-bulk-publish/package.json +++ b/packages/contentstack-bulk-publish/package.json @@ -1,13 +1,13 @@ { "name": "@contentstack/cli-cm-bulk-publish", "description": "Contentstack CLI plugin for bulk publish actions", - "version": "1.12.2", + "version": "1.13.0", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-config": "~1.21.0", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-config": "~1.21.1", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "dotenv": "^16.6.1", diff --git a/packages/contentstack-cli-cm-regex-validate/package.json b/packages/contentstack-cli-cm-regex-validate/package.json index 9283d45bb..d4d3557d3 100644 --- a/packages/contentstack-cli-cm-regex-validate/package.json +++ b/packages/contentstack-cli-cm-regex-validate/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-regex-validate", "description": "Validate Fields with Regex Property of Content Type and Global Field in a Stack", - "version": "1.0.2", + "version": "1.0.3", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli-cm-regex-validate/issues", "devDependencies": { @@ -66,7 +66,7 @@ }, "dependencies": { "@contentstack/cli-command": "^1.8.5", - "@contentstack/cli-utilities": "^1.19.0", + "@contentstack/cli-utilities": "^1.19.1", "@contentstack/management": "^1.30.4", "cli-table3": "^0.6.5", "cli-ux": "^6.0.9", diff --git a/packages/contentstack-cli-tsgen/package.json b/packages/contentstack-cli-tsgen/package.json index 74fa09c8c..311deba2d 100644 --- a/packages/contentstack-cli-tsgen/package.json +++ b/packages/contentstack-cli-tsgen/package.json @@ -1,12 +1,12 @@ { "name": "contentstack-cli-tsgen", "description": "Generate TypeScript typings from a Stack.", - "version": "4.10.2", + "version": "4.10.3", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli-plugins/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@contentstack/types-generator": "^3.10.2" }, "devDependencies": { diff --git a/packages/contentstack-clone/README.md b/packages/contentstack-clone/README.md index a24edc651..665f31bd7 100644 --- a/packages/contentstack-clone/README.md +++ b/packages/contentstack-clone/README.md @@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-clone/1.21.8 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-clone/1.21.11 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-clone/package.json b/packages/contentstack-clone/package.json index 3f4911dc6..5df132650 100644 --- a/packages/contentstack-clone/package.json +++ b/packages/contentstack-clone/package.json @@ -1,15 +1,15 @@ { "name": "@contentstack/cli-cm-clone", "description": "Contentstack stack clone plugin", - "version": "1.21.10", + "version": "1.21.11", "author": "Contentstack", "bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues", "dependencies": { "@colors/colors": "^1.6.0", - "@contentstack/cli-cm-export": "~1.26.0", - "@contentstack/cli-cm-import": "~1.34.0", + "@contentstack/cli-cm-export": "~1.27.0", + "@contentstack/cli-cm-import": "~1.35.0", "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "chalk": "^4.1.2", "inquirer": "8.2.7", diff --git a/packages/contentstack-content-type/README.md b/packages/contentstack-content-type/README.md index 454362922..45ee71cf6 100644 --- a/packages/contentstack-content-type/README.md +++ b/packages/contentstack-content-type/README.md @@ -44,7 +44,7 @@ $ npm install -g contentstack-cli-content-type $ csdx COMMAND running command... $ csdx (--version) -contentstack-cli-content-type/1.5.1 darwin-arm64 node-v22.21.1 +contentstack-cli-content-type/1.5.4 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-content-type/package.json b/packages/contentstack-content-type/package.json index 13180fcac..762ec1660 100644 --- a/packages/contentstack-content-type/package.json +++ b/packages/contentstack-content-type/package.json @@ -6,7 +6,7 @@ "bugs": "https://github.com/contentstack/cli-plugins/issues", "dependencies": { "@contentstack/cli-command": "^1.8.5", - "@contentstack/cli-utilities": "^1.19.0", + "@contentstack/cli-utilities": "^1.19.1", "axios": "^1.18.1", "cli-ux": "^6.0.9", "diff": "^9.0.0", diff --git a/packages/contentstack-export-to-csv/README.md b/packages/contentstack-export-to-csv/README.md index 675c62160..8d1579a0e 100644 --- a/packages/contentstack-export-to-csv/README.md +++ b/packages/contentstack-export-to-csv/README.md @@ -23,7 +23,7 @@ $ npm install -g @contentstack/cli-cm-export-to-csv $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-export-to-csv/1.12.5 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-export-to-csv/1.12.8 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-export-to-csv/package.json b/packages/contentstack-export-to-csv/package.json index 77d832d29..73214ab74 100644 --- a/packages/contentstack-export-to-csv/package.json +++ b/packages/contentstack-export-to-csv/package.json @@ -1,12 +1,12 @@ { "name": "@contentstack/cli-cm-export-to-csv", "description": "Export entries, taxonomies, terms, or organization users to CSV", - "version": "1.12.7", + "version": "1.12.8", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "fast-csv": "^4.3.6", "inquirer": "8.2.7", diff --git a/packages/contentstack-export/README.md b/packages/contentstack-export/README.md index e587ae4e2..53ddf68d3 100755 --- a/packages/contentstack-export/README.md +++ b/packages/contentstack-export/README.md @@ -24,7 +24,7 @@ $ npm install -g @contentstack/cli-cm-export $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-export/1.25.2 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-export/1.27.0 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index 768acdd66..c3b72d680 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -1,13 +1,13 @@ { "name": "@contentstack/cli-cm-export", "description": "Contentstack CLI plugin to export content from stack", - "version": "1.26.0", + "version": "1.27.0", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", - "@contentstack/cli-variants": "~1.6.1", + "@contentstack/cli-utilities": "~1.19.1", + "@contentstack/cli-variants": "~1.6.2", "@oclif/core": "^4.11.4", "async": "^3.2.6", "big-json": "^3.2.0", @@ -22,7 +22,7 @@ }, "devDependencies": { "@contentstack/cli-auth": "~1.8.5", - "@contentstack/cli-config": "~1.21.0", + "@contentstack/cli-config": "~1.21.1", "@contentstack/cli-dev-dependencies": "^1.3.1", "@oclif/plugin-help": "^6.2.28", "@oclif/test": "^4.1.18", diff --git a/packages/contentstack-external-migrate/package.json b/packages/contentstack-external-migrate/package.json index 24c2aff43..e693f0112 100644 --- a/packages/contentstack-external-migrate/package.json +++ b/packages/contentstack-external-migrate/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-external-migrate", - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.7", "description": "Migrate from external source to Contentstack", "author": "Contentstack", "license": "MIT", @@ -23,7 +23,7 @@ }, "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@contentstack/json-rte-serializer": "~2.1.0", "@contentstack/marketplace-sdk": "~1.5.3", "@oclif/core": "^4.8.0", diff --git a/packages/contentstack-import-setup/README.md b/packages/contentstack-import-setup/README.md index b7f0f9884..7fcf07388 100644 --- a/packages/contentstack-import-setup/README.md +++ b/packages/contentstack-import-setup/README.md @@ -23,7 +23,7 @@ $ npm install -g @contentstack/cli-cm-import-setup $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-import-setup/1.8.5 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-import-setup/1.8.8 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-import-setup/package.json b/packages/contentstack-import-setup/package.json index 6f3e03a1c..4d3c7d480 100644 --- a/packages/contentstack-import-setup/package.json +++ b/packages/contentstack-import-setup/package.json @@ -1,12 +1,12 @@ { "name": "@contentstack/cli-cm-import-setup", "description": "Contentstack CLI plugin to setup the mappers and configurations for the import command", - "version": "1.8.7", + "version": "1.8.8", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "big-json": "^3.2.0", "chalk": "^4.1.2", diff --git a/packages/contentstack-import/README.md b/packages/contentstack-import/README.md index eb49bcea3..19c133211 100644 --- a/packages/contentstack-import/README.md +++ b/packages/contentstack-import/README.md @@ -24,7 +24,7 @@ $ npm install -g @contentstack/cli-cm-import $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-import/1.33.4 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-import/1.35.0 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-import/package.json b/packages/contentstack-import/package.json index 396725b14..5d929524e 100644 --- a/packages/contentstack-import/package.json +++ b/packages/contentstack-import/package.json @@ -1,14 +1,14 @@ { "name": "@contentstack/cli-cm-import", "description": "Contentstack CLI plugin to import content into stack", - "version": "1.34.0", + "version": "1.35.0", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-audit": "~1.20.0", + "@contentstack/cli-audit": "~1.21.0", "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", - "@contentstack/cli-variants": "~1.6.1", + "@contentstack/cli-utilities": "~1.19.1", + "@contentstack/cli-variants": "~1.6.2", "@oclif/core": "^4.11.4", "big-json": "^3.2.0", "bluebird": "^3.7.2", diff --git a/packages/contentstack-migrate-rte/package.json b/packages/contentstack-migrate-rte/package.json index 5b66a127c..ca9abb13c 100644 --- a/packages/contentstack-migrate-rte/package.json +++ b/packages/contentstack-migrate-rte/package.json @@ -1,14 +1,14 @@ { "name": "@contentstack/cli-cm-migrate-rte", "description": "Contentstack CLI plugin to migrate HTML RTE to JSON RTE", - "version": "1.7.3", + "version": "1.7.4", "author": "contentstack", "bugs": { "url": "https://github.com/contentstack/cli-plugins/issues" }, "dependencies": { "@contentstack/cli-command": "1.8.5", - "@contentstack/cli-utilities": "1.19.0", + "@contentstack/cli-utilities": "1.19.1", "@contentstack/json-rte-serializer": "~2.1.0", "@oclif/core": "^4.12.0", "@oclif/plugin-help": "^6.2.53", diff --git a/packages/contentstack-migration/README.md b/packages/contentstack-migration/README.md index a2ba7d349..caa67d5fb 100644 --- a/packages/contentstack-migration/README.md +++ b/packages/contentstack-migration/README.md @@ -21,7 +21,7 @@ $ npm install -g @contentstack/cli-migration $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-migration/1.12.4 darwin-arm64 node-v22.21.1 +@contentstack/cli-migration/1.12.6 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-migration/package.json b/packages/contentstack-migration/package.json index 31e949af9..eb2b92437 100644 --- a/packages/contentstack-migration/package.json +++ b/packages/contentstack-migration/package.json @@ -1,11 +1,11 @@ { "name": "@contentstack/cli-migration", - "version": "1.12.5", + "version": "1.12.6", "author": "@contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "async": "^3.2.6", "callsites": "^3.1.0", diff --git a/packages/contentstack-query-export/package.json b/packages/contentstack-query-export/package.json index 8e111e94f..bcfbba299 100644 --- a/packages/contentstack-query-export/package.json +++ b/packages/contentstack-query-export/package.json @@ -1,14 +1,14 @@ { "name": "@contentstack/cli-cm-export-query", "description": "Contentstack CLI plugin to export content from stack", - "version": "1.0.6", + "version": "1.0.7", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-cm-export": "~1.26.0", + "@contentstack/cli-cm-export": "~1.27.0", "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", - "@contentstack/cli-variants": "~1.6.1", + "@contentstack/cli-utilities": "~1.19.1", + "@contentstack/cli-variants": "~1.6.2", "@oclif/core": "^4.11.4", "async": "^3.2.6", "big-json": "^3.2.0", diff --git a/packages/contentstack-seed/README.md b/packages/contentstack-seed/README.md index 6004904c5..48ac38f64 100644 --- a/packages/contentstack-seed/README.md +++ b/packages/contentstack-seed/README.md @@ -15,7 +15,7 @@ $ npm install -g @contentstack/cli-cm-seed $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-seed/1.15.7 darwin-arm64 node-v22.21.1 +@contentstack/cli-cm-seed/1.15.10 darwin-arm64 node-v24.18.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-seed/package.json b/packages/contentstack-seed/package.json index 6caa4768c..2cf29abbb 100644 --- a/packages/contentstack-seed/package.json +++ b/packages/contentstack-seed/package.json @@ -1,13 +1,13 @@ { "name": "@contentstack/cli-cm-seed", "description": "create a Stack from existing content types, entries, assets, etc.", - "version": "1.15.9", + "version": "1.15.10", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-cm-import": "~1.34.0", + "@contentstack/cli-cm-import": "~1.35.0", "@contentstack/cli-command": "~1.8.5", - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "inquirer": "8.2.7", "mkdirp": "^1.0.4", "tar": "^7.5.19", diff --git a/packages/contentstack-variants/package.json b/packages/contentstack-variants/package.json index c3f86bdb4..ea97d776a 100644 --- a/packages/contentstack-variants/package.json +++ b/packages/contentstack-variants/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-variants", - "version": "1.6.1", + "version": "1.6.2", "description": "Variants plugin", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -28,7 +28,7 @@ "typescript": "^5.8.3" }, "dependencies": { - "@contentstack/cli-utilities": "~1.19.0", + "@contentstack/cli-utilities": "~1.19.1", "@oclif/core": "^4.11.4", "lodash": "^4.18.1", "mkdirp": "^1.0.4", From 5b228f229f6d9e7a21a0e77b2e90aead15d45045 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 Aug 2026 18:57:24 +0530 Subject: [PATCH 39/44] updated lock file --- pnpm-lock.yaml | 73 +++++++------------------------------------------- 1 file changed, 9 insertions(+), 64 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 564879518..5f04a04ee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14732,8 +14732,8 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0)(typescript@5.9.3) '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 15.7.0(eslint@10.8.0) eslint-plugin-perfectionist: 2.11.0(eslint@10.8.0)(typescript@5.9.3) @@ -14814,8 +14814,8 @@ snapshots: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo: 0.49.0(eslint@10.8.0) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) eslint-plugin-jsdoc: 50.8.0(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 17.24.0(eslint@10.8.0)(typescript@5.9.3) @@ -14895,21 +14895,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3(supports-color@8.1.1) - eslint: 10.8.0 - get-tsconfig: 4.14.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.17 - unrs-resolver: 1.12.2 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) - transitivePeerDependencies: - - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0): dependencies: '@nolyfill/is-core-module': 1.0.39 @@ -14921,7 +14906,7 @@ snapshots: tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14936,17 +14921,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) - eslint: 10.8.0 - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) - transitivePeerDependencies: - - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: debug: 3.2.7 @@ -14969,14 +14943,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -15039,35 +15013,6 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 10.8.0 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) - hasown: 2.0.4 - is-core-module: 2.16.2 - is-glob: 4.0.3 - minimatch: 3.1.5 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.10 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 @@ -15126,7 +15071,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15137,7 +15082,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 From ab4e9058510c67cd6de4bd84f7b8b9c66afaffa8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 Aug 2026 19:04:48 +0530 Subject: [PATCH 40/44] updated lock file --- .talismanrc | 2 +- pnpm-lock.yaml | 278 ++++++++++++++++++++++++++----------------------- 2 files changed, 151 insertions(+), 129 deletions(-) diff --git a/.talismanrc b/.talismanrc index 5438b59b4..1ecf6680c 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,5 +1,5 @@ fileignoreconfig: - filename: pnpm-lock.yaml - checksum: 3b163065d39a7c186f29077bd7d89ee1dcd159a3e20e58e29273f0b7b22c26a1 + checksum: 90ca97ef1a06fb5b7d8071f1317e079de6a34fce91559f70f80d9d958b5a834e version: '1.0' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0335b9422..ff53ea72f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^1.11.1 version: 1.11.1(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) adm-zip: specifier: ^0.6.0 version: 0.6.0 @@ -133,8 +133,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@20.19.43) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -206,17 +206,17 @@ importers: packages/contentstack-bootstrap: dependencies: '@contentstack/cli-cm-seed': - specifier: ~1.15.9 + specifier: ~1.15.10 version: link:../contentstack-seed '@contentstack/cli-command': specifier: ~1.8.5 version: 1.8.5(@types/node@14.18.63) '@contentstack/cli-config': - specifier: ~1.21.0 - version: 1.21.0(@types/node@14.18.63) + specifier: ~1.21.1 + version: 1.21.1(@types/node@14.18.63) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@14.18.63)(debug@4.4.3) + specifier: ~1.19.1 + version: 1.19.1(@types/node@14.18.63) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -273,8 +273,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@22.20.1) + specifier: ~1.19.1 + version: 1.19.1(@types/node@22.20.1) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -328,8 +328,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@20.19.43) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) '@contentstack/delivery-sdk': specifier: ^5.4.0 version: 5.5.1 @@ -431,11 +431,11 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-config': - specifier: ~1.21.0 - version: 1.21.0(@types/node@22.20.1) + specifier: ~1.21.1 + version: 1.21.1(@types/node@22.20.1) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@22.20.1) + specifier: ~1.19.1 + version: 1.19.1(@types/node@22.20.1) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -483,8 +483,8 @@ importers: specifier: ^1.8.5 version: 1.8.5(@types/node@18.19.130) '@contentstack/cli-utilities': - specifier: ^1.19.0 - version: 1.19.0(@types/node@18.19.130) + specifier: ^1.19.1 + version: 1.19.1(@types/node@18.19.130) '@contentstack/management': specifier: ^1.30.4 version: 1.31.1 @@ -586,8 +586,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@22.20.1) + specifier: ~1.19.1 + version: 1.19.1(@types/node@22.20.1) '@contentstack/types-generator': specifier: ^3.10.2 version: 3.10.2(graphql@16.14.2) @@ -641,17 +641,17 @@ importers: specifier: ^1.6.0 version: 1.6.0 '@contentstack/cli-cm-export': - specifier: ~1.26.0 + specifier: ~1.27.0 version: link:../contentstack-export '@contentstack/cli-cm-import': - specifier: ~1.34.0 + specifier: ~1.35.0 version: link:../contentstack-import '@contentstack/cli-command': specifier: ~1.8.5 version: 1.8.5(@types/node@14.18.63) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@14.18.63)(debug@4.4.3) + specifier: ~1.19.1 + version: 1.19.1(@types/node@14.18.63) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -729,8 +729,8 @@ importers: specifier: ^1.8.5 version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-utilities': - specifier: ^1.19.0 - version: 1.19.0(@types/node@22.20.1) + specifier: ^1.19.1 + version: 1.19.1(@types/node@22.20.1) axios: specifier: ^1.18.1 version: 1.19.0(debug@4.4.3) @@ -814,10 +814,10 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@22.20.1) + specifier: ~1.19.1 + version: 1.19.1(@types/node@22.20.1) '@contentstack/cli-variants': - specifier: ~1.6.1 + specifier: ~1.6.2 version: link:../contentstack-variants '@oclif/core': specifier: ^4.11.4 @@ -857,8 +857,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@22.20.1) '@contentstack/cli-config': - specifier: ~1.21.0 - version: 1.21.0(@types/node@22.20.1) + specifier: ~1.21.1 + version: 1.21.1(@types/node@22.20.1) '@contentstack/cli-dev-dependencies': specifier: ^1.3.1 version: 1.3.1 @@ -926,8 +926,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@20.19.43) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -993,8 +993,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@20.19.43) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) '@contentstack/json-rte-serializer': specifier: ~2.1.0 version: 2.1.0 @@ -1066,16 +1066,16 @@ importers: packages/contentstack-import: dependencies: '@contentstack/cli-audit': - specifier: ~1.20.0 + specifier: ~1.21.0 version: link:../contentstack-audit '@contentstack/cli-command': specifier: ~1.8.5 version: 1.8.5(@types/node@14.18.63)(debug@4.4.3) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@14.18.63)(debug@4.4.3) + specifier: ~1.19.1 + version: 1.19.1(@types/node@14.18.63)(debug@4.4.3) '@contentstack/cli-variants': - specifier: ~1.6.1 + specifier: ~1.6.2 version: link:../contentstack-variants '@oclif/core': specifier: ^4.11.4 @@ -1166,8 +1166,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@14.18.63) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@14.18.63)(debug@4.4.3) + specifier: ~1.19.1 + version: 1.19.1(@types/node@14.18.63) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -1240,10 +1240,10 @@ importers: dependencies: '@contentstack/cli-command': specifier: 1.8.5 - version: 1.8.5(@types/node@18.19.130) + version: 1.8.5(@types/node@14.18.63) '@contentstack/cli-utilities': - specifier: 1.19.0 - version: 1.19.0(@types/node@18.19.130) + specifier: 1.19.1 + version: 1.19.1(@types/node@14.18.63) '@contentstack/json-rte-serializer': specifier: ~2.1.0 version: 2.1.0 @@ -1312,8 +1312,8 @@ importers: specifier: ~1.8.5 version: 1.8.5(@types/node@14.18.63) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@14.18.63)(debug@4.4.3) + specifier: ~1.19.1 + version: 1.19.1(@types/node@14.18.63) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -1388,16 +1388,16 @@ importers: packages/contentstack-query-export: dependencies: '@contentstack/cli-cm-export': - specifier: ~1.26.0 + specifier: ~1.27.0 version: link:../contentstack-export '@contentstack/cli-command': specifier: ~1.8.5 version: 1.8.5(@types/node@20.19.43) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) '@contentstack/cli-variants': - specifier: ~1.6.1 + specifier: ~1.6.2 version: link:../contentstack-variants '@oclif/core': specifier: ^4.11.4 @@ -1503,14 +1503,14 @@ importers: packages/contentstack-seed: dependencies: '@contentstack/cli-cm-import': - specifier: ~1.34.0 + specifier: ~1.35.0 version: link:../contentstack-import '@contentstack/cli-command': specifier: ~1.8.5 version: 1.8.5(@types/node@14.18.63) '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@14.18.63)(debug@4.4.3) + specifier: ~1.19.1 + version: 1.19.1(@types/node@14.18.63) inquirer: specifier: 8.2.7 version: 8.2.7(@types/node@14.18.63) @@ -1570,8 +1570,8 @@ importers: packages/contentstack-variants: dependencies: '@contentstack/cli-utilities': - specifier: ~1.19.0 - version: 1.19.0(@types/node@20.19.43) + specifier: ~1.19.1 + version: 1.19.1(@types/node@20.19.43) '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -2317,8 +2317,8 @@ packages: resolution: {integrity: sha512-gwg04KOYZUDdr5vgjRfGSdIVIPZ/Qfnyv0tG+9ihpZwVl7JxsJ9Rpg8olAtw1oy+LqjYZzc6cx0uaCFO3c/Skg==} engines: {node: '>=22.0.0'} - '@contentstack/cli-config@1.21.0': - resolution: {integrity: sha512-vxSuMf7qjAzxrAIkdsYX4YGDOxq1dlX0RMFwLbzMuEBINOuxGr6WsryXxeR/5QCkD1kb07qh2puq4FxBjPn4HQ==} + '@contentstack/cli-config@1.21.1': + resolution: {integrity: sha512-T7acgZVgIv2Q7rkSpuYqHHHJJ1RyS4tmaegQFAamQbUfrVOz/eYf3Oo3YXYDQn8lFPdmr5zHAbVykLZIp1PLBQ==} engines: {node: '>=22.0.0'} '@contentstack/cli-dev-dependencies@1.3.1': @@ -2329,8 +2329,8 @@ packages: engines: {node: '>=22.0.0'} hasBin: true - '@contentstack/cli-utilities@1.19.0': - resolution: {integrity: sha512-QkQ2KakgMLYt2oa7bov1RHb4N1YjJqGqGDkh3oiTfgN+c5FvqoyaRUrngQCjefat3GLd2MY2SOmgILcBCghTpw==} + '@contentstack/cli-utilities@1.19.1': + resolution: {integrity: sha512-gf7nWljHzsEIV+sOZra4pY3M5wojad2Iy3gPDFKl/F2VeH6GynGERVyz7hKjQgefBBitV6MGZKNIN+TVtR4gVA==} '@contentstack/core@1.5.0': resolution: {integrity: sha512-GTNjPYqi49EFpdGp+6UGdY55OoM48Rc7UyCUTYPdzcmrvYlmiL0JKqyozShEVaqrDMdaNBQZu8PRvRA7TpDVNA==} @@ -3054,42 +3054,36 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.2.2': resolution: {integrity: sha512-B5G/zJdHaoJn9vD50eGHWkiWfmq8Uhi3IiLPJTzmZTrAalk1bztUikSXo0qga18ibE0IXboyeMUnhPjhAJ45wQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.2.2': resolution: {integrity: sha512-6mC/awzKka8W6EoekjegpfGkjz8jXWDX63pqu/HYVpyKtZfu65Jsh4QAH3Kej3CAv/c1oGX7psTmFEbr0mDxLA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.2.2': resolution: {integrity: sha512-412MX9fJLdA1IK28EZnc8jYv2HRTleOZgfLQumJ5zy7OeJLZlg/CETwFaXjNmGVxG51cFHpKLqb5LKvBC+HsHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.2.2': resolution: {integrity: sha512-Q/+HI/ToJafZ1iCqGgVQXUEkIjufHCTF0gBQ2a5o3cg7GJ2h0qyq3nvvSmU+bGda2/7ygXpTY4TM6gO9OhQ0ZA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [glibc] '@rolldown/binding-linux-x64-musl@1.2.2': resolution: {integrity: sha512-ZKp/w41n6wCvxzxQHtQSbuphfX3Y4cCvbjkKHusrLx4lh+JWLTU7StSltO/DKARISzbj368d+qUaCjI8K2wzXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [musl] '@rolldown/binding-openharmony-arm64@1.2.2': resolution: {integrity: sha512-pxE6xD4KS3eAROkKK5yrhB9/3+vhlhVGMvlQLbdpzrBGDbKrnzx3RLwPaHvasLo6jgaiBLn7e04Df9C4tYhjmA==} @@ -3195,79 +3189,66 @@ packages: resolution: {integrity: sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.62.4': resolution: {integrity: sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.62.4': resolution: {integrity: sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.62.4': resolution: {integrity: sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.62.4': resolution: {integrity: sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.62.4': resolution: {integrity: sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.62.4': resolution: {integrity: sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.62.4': resolution: {integrity: sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.62.4': resolution: {integrity: sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.62.4': resolution: {integrity: sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.62.4': resolution: {integrity: sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.62.4': resolution: {integrity: sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.62.4': resolution: {integrity: sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.62.4': resolution: {integrity: sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==} @@ -3878,61 +3859,51 @@ packages: resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} cpu: [arm64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.12.2': resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} cpu: [arm64] os: [linux] - libc: [musl] '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} cpu: [loong64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-loong64-musl@1.12.2': resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} cpu: [loong64] os: [linux] - libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} cpu: [ppc64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} cpu: [riscv64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} cpu: [riscv64] os: [linux] - libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} cpu: [s390x] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.12.2': resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} cpu: [x64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.12.2': resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} cpu: [x64] os: [linux] - libc: [musl] '@unrs/resolver-binding-openharmony-arm64@1.12.2': resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} @@ -6848,28 +6819,24 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] lightningcss-linux-arm64-musl@1.33.0: resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] lightningcss-linux-x64-gnu@1.33.0: resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] lightningcss-linux-x64-musl@1.33.0: resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] lightningcss-win32-arm64-msvc@1.33.0: resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} @@ -10145,7 +10112,7 @@ snapshots: '@contentstack/cli-auth@1.8.5(@types/node@22.20.1)': dependencies: '@contentstack/cli-command': 1.8.5(@types/node@22.20.1) - '@contentstack/cli-utilities': 1.19.0(@types/node@22.20.1) + '@contentstack/cli-utilities': 1.19.1(@types/node@22.20.1) '@oclif/core': 4.13.3 otplib: 12.0.1 transitivePeerDependencies: @@ -10155,7 +10122,7 @@ snapshots: '@contentstack/cli-command@1.8.5(@types/node@14.18.63)': dependencies: - '@contentstack/cli-utilities': 1.19.0(@types/node@14.18.63) + '@contentstack/cli-utilities': 1.19.1(@types/node@14.18.63) '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -10165,7 +10132,7 @@ snapshots: '@contentstack/cli-command@1.8.5(@types/node@14.18.63)(debug@4.4.3)': dependencies: - '@contentstack/cli-utilities': 1.19.0(@types/node@14.18.63)(debug@4.4.3) + '@contentstack/cli-utilities': 1.19.1(@types/node@14.18.63)(debug@4.4.3) '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -10175,7 +10142,7 @@ snapshots: '@contentstack/cli-command@1.8.5(@types/node@18.19.130)': dependencies: - '@contentstack/cli-utilities': 1.19.0(@types/node@18.19.130) + '@contentstack/cli-utilities': 1.19.1(@types/node@18.19.130) '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -10185,7 +10152,7 @@ snapshots: '@contentstack/cli-command@1.8.5(@types/node@20.19.43)': dependencies: - '@contentstack/cli-utilities': 1.19.0(@types/node@20.19.43) + '@contentstack/cli-utilities': 1.19.1(@types/node@20.19.43) '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -10195,7 +10162,7 @@ snapshots: '@contentstack/cli-command@1.8.5(@types/node@22.20.1)': dependencies: - '@contentstack/cli-utilities': 1.19.0(@types/node@22.20.1) + '@contentstack/cli-utilities': 1.19.1(@types/node@22.20.1) '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -10203,10 +10170,10 @@ snapshots: - debug - supports-color - '@contentstack/cli-config@1.21.0(@types/node@14.18.63)': + '@contentstack/cli-config@1.21.1(@types/node@14.18.63)': dependencies: '@contentstack/cli-command': 1.8.5(@types/node@14.18.63) - '@contentstack/cli-utilities': 1.19.0(@types/node@14.18.63) + '@contentstack/cli-utilities': 1.19.1(@types/node@14.18.63) '@contentstack/utils': 1.9.1 '@oclif/core': 4.13.3 transitivePeerDependencies: @@ -10214,10 +10181,10 @@ snapshots: - debug - supports-color - '@contentstack/cli-config@1.21.0(@types/node@22.20.1)': + '@contentstack/cli-config@1.21.1(@types/node@22.20.1)': dependencies: '@contentstack/cli-command': 1.8.5(@types/node@22.20.1) - '@contentstack/cli-utilities': 1.19.0(@types/node@22.20.1) + '@contentstack/cli-utilities': 1.19.1(@types/node@22.20.1) '@contentstack/utils': 1.9.1 '@oclif/core': 4.13.3 transitivePeerDependencies: @@ -10238,7 +10205,7 @@ snapshots: dependencies: '@apollo/client': 3.14.1(graphql@16.14.2) '@contentstack/cli-command': 1.8.5(@types/node@20.19.43) - '@contentstack/cli-utilities': 1.19.0(@types/node@20.19.43) + '@contentstack/cli-utilities': 1.19.1(@types/node@20.19.43) '@oclif/core': 4.13.3 '@oclif/plugin-help': 6.2.56 '@rollup/plugin-commonjs': 28.0.9(rollup@4.62.4) @@ -10272,7 +10239,7 @@ snapshots: - tslib - typescript - '@contentstack/cli-utilities@1.19.0(@types/node@14.18.63)': + '@contentstack/cli-utilities@1.19.1(@types/node@14.18.63)': dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) @@ -10310,7 +10277,7 @@ snapshots: - debug - supports-color - '@contentstack/cli-utilities@1.19.0(@types/node@14.18.63)(debug@4.4.3)': + '@contentstack/cli-utilities@1.19.1(@types/node@14.18.63)(debug@4.4.3)': dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) @@ -10348,7 +10315,7 @@ snapshots: - debug - supports-color - '@contentstack/cli-utilities@1.19.0(@types/node@18.19.130)': + '@contentstack/cli-utilities@1.19.1(@types/node@18.19.130)': dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) @@ -10386,7 +10353,7 @@ snapshots: - debug - supports-color - '@contentstack/cli-utilities@1.19.0(@types/node@20.19.43)': + '@contentstack/cli-utilities@1.19.1(@types/node@20.19.43)': dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) @@ -10424,7 +10391,7 @@ snapshots: - debug - supports-color - '@contentstack/cli-utilities@1.19.0(@types/node@22.20.1)': + '@contentstack/cli-utilities@1.19.1(@types/node@22.20.1)': dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) @@ -11095,16 +11062,16 @@ snapshots: '@inquirer/prompts@7.10.1': dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@18.19.130) - '@inquirer/confirm': 5.1.21(@types/node@18.19.130) - '@inquirer/editor': 4.2.23(@types/node@18.19.130) - '@inquirer/expand': 4.0.23(@types/node@18.19.130) - '@inquirer/input': 4.3.1(@types/node@18.19.130) - '@inquirer/number': 3.0.23(@types/node@18.19.130) - '@inquirer/password': 4.0.23(@types/node@18.19.130) - '@inquirer/rawlist': 4.1.11(@types/node@18.19.130) - '@inquirer/search': 3.2.2(@types/node@18.19.130) - '@inquirer/select': 4.4.2(@types/node@18.19.130) + '@inquirer/checkbox': 4.3.2(@types/node@14.18.63) + '@inquirer/confirm': 5.1.21(@types/node@14.18.63) + '@inquirer/editor': 4.2.23(@types/node@14.18.63) + '@inquirer/expand': 4.0.23(@types/node@14.18.63) + '@inquirer/input': 4.3.1(@types/node@14.18.63) + '@inquirer/number': 3.0.23(@types/node@14.18.63) + '@inquirer/password': 4.0.23(@types/node@14.18.63) + '@inquirer/rawlist': 4.1.11(@types/node@14.18.63) + '@inquirer/search': 3.2.2(@types/node@14.18.63) + '@inquirer/select': 4.4.2(@types/node@14.18.63) '@inquirer/prompts@7.10.1(@types/node@14.18.63)': dependencies: @@ -14771,8 +14738,8 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0)(typescript@5.9.3) '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 15.7.0(eslint@10.8.0) eslint-plugin-perfectionist: 2.11.0(eslint@10.8.0)(typescript@5.9.3) @@ -14853,8 +14820,8 @@ snapshots: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo: 0.49.0(eslint@10.8.0) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) eslint-plugin-jsdoc: 50.8.0(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 17.24.0(eslint@10.8.0)(typescript@5.9.3) @@ -14934,6 +14901,21 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3(supports-color@8.1.1) + eslint: 10.8.0 + get-tsconfig: 4.14.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.17 + unrs-resolver: 1.12.2 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + transitivePeerDependencies: + - supports-color + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0): dependencies: '@nolyfill/is-core-module': 1.0.39 @@ -14945,7 +14927,7 @@ snapshots: tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14960,6 +14942,17 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) + eslint: 10.8.0 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: debug: 3.2.7 @@ -14982,14 +14975,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -15052,6 +15045,35 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 10.8.0 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + hasown: 2.0.4 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.10 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 @@ -15110,7 +15132,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15121,7 +15143,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 From 846f33e45f9b30235ce89b2c0147995e17871b97 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 6 Aug 2026 13:32:28 +0530 Subject: [PATCH 41/44] style(bulk-operations): fix prettier lint error in bulk-assets imports Co-Authored-By: Claude Opus 5 (1M context) --- .../src/commands/cm/stacks/bulk-assets.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts index eb44b6fdf..868f324c2 100644 --- a/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts +++ b/packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-assets.ts @@ -3,13 +3,7 @@ import * as path from 'path'; import { flags, handleAndLogError, log, FlagInput } from '@contentstack/cli-utilities'; -import { - AssetPublishData, - BulkOperationResult, - ResourceType, - OperationType, - CsAssetsFlags, -} from '../../../interfaces'; +import { AssetPublishData, BulkOperationResult, ResourceType, OperationType, CsAssetsFlags } from '../../../interfaces'; import { BaseBulkCommand } from '../../../base-bulk-command'; import { $t, From 4e79b8f8cda4a49de7ca89b031ff60a7c8ba6572 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 6 Aug 2026 15:47:55 +0530 Subject: [PATCH 42/44] updated lock file --- .talismanrc | 2 +- pnpm-lock.yaml | 543 ++++--------------------------------------------- 2 files changed, 35 insertions(+), 510 deletions(-) diff --git a/.talismanrc b/.talismanrc index f7785b2ad..5954e5dfd 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,7 +1,7 @@ fileignoreconfig: - filename: pnpm-lock.yaml - checksum: 51ec134ce9a9e713df06b682b6ab6183c95f6cc68253db267081011d0d303d7c + checksum: 649aae748e3ae8c157439dc6c7c9ea402cc19b4dab7ca64b7e4d839d1375df53 - filename: packages/contentstack-audit/src/audit-base-command.ts checksum: b706ea114a3cb5e4c0e7e163f32ceffa3356a6b0766bf5b8fe387c3c72f44c36 - filename: packages/contentstack-audit/src/types/content-types.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 096953d1e..10639f084 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,19 +37,11 @@ importers: specifier: ^1.11.1 version: 1.11.2(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) - adm-zip: - specifier: ^0.5.18 - version: 0.5.18 -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) adm-zip: specifier: ^0.6.0 version: 0.6.0 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 chalk: specifier: ^5.6.2 version: 5.6.2 @@ -197,13 +189,8 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@20.19.43) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -278,29 +265,17 @@ importers: packages/contentstack-bootstrap: dependencies: '@contentstack/cli-cm-seed': -<<<<<<< HEAD specifier: ~2.0.0-beta.25 -======= - specifier: ~1.15.10 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-seed '@contentstack/cli-command': specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@18.19.130) '@contentstack/cli-config': -<<<<<<< HEAD specifier: ~2.0.0-beta.15 version: 2.0.0-beta.15(@types/node@18.19.130) '@contentstack/cli-utilities': specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@18.19.130) -======= - specifier: ~1.21.1 - version: 1.21.1(@types/node@14.18.63) - '@contentstack/cli-utilities': - specifier: ~1.19.1 - version: 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -360,13 +335,8 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@22.20.1) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@22.20.1) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -423,18 +393,13 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@20.19.43) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/delivery-sdk': - specifier: ^5.2.0 + specifier: ^5.4.0 version: 5.5.2 '@contentstack/management': - specifier: ^1.30.2 + specifier: ^1.30.3 version: 1.31.1 lodash: specifier: 4.18.1 @@ -525,76 +490,16 @@ importers: specifier: ~6.0.3 version: 6.0.3 -<<<<<<< HEAD -======= - packages/contentstack-bulk-publish: - dependencies: - '@contentstack/cli-command': - specifier: ~1.8.5 - version: 1.8.5(@types/node@22.20.1) - '@contentstack/cli-config': - specifier: ~1.21.1 - version: 1.21.1(@types/node@22.20.1) - '@contentstack/cli-utilities': - specifier: ~1.19.1 - version: 1.19.1(@types/node@22.20.1) - '@oclif/core': - specifier: ^4.11.4 - version: 4.13.3 - chalk: - specifier: ^4.1.2 - version: 4.1.2 - dotenv: - specifier: ^16.6.1 - version: 16.6.1 - inquirer: - specifier: 8.2.7 - version: 8.2.7(@types/node@22.20.1) - lodash: - specifier: 4.18.1 - version: 4.18.1 - winston: - specifier: ^3.19.0 - version: 3.19.0 - devDependencies: - '@oclif/test': - specifier: ^4.1.18 - version: 4.1.21(@oclif/core@4.13.3) - chai: - specifier: ^4.5.0 - version: 4.5.0 - eslint: - specifier: ^10.5.0 - version: 10.8.0 - eslint-config-oclif: - specifier: ^6.0.62 - version: 6.0.179(eslint@10.8.0)(typescript@6.0.3) - mocha: - specifier: ^10.8.2 - version: 10.8.2 - nyc: - specifier: ^15.1.0 - version: 15.1.0 - oclif: - specifier: ^4.23.8 - version: 4.23.29(@types/node@22.20.1) - ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 packages/contentstack-cli-cm-regex-validate: dependencies: '@contentstack/cli-command': specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@18.19.130) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@18.19.130) -======= - specifier: ^1.19.1 - version: 1.19.1(@types/node@18.19.130) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/management': - specifier: ^1.30.2 + specifier: ^1.30.4 version: 1.31.1 cli-table3: specifier: ^0.6.5 @@ -685,13 +590,8 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@22.20.1) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@22.20.1) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/types-generator': specifier: ^3.10.2 version: 3.10.2(graphql@16.14.2) @@ -745,29 +645,17 @@ importers: specifier: ^1.6.0 version: 1.6.0 '@contentstack/cli-cm-export': -<<<<<<< HEAD specifier: ~2.0.0-beta.25 version: link:../contentstack-export '@contentstack/cli-cm-import': specifier: ~2.0.0-beta.25 -======= - specifier: ~1.27.0 - version: link:../contentstack-export - '@contentstack/cli-cm-import': - specifier: ~1.35.0 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-import '@contentstack/cli-command': specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@18.19.130) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@18.19.130) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -845,7 +733,6 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@22.20.1) '@types/diff2html': @@ -866,19 +753,6 @@ importers: axios: specifier: ^1.18.1 version: 1.19.0(debug@4.4.3) -======= - specifier: ^1.19.1 - version: 1.19.1(@types/node@22.20.1) - axios: - specifier: ^1.18.1 - version: 1.19.0(debug@4.4.3) - cli-ux: - specifier: ^6.0.9 - version: 6.0.9 - diff: - specifier: ^9.0.0 - version: 9.0.0 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 diff2html: specifier: ^3.4.56 version: 3.4.56 @@ -907,21 +781,12 @@ importers: '@oclif/plugin-help': specifier: ^6.2.49 version: 6.2.56 - '@types/diff2html': - specifier: ^3.0.3 - version: 3.0.3 '@types/jest': specifier: ^29.5.14 version: 29.5.14 '@types/node': specifier: ^22.19.19 version: 22.20.1 - '@types/table': - specifier: ^6.3.2 - version: 6.3.2 - '@types/tmp': - specifier: ^0.2.6 - version: 0.2.6 eslint: specifier: ^10.5.0 version: 10.8.0 @@ -956,17 +821,10 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@22.20.1) '@contentstack/cli-variants': specifier: ~2.0.0-beta.20 -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@22.20.1) - '@contentstack/cli-variants': - specifier: ~1.6.2 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-variants '@oclif/core': specifier: ^4.11.4 @@ -1006,16 +864,11 @@ importers: specifier: ~2.0.0-beta.17 version: 2.0.0-beta.17(@types/node@22.20.1) '@contentstack/cli-config': -<<<<<<< HEAD specifier: ~2.0.0-beta.15 version: 2.0.0-beta.15(@types/node@22.20.1) -======= - specifier: ~1.21.1 - version: 1.21.1(@types/node@22.20.1) '@contentstack/cli-dev-dependencies': specifier: ^1.3.1 version: 1.3.1 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/plugin-help': specifier: ^6.2.49 version: 6.2.56 @@ -1080,16 +933,11 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@20.19.43) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) '@inquirer/prompts': specifier: ^7.0.0 version: 7.10.1(@types/node@20.19.43) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -1149,13 +997,8 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@20.19.43) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/json-rte-serializer': specifier: ~2.1.0 version: 2.1.0 @@ -1251,27 +1094,16 @@ importers: specifier: ~1.0.0-beta.8 version: link:../contentstack-asset-management '@contentstack/cli-audit': -<<<<<<< HEAD specifier: ~2.0.0-beta.16 -======= - specifier: ~1.21.0 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-audit '@contentstack/cli-command': specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@14.18.63)(debug@4.4.3) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@14.18.63)(debug@4.4.3) '@contentstack/cli-variants': specifier: ~2.0.0-beta.20 -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@14.18.63)(debug@4.4.3) - '@contentstack/cli-variants': - specifier: ~1.6.2 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-variants '@oclif/core': specifier: ^4.11.4 @@ -1368,13 +1200,8 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@14.18.63) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@14.18.63)(debug@4.4.3) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -1464,19 +1291,11 @@ importers: packages/contentstack-migrate-rte: dependencies: '@contentstack/cli-command': -<<<<<<< HEAD specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@22.20.1) -======= - specifier: 1.8.5 - version: 1.8.5(@types/node@14.18.63) - '@contentstack/cli-utilities': - specifier: 1.19.1 - version: 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/json-rte-serializer': specifier: ~2.1.0 version: 2.1.0 @@ -1548,13 +1367,8 @@ importers: specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@14.18.63) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@14.18.63)(debug@4.4.3) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -1635,27 +1449,16 @@ importers: specifier: ~1.0.0-beta.8 version: link:../contentstack-asset-management '@contentstack/cli-cm-export': -<<<<<<< HEAD specifier: ~2.0.0-beta.25 -======= - specifier: ~1.27.0 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-export '@contentstack/cli-command': specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@20.19.43) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) '@contentstack/cli-variants': specifier: ~2.0.0-beta.20 -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) - '@contentstack/cli-variants': - specifier: ~1.6.2 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-variants '@oclif/core': specifier: ^4.11.4 @@ -1758,23 +1561,14 @@ importers: packages/contentstack-seed: dependencies: '@contentstack/cli-cm-import': -<<<<<<< HEAD specifier: ~2.0.0-beta.25 -======= - specifier: ~1.35.0 ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 version: link:../contentstack-import '@contentstack/cli-command': specifier: ~2.0.0-beta.11 version: 2.0.0-beta.11(@types/node@18.19.130) '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@18.19.130) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 inquirer: specifier: 12.11.1 version: 12.11.1(@types/node@18.19.130) @@ -1840,13 +1634,8 @@ importers: packages/contentstack-variants: dependencies: '@contentstack/cli-utilities': -<<<<<<< HEAD specifier: ~2.0.0-beta.12 version: 2.0.0-beta.12(@types/node@20.19.43) -======= - specifier: ~1.19.1 - version: 1.19.1(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': specifier: ^4.11.4 version: 4.13.3 @@ -2582,19 +2371,17 @@ packages: resolution: {integrity: sha512-GlkxqptxgzHPlpyS0yOKWTNDGNom4UpSlwqZgkWe5tWZJLqmml52u6GgzAvB6byDuzdwbaUzIO8+uwnfYuPmkQ==} engines: {node: '>=22.0.0'} -<<<<<<< HEAD '@contentstack/cli-command@2.0.0-beta.11': resolution: {integrity: sha512-WJXoaW8XbnseAkR8fWQeHclF9WhDyNZhdT4L9hPhkasOSNpsNdk7EVVKZUvY4l81XfR2Nq7b8WOC/q1Cbz8FXw==} -======= - '@contentstack/cli-config@1.21.1': - resolution: {integrity: sha512-T7acgZVgIv2Q7rkSpuYqHHHJJ1RyS4tmaegQFAamQbUfrVOz/eYf3Oo3YXYDQn8lFPdmr5zHAbVykLZIp1PLBQ==} ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 engines: {node: '>=22.0.0'} '@contentstack/cli-config@2.0.0-beta.15': resolution: {integrity: sha512-JXgLHc/KLrgzPY4lng11jL2xSTgT0Cl8/zKmVnSuj7in5HKCwWPNdyvbBNtk3C7QkxnR+3OpHqgOVMjVbbtyFg==} engines: {node: '>=22.0.0'} + '@contentstack/cli-dev-dependencies@1.3.1': + resolution: {integrity: sha512-RQuCGQxBdZ+aNhOMwt/VMpz/9AL2PwIFz7H9rUS6BzPOe6G4RjmzFLXi/gnyECbyLoIgyGGXTjlz8NQ0oapp7Q==} + '@contentstack/cli-launch@1.11.2': resolution: {integrity: sha512-CiGheBsLPq9Y7/KsO2z/Il1atvXILjtElUaLooX79XPb8N2PELEXHGaIlmtWB0oYUTWS+kNoC+cgHXsEAk6vzw==} engines: {node: '>=22.0.0'} @@ -3552,9 +3339,15 @@ packages: '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/git-diff@2.0.7': + resolution: {integrity: sha512-hipFAUcmf3c+45+Y8+J/xk7gT+0HBuT3O8OTtrnoP6R9gI0r2xESZNdYiA0pj7kQyPCwmkgbnxmfwQ9Ld2lZLQ==} + '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/hogan.js@3.0.5': + resolution: {integrity: sha512-/uRaY3HGPWyLqOyhgvW9Aa43BNnLZrNeQxl2p8wqId4UHMfPKolSB+U7BlZyO1ng7MkLnyEAItsBzCG0SDhqrA==} + '@types/http-cache-semantics@4.2.0': resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} @@ -9771,13 +9564,8 @@ snapshots: '@contentstack/cli-auth@2.0.0-beta.17(@types/node@22.20.1)': dependencies: -<<<<<<< HEAD '@contentstack/cli-command': 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@22.20.1) -======= - '@contentstack/cli-command': 1.8.5(@types/node@22.20.1) - '@contentstack/cli-utilities': 1.19.1(@types/node@22.20.1) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': 4.13.3 otplib: 12.0.1 transitivePeerDependencies: @@ -9787,11 +9575,7 @@ snapshots: '@contentstack/cli-command@1.8.6(@types/node@20.19.43)': dependencies: -<<<<<<< HEAD '@contentstack/cli-utilities': 1.19.1(@types/node@20.19.43) -======= - '@contentstack/cli-utilities': 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -9801,11 +9585,7 @@ snapshots: '@contentstack/cli-command@2.0.0-beta.11(@types/node@14.18.63)': dependencies: -<<<<<<< HEAD '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@14.18.63) -======= - '@contentstack/cli-utilities': 1.19.1(@types/node@14.18.63)(debug@4.4.3) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -9815,11 +9595,7 @@ snapshots: '@contentstack/cli-command@2.0.0-beta.11(@types/node@14.18.63)(debug@4.4.3)': dependencies: -<<<<<<< HEAD '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@14.18.63)(debug@4.4.3) -======= - '@contentstack/cli-utilities': 1.19.1(@types/node@18.19.130) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -9829,11 +9605,7 @@ snapshots: '@contentstack/cli-command@2.0.0-beta.11(@types/node@18.19.130)': dependencies: -<<<<<<< HEAD '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@18.19.130) -======= - '@contentstack/cli-utilities': 1.19.1(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -9843,11 +9615,7 @@ snapshots: '@contentstack/cli-command@2.0.0-beta.11(@types/node@20.19.43)': dependencies: -<<<<<<< HEAD '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@20.19.43) -======= - '@contentstack/cli-utilities': 1.19.1(@types/node@22.20.1) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@oclif/core': 4.13.3 contentstack: 3.27.1 transitivePeerDependencies: @@ -9855,7 +9623,6 @@ snapshots: - debug - supports-color -<<<<<<< HEAD '@contentstack/cli-command@2.0.0-beta.11(@types/node@22.20.1)': dependencies: '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@22.20.1) @@ -9870,12 +9637,6 @@ snapshots: dependencies: '@contentstack/cli-command': 2.0.0-beta.11(@types/node@18.19.130) '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@18.19.130) -======= - '@contentstack/cli-config@1.21.1(@types/node@14.18.63)': - dependencies: - '@contentstack/cli-command': 1.8.5(@types/node@14.18.63) - '@contentstack/cli-utilities': 1.19.1(@types/node@14.18.63) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/utils': 1.9.1 '@oclif/core': 4.13.3 transitivePeerDependencies: @@ -9883,17 +9644,10 @@ snapshots: - debug - supports-color -<<<<<<< HEAD '@contentstack/cli-config@2.0.0-beta.15(@types/node@22.20.1)': dependencies: '@contentstack/cli-command': 2.0.0-beta.11(@types/node@22.20.1) '@contentstack/cli-utilities': 2.0.0-beta.12(@types/node@22.20.1) -======= - '@contentstack/cli-config@1.21.1(@types/node@22.20.1)': - dependencies: - '@contentstack/cli-command': 1.8.5(@types/node@22.20.1) - '@contentstack/cli-utilities': 1.19.1(@types/node@22.20.1) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/utils': 1.9.1 '@oclif/core': 4.13.3 transitivePeerDependencies: @@ -9901,14 +9655,19 @@ snapshots: - debug - supports-color + '@contentstack/cli-dev-dependencies@1.3.1': + dependencies: + '@oclif/core': 4.13.3 + '@oclif/test': 4.1.21(@oclif/core@4.13.3) + fancy-test: 2.0.42 + lodash: 4.18.1 + transitivePeerDependencies: + - supports-color + '@contentstack/cli-launch@1.11.2(@types/node@20.19.43)(tslib@2.8.1)(typescript@5.9.3)': dependencies: '@apollo/client': 3.14.1(graphql@16.14.2) -<<<<<<< HEAD '@contentstack/cli-command': 1.8.6(@types/node@20.19.43) -======= - '@contentstack/cli-command': 1.8.5(@types/node@20.19.43) ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/cli-utilities': 1.19.1(@types/node@20.19.43) '@oclif/core': 4.13.3 '@oclif/plugin-help': 6.2.56 @@ -9943,123 +9702,6 @@ snapshots: - tslib - typescript -<<<<<<< HEAD -======= - '@contentstack/cli-utilities@1.19.1(@types/node@14.18.63)': - dependencies: - '@contentstack/management': 1.30.4(debug@4.4.3) - '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) - '@contentstack/utils': 1.9.1 - '@oclif/core': 4.13.3 - axios: 1.19.0(debug@4.4.3) - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-progress: 3.12.0 - cli-table: 0.3.11 - conf: 10.2.0 - dotenv: 16.6.1 - figures: 3.2.0 - inquirer: 8.2.7(@types/node@14.18.63) - inquirer-search-checkbox: 1.0.0 - inquirer-search-list: 1.2.6 - js-yaml: 5.2.3 - klona: 2.0.6 - lodash: 4.18.1 - mkdirp: 1.0.4 - open: 8.4.2 - ora: 5.4.1 - papaparse: 5.5.4 - recheck: 4.4.5 - rxjs: 6.6.7 - short-uuid: 6.0.3 - traverse: 0.6.11 - tty-table: 4.2.3 - unique-string: 2.0.0 - uuid: 14.0.1 - winston: 3.19.0 - xdg-basedir: 4.0.0 - transitivePeerDependencies: - - '@types/node' - - debug - - supports-color - - '@contentstack/cli-utilities@1.19.1(@types/node@14.18.63)(debug@4.4.3)': - dependencies: - '@contentstack/management': 1.30.4(debug@4.4.3) - '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) - '@contentstack/utils': 1.9.1 - '@oclif/core': 4.13.3 - axios: 1.19.0(debug@4.4.3) - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-progress: 3.12.0 - cli-table: 0.3.11 - conf: 10.2.0 - dotenv: 16.6.1 - figures: 3.2.0 - inquirer: 8.2.7(@types/node@14.18.63) - inquirer-search-checkbox: 1.0.0 - inquirer-search-list: 1.2.6 - js-yaml: 5.2.3 - klona: 2.0.6 - lodash: 4.18.1 - mkdirp: 1.0.4 - open: 8.4.2 - ora: 5.4.1 - papaparse: 5.5.4 - recheck: 4.4.5 - rxjs: 6.6.7 - short-uuid: 6.0.3 - traverse: 0.6.11 - tty-table: 4.2.3 - unique-string: 2.0.0 - uuid: 14.0.1 - winston: 3.19.0 - xdg-basedir: 4.0.0 - transitivePeerDependencies: - - '@types/node' - - debug - - supports-color - - '@contentstack/cli-utilities@1.19.1(@types/node@18.19.130)': - dependencies: - '@contentstack/management': 1.30.4(debug@4.4.3) - '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) - '@contentstack/utils': 1.9.1 - '@oclif/core': 4.13.3 - axios: 1.19.0(debug@4.4.3) - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-progress: 3.12.0 - cli-table: 0.3.11 - conf: 10.2.0 - dotenv: 16.6.1 - figures: 3.2.0 - inquirer: 8.2.7(@types/node@18.19.130) - inquirer-search-checkbox: 1.0.0 - inquirer-search-list: 1.2.6 - js-yaml: 5.2.3 - klona: 2.0.6 - lodash: 4.18.1 - mkdirp: 1.0.4 - open: 8.4.2 - ora: 5.4.1 - papaparse: 5.5.4 - recheck: 4.4.5 - rxjs: 6.6.7 - short-uuid: 6.0.3 - traverse: 0.6.11 - tty-table: 4.2.3 - unique-string: 2.0.0 - uuid: 14.0.1 - winston: 3.19.0 - xdg-basedir: 4.0.0 - transitivePeerDependencies: - - '@types/node' - - debug - - supports-color - ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@contentstack/cli-utilities@1.19.1(@types/node@20.19.43)': dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) @@ -10098,11 +9740,7 @@ snapshots: - debug - supports-color -<<<<<<< HEAD '@contentstack/cli-utilities@2.0.0-beta.12(@types/node@14.18.63)': -======= - '@contentstack/cli-utilities@1.19.1(@types/node@22.20.1)': ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 dependencies: '@contentstack/management': 1.30.4(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.4(debug@4.4.3) @@ -10947,22 +10585,6 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 -<<<<<<< HEAD -======= - '@inquirer/prompts@7.10.1': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@14.18.63) - '@inquirer/confirm': 5.1.21(@types/node@14.18.63) - '@inquirer/editor': 4.2.23(@types/node@14.18.63) - '@inquirer/expand': 4.0.23(@types/node@14.18.63) - '@inquirer/input': 4.3.1(@types/node@14.18.63) - '@inquirer/number': 3.0.23(@types/node@14.18.63) - '@inquirer/password': 4.0.23(@types/node@14.18.63) - '@inquirer/rawlist': 4.1.11(@types/node@14.18.63) - '@inquirer/search': 3.2.2(@types/node@14.18.63) - '@inquirer/select': 4.4.2(@types/node@14.18.63) - ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 '@inquirer/prompts@7.10.1(@types/node@14.18.63)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@14.18.63) @@ -11957,10 +11579,14 @@ snapshots: '@types/jsonfile': 6.1.4 '@types/node': 20.19.43 + '@types/git-diff@2.0.7': {} + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 20.19.43 + '@types/hogan.js@3.0.5': {} + '@types/http-cache-semantics@4.2.0': {} '@types/http-errors@2.0.5': {} @@ -14126,8 +13752,8 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0)(typescript@5.9.3) '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 15.7.0(eslint@10.8.0) eslint-plugin-perfectionist: 2.11.0(eslint@10.8.0)(typescript@5.9.3) @@ -14198,8 +13824,8 @@ snapshots: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint-config-xo: 0.49.0(eslint@10.8.0) eslint-config-xo-space: 0.35.0(eslint@10.8.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) eslint-plugin-jsdoc: 50.8.0(eslint@10.8.0) eslint-plugin-mocha: 10.5.0(eslint@10.8.0) eslint-plugin-n: 17.24.0(eslint@10.8.0)(typescript@5.9.3) @@ -14269,21 +13895,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3(supports-color@8.1.1) - eslint: 10.8.0 - get-tsconfig: 4.14.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.17 - unrs-resolver: 1.12.2 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) - transitivePeerDependencies: - - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0): dependencies: '@nolyfill/is-core-module': 1.0.39 @@ -14295,35 +13906,10 @@ snapshots: tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) transitivePeerDependencies: - supports-color -<<<<<<< HEAD -======= - eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@4.9.5) - eslint: 10.8.0 - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) - eslint: 10.8.0 - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) - transitivePeerDependencies: - - supports-color - ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 eslint-module-utils@2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: debug: 3.2.7 @@ -14346,14 +13932,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.66.0(eslint@10.8.0)(typescript@5.9.3) eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@10.8.0) transitivePeerDependencies: - supports-color @@ -14381,67 +13967,6 @@ snapshots: eslint-utils: 2.1.0 regexpp: 3.2.0 -<<<<<<< HEAD -======= - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 10.8.0 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) - hasown: 2.0.4 - is-core-module: 2.16.2 - is-glob: 4.0.3 - minimatch: 3.1.5 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.10 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@4.9.5) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 10.8.0 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) - hasown: 2.0.4 - is-core-module: 2.16.2 - is-glob: 4.0.3 - minimatch: 3.1.5 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.10 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@10.8.0)(typescript@5.9.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - ->>>>>>> d9406964bb098518c3fac7df67ef9c0f77d3a7d5 eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 @@ -14500,7 +14025,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -14511,7 +14036,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@10.8.0)(typescript@5.9.3))(eslint@10.8.0))(eslint@10.8.0))(eslint@10.8.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@10.8.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 From c5d7d4e04c6e44dcabce5454f7e5555a87bc2be2 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 6 Aug 2026 16:13:07 +0530 Subject: [PATCH 43/44] fix(audit): correct 'detials' typo in ASSET_FIX message The ASSET_FIX message shipped with a misspelling in user-facing output. A regression test in test/unit/messages/index.test.ts guards against it and was failing. Co-Authored-By: Claude Opus 5 (1M context) --- packages/contentstack-audit/src/messages/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contentstack-audit/src/messages/index.ts b/packages/contentstack-audit/src/messages/index.ts index 842b6c759..d5bf41cb5 100644 --- a/packages/contentstack-audit/src/messages/index.ts +++ b/packages/contentstack-audit/src/messages/index.ts @@ -67,7 +67,7 @@ const auditFixMsg = { WF_FIX_MSG: 'Successfully removed the workflow {uid} named {name}.', ENTRY_MANDATORY_FIELD_FIX: `Removing the publish details from the entry with UID '{uid}' in Locale '{locale}'...`, ENTRY_SELECT_FIELD_FIX: `Adding the value '{value}' in the select field of entry UID '{uid}'...`, - ASSET_FIX: `Fixed publish detials for Asset with UID '{uid}'`, + ASSET_FIX: `Fixed publish details for Asset with UID '{uid}'`, FIELD_RULE_FIX_MESSAGE: `Fixed Field Rule '{num}' target of Content-type '{ctUid}`, ASSET_SCAN_STATUS_FIX: `Removed asset with UID '{uid}' (scan status: '{status}') from assets.json.`, ENTRY_ASSET_REF_FIX: `Removed reference to asset '{asset_uid}' from entry '{uid}' field '{field}'.`, From c0b58da7402f59f2dcd334735288ff48db41063c Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 6 Aug 2026 16:13:31 +0530 Subject: [PATCH 44/44] refactor(import): remove unused detectAssetScanning method The private method had no callers. Asset scanning detection is already handled in import-config-handler.ts via config.planStatus['assetsScan'], which feeds assetScanningEnabled and skipAssetsPublish. Keeping a second detection path with a different data source risked drift, and its bare catch reported "not enabled" on any API error. Co-Authored-By: Claude Opus 5 (1M context) --- .../contentstack-import/src/import/module-importer.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/contentstack-import/src/import/module-importer.ts b/packages/contentstack-import/src/import/module-importer.ts index aae55d0b8..930350a18 100755 --- a/packages/contentstack-import/src/import/module-importer.ts +++ b/packages/contentstack-import/src/import/module-importer.ts @@ -194,16 +194,6 @@ class ModuleImporter { log.error(`Audit failed with following error. ${error}`, this.importConfig.context); } } - - private async detectAssetScanning(orgUid: string): Promise { - try { - const orgDetails = await this.managementAPIClient.organization(orgUid).fetch({ include_plan: true }); - const features: Array<{ uid: string; enabled?: boolean }> = orgDetails?.plan?.features || []; - return features.some((f) => (f.uid === 'assetsScan' || f.uid === 'amAssetsScan') && f.enabled === true); - } catch { - return false; - } - } } export default ModuleImporter;