From fde36051ba2918e6992a4d8271dc5a1cc2a899c7 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Tue, 24 Mar 2026 21:11:17 +0530 Subject: [PATCH 1/9] feat: add publishing rules support --- .talismanrc | 18 +- .../contentstack-export/src/config/index.ts | 6 + .../src/export/modules/publishing-rules.ts | 86 ++++++ .../src/types/default-config.ts | 7 + .../contentstack-export/src/types/index.ts | 9 + .../contentstack-import/src/config/index.ts | 8 + .../src/import/modules/base-class.ts | 10 +- .../src/import/modules/publishing-rules.ts | 275 ++++++++++++++++++ .../src/types/default-config.ts | 5 + .../contentstack-import/src/types/index.ts | 7 + .../contentstack-import/src/utils/index.ts | 1 + .../src/utils/publishing-rules-helper.ts | 32 ++ .../src/types/export-config.ts | 8 + 13 files changed, 469 insertions(+), 3 deletions(-) create mode 100644 packages/contentstack-export/src/export/modules/publishing-rules.ts create mode 100644 packages/contentstack-import/src/import/modules/publishing-rules.ts create mode 100644 packages/contentstack-import/src/utils/publishing-rules-helper.ts diff --git a/.talismanrc b/.talismanrc index 3391ac5dd..7a54d723e 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,18 @@ fileignoreconfig: - - filename: pnpm-lock.yaml - checksum: 97cb862682f7dec430f2079ac686bbfec4fc22c080c8d50cf14c4e2249bb8c8c + - filename: packages/contentstack-import/src/config/index.ts + checksum: 541136c45d6a74010e4999389dd9c06a0e6b7b74bea62087d66c50b17e8e5d11 + - filename: packages/contentstack-variants/src/types/export-config.ts + checksum: 5707cf07e6777d31d4730567d861300a94b16b8a97e47fb3d804efb67f214aab + - filename: packages/contentstack-import/src/types/index.ts + checksum: 068079597f11b6460cca4005ca2345d7c2a954dc516a14c51782c631652cd5a3 + - filename: packages/contentstack-export/src/config/index.ts + checksum: 2c811d2bd7b6657b567fd120cfaf05306ca751109c070bf7b49c18d06b211764 + - filename: packages/contentstack-export/src/types/index.ts + checksum: 173b811f93b12da873d5860275a85438d2f78a1c4e387c77ec5246f1c0231da2 + - filename: packages/contentstack-export/src/types/default-config.ts + checksum: 0cc62919207384ec710ea3f8a3445d6e5bd78cc2c5306b9e74aaeec688eb028d + - filename: packages/contentstack-import/src/types/default-config.ts + checksum: 0db51c83ce44e31d51ae881a0f0bfc2cd39cb15bd333fe3b1e9f19292d575d91 + - filename: packages/contentstack-import/src/import/modules/publishing-rules.ts + checksum: 429a803bc18e691db93bae3df1714071d0face6441b82cb938a83e8bf94ae14c version: '1.0' diff --git a/packages/contentstack-export/src/config/index.ts b/packages/contentstack-export/src/config/index.ts index 85aa028fa..e3c4d12a2 100644 --- a/packages/contentstack-export/src/config/index.ts +++ b/packages/contentstack-export/src/config/index.ts @@ -36,6 +36,7 @@ const config: DefaultConfig = { 'content-types', 'custom-roles', 'workflows', + 'publishing-rules', 'personalize', 'entries', 'labels', @@ -86,6 +87,11 @@ const config: DefaultConfig = { fileName: 'workflows.json', invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, globalfields: { dirName: 'global_fields', fileName: 'globalfields.json', diff --git a/packages/contentstack-export/src/export/modules/publishing-rules.ts b/packages/contentstack-export/src/export/modules/publishing-rules.ts new file mode 100644 index 000000000..483189994 --- /dev/null +++ b/packages/contentstack-export/src/export/modules/publishing-rules.ts @@ -0,0 +1,86 @@ +import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; +import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, log } from '@contentstack/cli-utilities'; + +import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { PublishingRulesConfig, ModuleClassParams } from '../../types'; + +export default class ExportPublishingRules extends BaseClass { + private readonly publishingRules: Record> = {}; + private readonly publishingRulesConfig: PublishingRulesConfig; + private publishingRulesFolderPath: string; + private readonly qs: { include_count: boolean; skip?: number }; + + constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { + super({ exportConfig, stackAPIClient }); + this.publishingRulesConfig = exportConfig.modules['publishing-rules']; + this.qs = { include_count: true }; + this.exportConfig.context.module = 'publishing-rules'; + } + + async start(): Promise { + this.publishingRulesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.publishingRulesConfig.dirName, + ); + log.debug(`Publishing rules folder path: ${this.publishingRulesFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.publishingRulesFolderPath); + log.debug('Created publishing rules directory', this.exportConfig.context); + + await this.fetchAllPublishingRules(); + + if (isEmpty(this.publishingRules)) { + log.info('No Publishing Rules found', this.exportConfig.context); + return; + } + + const outPath = pResolve(this.publishingRulesFolderPath, this.publishingRulesConfig.fileName); + fsUtil.writeFile(outPath, this.publishingRules); + log.success( + `Publishing rules exported successfully! Total count: ${Object.keys(this.publishingRules).length}`, + this.exportConfig.context, + ); + } + + private async fetchAllPublishingRules(skip = 0): Promise { + try { + if (skip > 0) { + this.qs.skip = skip; + } + + const data: { items?: Record[]; count?: number } = await this.stack + .workflow() + .publishRule() + .fetchAll(this.qs); + + const items = data.items ?? []; + const total = data.count ?? items.length; + + if (!items.length) { + log.debug('No publishing rules returned for this page', this.exportConfig.context); + return; + } + + for (const rule of items) { + const uid = rule.uid as string | undefined; + if (uid) { + this.publishingRules[uid] = omit(rule, this.publishingRulesConfig.invalidKeys) as Record< + string, + unknown + >; + } + } + + const nextSkip = skip + items.length; + if (nextSkip < total) { + await this.fetchAllPublishingRules(nextSkip); + } + } catch (error: unknown) { + handleAndLogError(error as Error, { ...this.exportConfig.context }); + } + } +} diff --git a/packages/contentstack-export/src/types/default-config.ts b/packages/contentstack-export/src/types/default-config.ts index 12090760c..01cb84c89 100644 --- a/packages/contentstack-export/src/types/default-config.ts +++ b/packages/contentstack-export/src/types/default-config.ts @@ -67,6 +67,13 @@ export default interface DefaultConfig { invalidKeys: string[]; dependencies?: Modules[]; }; + 'publishing-rules': { + dirName: string; + fileName: string; + invalidKeys: string[]; + dependencies?: Modules[]; + limit?: number; + }; globalfields: { dirName: string; fileName: string; diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index ec2118510..fd13364a5 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -46,6 +46,7 @@ export type Modules = | 'content-types' | 'custom-roles' | 'workflows' + | 'publishing-rules' | 'labels' | 'marketplace-apps' | 'taxonomies' @@ -117,6 +118,14 @@ export interface WorkflowConfig { limit?: number; } +export interface PublishingRulesConfig { + dirName: string; + fileName: string; + invalidKeys: string[]; + dependencies?: Modules[]; + limit?: number; +} + export interface CustomRoleConfig { dirName: string; fileName: string; diff --git a/packages/contentstack-import/src/config/index.ts b/packages/contentstack-import/src/config/index.ts index 76b70e112..e8c9e2179 100644 --- a/packages/contentstack-import/src/config/index.ts +++ b/packages/contentstack-import/src/config/index.ts @@ -41,6 +41,7 @@ const config: DefaultConfig = { 'personalize', 'custom-roles', 'workflows', + 'publishing-rules', 'entries', 'variant-entries', 'labels', @@ -88,6 +89,11 @@ const config: DefaultConfig = { fileName: 'workflows.json', invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, assets: { dirName: 'assets', assetBatchLimit: 1, @@ -455,5 +461,7 @@ const config: DefaultConfig = { globalModules: ['webhooks'], entriesPublish: true, }; +export const PUBLISHING_RULES_APPROVERS_SKIP_MSG = + 'Skipping import of publish rule approver(s) (roles/users); reconfigure approvers on the target stack.'; export default config; diff --git a/packages/contentstack-import/src/import/modules/base-class.ts b/packages/contentstack-import/src/import/modules/base-class.ts index a0eb77075..1981f1887 100644 --- a/packages/contentstack-import/src/import/modules/base-class.ts +++ b/packages/contentstack-import/src/import/modules/base-class.ts @@ -51,7 +51,8 @@ export type ApiModuleType = | 'delete-entries' | 'create-taxonomies' | 'create-terms' - | 'import-taxonomy'; + | 'import-taxonomy' + | 'create-publishing-rule'; export type ApiOptions = { uid?: string; @@ -374,6 +375,13 @@ export default abstract class BaseClass { .create({ workflow: apiData as WorkflowData }) .then(onSuccess) .catch(onReject); + case 'create-publishing-rule': + return this.stack + .workflow() + .publishRule() + .create({ publishing_rule: omit(apiData, ['uid']) as any }) + .then(onSuccess) + .catch(onReject); case 'create-custom-role': return this.stack .role() diff --git a/packages/contentstack-import/src/import/modules/publishing-rules.ts b/packages/contentstack-import/src/import/modules/publishing-rules.ts new file mode 100644 index 000000000..ca7734585 --- /dev/null +++ b/packages/contentstack-import/src/import/modules/publishing-rules.ts @@ -0,0 +1,275 @@ +import chalk from 'chalk'; +import values from 'lodash/values'; +import isEmpty from 'lodash/isEmpty'; +import { join } from 'node:path'; + +import BaseClass, { ApiOptions } from './base-class'; +import { PUBLISHING_RULES_APPROVERS_SKIP_MSG } from '../../config'; +import { fsUtil, fileHelper, parseErrorPayload, isDuplicatePublishingRuleError } from '../../utils'; +import { log, handleAndLogError } from '@contentstack/cli-utilities'; +import { ModuleClassParams, PublishingRulesConfig } from '../../types'; + +export default class ImportPublishingRules extends BaseClass { + private readonly mapperDirPath: string; + private readonly publishingRulesFolderPath: string; + private readonly publishingRulesUidMapperPath: string; + private readonly createdPublishingRulesPath: string; + private readonly failedPublishingRulesPath: string; + private readonly publishingRulesConfig: PublishingRulesConfig; + private publishingRules: Record; + private publishingRulesUidMapper: Record; + private readonly createdPublishingRules: Record[]; + private readonly failedPublishingRules: Record[]; + private envUidMapper: Record; + private workflowUidMapper: Record; + private readonly stageUidMapper: Record = {}; + + constructor({ importConfig, stackAPIClient }: ModuleClassParams) { + super({ importConfig, stackAPIClient }); + this.importConfig.context.module = 'publishing-rules'; + this.publishingRulesConfig = importConfig.modules['publishing-rules']; + this.mapperDirPath = join(this.importConfig.backupDir, 'mapper', 'publishing-rules'); + this.publishingRulesFolderPath = join(this.importConfig.backupDir, this.publishingRulesConfig.dirName); + this.publishingRulesUidMapperPath = join(this.mapperDirPath, 'uid-mapping.json'); + this.createdPublishingRulesPath = join(this.mapperDirPath, 'success.json'); + this.failedPublishingRulesPath = join(this.mapperDirPath, 'fails.json'); + this.publishingRules = {}; + this.publishingRulesUidMapper = {}; + this.createdPublishingRules = []; + this.failedPublishingRules = []; + this.envUidMapper = {}; + this.workflowUidMapper = {}; + } + + private static collectOldStageUidToName( + exportedWorkflows: Record, + ): Record { + const map: Record = {}; + for (const workflow of Object.values(exportedWorkflows)) { + for (const stage of workflow.workflow_stages ?? []) { + if (stage.uid && stage.name) { + map[stage.uid] = stage.name; + } + } + } + return map; + } + + /** + * Returns `{ noSuccessMsg: true }` if any rule failed, so the import command skips the generic stack success line. + */ + async start(): Promise<{ noSuccessMsg: true } | void> { + const rulesFilePath = join(this.publishingRulesFolderPath, this.publishingRulesConfig.fileName); + + if (!fileHelper.fileExistsSync(rulesFilePath)) { + log.info(`No Publishing Rules found - '${rulesFilePath}'`, this.importConfig.context); + return; + } + + this.publishingRules = (fsUtil.readFile(rulesFilePath, true) as Record) ?? {}; + if (isEmpty(this.publishingRules)) { + log.info('No Publishing Rules found', this.importConfig.context); + return; + } + + await fsUtil.makeDirectory(this.mapperDirPath); + + this.publishingRulesUidMapper = this.readUidMappingFile(this.publishingRulesUidMapperPath); + this.envUidMapper = this.readMapper('environments'); + this.workflowUidMapper = this.readMapper('workflows'); + + await this.buildStageUidMapper(); + await this.importPublishingRules(); + + if (this.createdPublishingRules?.length) { + fsUtil.writeFile(this.createdPublishingRulesPath, this.createdPublishingRules); + } + if (this.failedPublishingRules?.length) { + fsUtil.writeFile(this.failedPublishingRulesPath, this.failedPublishingRules); + } + + const successCount = this.createdPublishingRules.length; + const failCount = this.failedPublishingRules.length; + + if (failCount > 0 && successCount === 0) { + log.error( + `Publishing rules import failed! ${failCount} rule(s) could not be imported. Check '${this.failedPublishingRulesPath}' for details.`, + this.importConfig.context, + ); + } else if (failCount > 0) { + log.warn( + `Publishing rules import completed with errors. Imported: ${successCount}, Failed: ${failCount}. Check '${this.failedPublishingRulesPath}' for details.`, + this.importConfig.context, + ); + } else { + log.success('Publishing rules have been imported successfully!', this.importConfig.context); + } + + if (failCount > 0) { + return { noSuccessMsg: true }; + } + } + + private readUidMappingFile(path: string): Record { + return fileHelper.fileExistsSync(path) ? (fsUtil.readFile(path, true) as Record) ?? {} : {}; + } + + private readMapper(moduleDir: string): Record { + const p = join(this.importConfig.backupDir, 'mapper', moduleDir, 'uid-mapping.json'); + return this.readUidMappingFile(p); + } + + private async importPublishingRules(): Promise { + const apiContent = values(this.publishingRules) as Record[]; + log.debug(`Importing ${apiContent.length} publishing rule(s)`, this.importConfig.context); + + const onSuccess = ({ response, apiData }: { response: { uid: string }; apiData: { uid: string } }) => { + const { uid } = apiData; + this.createdPublishingRules.push(response as unknown as Record); + this.publishingRulesUidMapper[uid] = response.uid; + log.success(`Publishing rule imported successfully (${uid} → ${response.uid})`, this.importConfig.context); + fsUtil.writeFile(this.publishingRulesUidMapperPath, this.publishingRulesUidMapper); + }; + + const onReject = ({ error, apiData }: { error: unknown; apiData: Record }) => { + const uid = apiData.uid as string; + const parsed = parseErrorPayload(error); + + if (isDuplicatePublishingRuleError(parsed, error)) { + log.info(`Publishing rule '${uid}' already exists`, this.importConfig.context); + return; + } + + this.failedPublishingRules.push(apiData); + handleAndLogError( + error as Error, + { ...this.importConfig.context, publishingRuleUid: uid }, + `Publishing rule '${uid}' failed to import`, + ); + }; + + await this.makeConcurrentCall( + { + apiContent, + processName: 'import publishing rules', + apiParams: { + serializeData: this.serializePublishingRules.bind(this), + reject: onReject, + resolve: onSuccess, + entity: 'create-publishing-rule', + includeParamOnCompletion: true, + }, + concurrencyLimit: this.importConfig.fetchConcurrency || 1, + }, + undefined, + false, + ); + } + + private mergeFetchedWorkflowStages( + workflow: { workflow_stages?: { uid?: string; name?: string }[] }, + oldStageUidToName: Record, + ): void { + for (const newStage of workflow.workflow_stages ?? []) { + const oldUid = Object.keys(oldStageUidToName).find((u) => oldStageUidToName[u] === newStage.name); + if (oldUid && newStage.uid) { + this.stageUidMapper[oldUid] = newStage.uid; + } + } + } + + private async buildStageUidMapper(): Promise { + const wf = this.importConfig.modules.workflows as { dirName: string; fileName: string }; + const workflowsFilePath = join(this.importConfig.backupDir, wf.dirName, wf.fileName); + + if (!fileHelper.fileExistsSync(workflowsFilePath)) { + log.debug('No exported workflows file; stage UID mapping skipped', this.importConfig.context); + return; + } + + const exportedWorkflows = fsUtil.readFile(workflowsFilePath, true) as Record< + string, + { workflow_stages?: { uid?: string; name?: string }[] } + > | null; + if (!exportedWorkflows) return; + + const oldStageUidToName = ImportPublishingRules.collectOldStageUidToName(exportedWorkflows); + + for (const newWorkflowUid of Object.values(this.workflowUidMapper)) { + try { + const workflow = await this.stack.workflow(newWorkflowUid as string).fetch(); + this.mergeFetchedWorkflowStages( + workflow as { workflow_stages?: { uid?: string; name?: string }[] }, + oldStageUidToName, + ); + } catch (error: unknown) { + log.debug(`Stage mapping: could not fetch workflow '${newWorkflowUid}'`, this.importConfig.context); + handleAndLogError(error as Error, { ...this.importConfig.context }); + } + } + + log.debug(`Stage UID mapper: ${Object.keys(this.stageUidMapper).length} entr(y/ies)`, this.importConfig.context); + } + + private stripApprovers(rule: Record): void { + if (rule.approvers == null) return; + + const a = rule.approvers as { roles?: unknown[]; users?: unknown[] }; + const hadContent = (Array.isArray(a.roles) && a.roles.length > 0) || (Array.isArray(a.users) && a.users.length > 0); + if (hadContent) { + log.info(chalk.yellow(PUBLISHING_RULES_APPROVERS_SKIP_MSG), this.importConfig.context); + } + rule.approvers = { roles: [], users: [] }; + } + + private remapReference( + rule: Record, + field: 'workflow' | 'environment', + mapper: Record, + ): void { + const current = rule[field] as string | undefined; + if (!current) return; + const mapped = mapper[current] as string | undefined; + if (mapped) { + rule[field] = mapped; + log.debug(`${field} UID remapped`, this.importConfig.context); + } else { + log.debug(`No ${field} mapping for ${current}; leaving as-is`, this.importConfig.context); + } + } + + serializePublishingRules(apiOptions: ApiOptions): ApiOptions { + const rule = apiOptions.apiData as Record; + const ruleUid = rule.uid as string; + + if (ruleUid in this.publishingRulesUidMapper) { + log.info( + `Publishing rule '${ruleUid}' already exists. Skipping it to avoid duplicates!`, + this.importConfig.context, + ); + apiOptions.entity = undefined; + return apiOptions; + } + + const oldUid = ruleUid; + delete rule.uid; + + this.stripApprovers(rule); + this.remapReference(rule, 'workflow', this.workflowUidMapper); + this.remapReference(rule, 'environment', this.envUidMapper); + + if (rule.workflow_stage) { + const stage = rule.workflow_stage as string; + const mappedStage = this.stageUidMapper[stage]; + if (mappedStage) { + rule.workflow_stage = mappedStage; + log.debug('workflow_stage UID remapped', this.importConfig.context); + } else { + log.debug(`No workflow_stage mapping for ${stage}; leaving as-is`, this.importConfig.context); + } + } + + apiOptions.apiData = { ...rule, uid: oldUid }; + return apiOptions; + } +} diff --git a/packages/contentstack-import/src/types/default-config.ts b/packages/contentstack-import/src/types/default-config.ts index aa4867d29..e27968b9b 100644 --- a/packages/contentstack-import/src/types/default-config.ts +++ b/packages/contentstack-import/src/types/default-config.ts @@ -49,6 +49,11 @@ export default interface DefaultConfig { fileName: string; invalidKeys: string[]; }; + 'publishing-rules': { + dirName: string; + fileName: string; + invalidKeys: string[]; + }; assets: { dirName: string; assetBatchLimit: number; diff --git a/packages/contentstack-import/src/types/index.ts b/packages/contentstack-import/src/types/index.ts index ee9062465..8dac29ffa 100644 --- a/packages/contentstack-import/src/types/index.ts +++ b/packages/contentstack-import/src/types/index.ts @@ -46,6 +46,7 @@ export type Modules = | 'content-types' | 'custom-roles' | 'workflows' + | 'publishing-rules' | 'labels' | 'marketplace-apps' | 'taxonomies' @@ -94,6 +95,12 @@ export interface WorkflowConfig { invalidKeys: string[]; } +export interface PublishingRulesConfig { + dirName: string; + fileName: string; + invalidKeys: string[]; +} + export interface CustomRoleConfig { dirName: string; fileName: string; diff --git a/packages/contentstack-import/src/utils/index.ts b/packages/contentstack-import/src/utils/index.ts index fcf452a26..8232acd5d 100644 --- a/packages/contentstack-import/src/utils/index.ts +++ b/packages/contentstack-import/src/utils/index.ts @@ -33,3 +33,4 @@ export { export * from './common-helper'; export * from './log'; export { lookUpTaxonomy, lookUpTerms } from './taxonomies-helper'; +export { parseErrorPayload, isDuplicatePublishingRuleError } from './publishing-rules-helper'; diff --git a/packages/contentstack-import/src/utils/publishing-rules-helper.ts b/packages/contentstack-import/src/utils/publishing-rules-helper.ts new file mode 100644 index 000000000..b7f3b44ec --- /dev/null +++ b/packages/contentstack-import/src/utils/publishing-rules-helper.ts @@ -0,0 +1,32 @@ +/** + * Helpers for publishing rules import (API error shape, duplicate detection). + */ + +export function parseErrorPayload(error: unknown): { + errors?: Record; + error_message?: string; +} | null { + if (!error || typeof error !== 'object') return null; + const e = error as { message?: string; errors?: Record }; + if (e.errors) return e; + if (e.message && typeof e.message === 'string') { + try { + return JSON.parse(e.message) as { errors?: Record; error_message?: string }; + } catch { + return null; + } + } + return null; +} + +export function isDuplicatePublishingRuleError( + parsed: { errors?: Record; error_message?: string } | null, + raw: unknown, +): boolean { + const errors = parsed?.errors ?? (raw as { errors?: Record })?.errors; + if (errors?.name || errors?.['publishing_rule.name'] || errors?.['publish_rule.name']) { + return true; + } + const msg = parsed?.error_message; + return typeof msg === 'string' && /already exists|duplicate/i.test(msg); +} diff --git a/packages/contentstack-variants/src/types/export-config.ts b/packages/contentstack-variants/src/types/export-config.ts index f9336bc96..8b782c2b0 100644 --- a/packages/contentstack-variants/src/types/export-config.ts +++ b/packages/contentstack-variants/src/types/export-config.ts @@ -17,6 +17,7 @@ export type Modules = | 'content-types' | 'custom-roles' | 'workflows' + | 'publishing-rules' | 'labels' | 'marketplace-apps' | 'taxonomies' @@ -88,6 +89,13 @@ export interface DefaultConfig { invalidKeys: string[]; dependencies?: Modules[]; }; + 'publishing-rules': { + dirName: string; + fileName: string; + invalidKeys: string[]; + dependencies?: Modules[]; + limit?: number; + }; globalfields: { dirName: string; fileName: string; From 77ce3f0b31928d53936001d3bfa6e149cccf5a66 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Tue, 24 Mar 2026 21:26:13 +0530 Subject: [PATCH 2/9] chore: add test cases for publishing rules --- .talismanrc | 22 +- .../test/unit/import/modules/locales.test.ts | 5 + .../import/modules/publishing-rules.test.ts | 333 ++++++++++++++++++ .../test/unit/utils/extension-helper.test.ts | 5 + .../utils/publishing-rules-helper.test.ts | 57 +++ 5 files changed, 406 insertions(+), 16 deletions(-) create mode 100644 packages/contentstack-import/test/unit/import/modules/publishing-rules.test.ts create mode 100644 packages/contentstack-import/test/unit/utils/publishing-rules-helper.test.ts diff --git a/.talismanrc b/.talismanrc index 7a54d723e..2444ce1a8 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,18 +1,8 @@ fileignoreconfig: - - filename: packages/contentstack-import/src/config/index.ts - checksum: 541136c45d6a74010e4999389dd9c06a0e6b7b74bea62087d66c50b17e8e5d11 - - filename: packages/contentstack-variants/src/types/export-config.ts - checksum: 5707cf07e6777d31d4730567d861300a94b16b8a97e47fb3d804efb67f214aab - - filename: packages/contentstack-import/src/types/index.ts - checksum: 068079597f11b6460cca4005ca2345d7c2a954dc516a14c51782c631652cd5a3 - - filename: packages/contentstack-export/src/config/index.ts - checksum: 2c811d2bd7b6657b567fd120cfaf05306ca751109c070bf7b49c18d06b211764 - - filename: packages/contentstack-export/src/types/index.ts - checksum: 173b811f93b12da873d5860275a85438d2f78a1c4e387c77ec5246f1c0231da2 - - filename: packages/contentstack-export/src/types/default-config.ts - checksum: 0cc62919207384ec710ea3f8a3445d6e5bd78cc2c5306b9e74aaeec688eb028d - - filename: packages/contentstack-import/src/types/default-config.ts - checksum: 0db51c83ce44e31d51ae881a0f0bfc2cd39cb15bd333fe3b1e9f19292d575d91 - - filename: packages/contentstack-import/src/import/modules/publishing-rules.ts - checksum: 429a803bc18e691db93bae3df1714071d0face6441b82cb938a83e8bf94ae14c + - filename: packages/contentstack-import/test/unit/utils/extension-helper.test.ts + checksum: c5aad4f28fbab6610d955490f061e647714b88f7b8f8d9cc4dbc3b4a10b9e59a + - filename: packages/contentstack-import/test/unit/import/modules/locales.test.ts + checksum: 0085926464eeb17cda0b9fb5a16853ad9c9aec9a42b54161107d0c808347498f + - filename: packages/contentstack-import/test/unit/import/modules/publishing-rules.test.ts + checksum: 0fcbff5dab2f9e594fe2a316c3c96e8d86bcd5d72e7c1f9eb35c0e3458f87817 version: '1.0' diff --git a/packages/contentstack-import/test/unit/import/modules/locales.test.ts b/packages/contentstack-import/test/unit/import/modules/locales.test.ts index fc3631e81..1f5da35cf 100644 --- a/packages/contentstack-import/test/unit/import/modules/locales.test.ts +++ b/packages/contentstack-import/test/unit/import/modules/locales.test.ts @@ -51,6 +51,11 @@ describe('ImportLocales', () => { webhooks: { dirName: 'webhooks', fileName: 'webhooks.json' }, releases: { dirName: 'releases', fileName: 'releases.json', invalidKeys: ['uid'] }, workflows: { dirName: 'workflows', fileName: 'workflows.json', invalidKeys: ['uid'] }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['uid'], + }, assets: { dirName: 'assets', assetBatchLimit: 10, diff --git a/packages/contentstack-import/test/unit/import/modules/publishing-rules.test.ts b/packages/contentstack-import/test/unit/import/modules/publishing-rules.test.ts new file mode 100644 index 000000000..26aa3f4a7 --- /dev/null +++ b/packages/contentstack-import/test/unit/import/modules/publishing-rules.test.ts @@ -0,0 +1,333 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import { join } from 'node:path'; +import ImportPublishingRules from '../../../../src/import/modules/publishing-rules'; +import { ImportConfig } from '../../../../src/types'; +describe('ImportPublishingRules', () => { + const BACKUP = '/test/backup'; + const rulesFile = join(BACKUP, 'workflows', 'publishing-rules.json'); + const workflowsExportFile = join(BACKUP, 'workflows', 'workflows.json'); + const workflowMapperFile = join(BACKUP, 'mapper', 'workflows', 'uid-mapping.json'); + const envMapperFile = join(BACKUP, 'mapper', 'environments', 'uid-mapping.json'); + const publishingMapperFile = join(BACKUP, 'mapper', 'publishing-rules', 'uid-mapping.json'); + + let importPublishingRules: ImportPublishingRules; + let mockStackClient: any; + let mockImportConfig: ImportConfig; + let fsUtilStub: any; + let fileHelperStub: any; + let makeConcurrentCallStub: sinon.SinonStub; + let logStub: { info: sinon.SinonStub; debug: sinon.SinonStub; success: sinon.SinonStub; error: sinon.SinonStub; warn: sinon.SinonStub }; + beforeEach(() => { + fsUtilStub = { + readFile: sinon.stub(), + writeFile: sinon.stub(), + makeDirectory: sinon.stub().resolves(), + }; + + fileHelperStub = { + fileExistsSync: sinon.stub(), + }; + + sinon.replace(require('../../../../src/utils'), 'fileHelper', fileHelperStub); + sinon.replaceGetter(require('../../../../src/utils'), 'fsUtil', () => fsUtilStub); + + const fetchWorkflowStub = sinon.stub().resolves({ + workflow_stages: [{ uid: 'stage-new', name: 'Review' }], + }); + mockStackClient = { + workflow: sinon.stub().returns({ + fetch: fetchWorkflowStub, + }), + }; + + mockImportConfig = { + apiKey: 'test', + backupDir: BACKUP, + data: '/test/content', + contentVersion: 1, + region: 'us', + fetchConcurrency: 2, + context: { + command: 'cm:stacks:import', + module: 'publishing-rules', + userId: 'user-123', + email: 'test@example.com', + sessionId: 'session-123', + apiKey: 'test', + orgId: 'org-123', + authenticationMethod: 'Basic Auth', + }, + modules: { + workflows: { + dirName: 'workflows', + fileName: 'workflows.json', + invalidKeys: ['uid'], + }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['uid'], + }, + }, + } as any; + + importPublishingRules = new ImportPublishingRules({ + importConfig: mockImportConfig as any, + stackAPIClient: mockStackClient, + moduleName: 'publishing-rules', + }); + + makeConcurrentCallStub = sinon.stub(importPublishingRules as any, 'makeConcurrentCall').resolves(); + + const cliUtilities = require('@contentstack/cli-utilities'); + logStub = { + info: sinon.stub(), + debug: sinon.stub(), + success: sinon.stub(), + error: sinon.stub(), + warn: sinon.stub(), + }; + sinon.stub(cliUtilities, 'log').value(logStub); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('Constructor', () => { + it('sets context.module to publishing-rules and derives exact paths from backupDir and config', () => { + expect(mockImportConfig.context.module).to.equal('publishing-rules'); + expect(importPublishingRules['mapperDirPath']).to.equal(join(BACKUP, 'mapper', 'publishing-rules')); + expect(importPublishingRules['publishingRulesFolderPath']).to.equal(join(BACKUP, 'workflows')); + expect(importPublishingRules['publishingRulesUidMapperPath']).to.equal(publishingMapperFile); + expect(importPublishingRules['createdPublishingRulesPath']).to.equal( + join(BACKUP, 'mapper', 'publishing-rules', 'success.json'), + ); + expect(importPublishingRules['failedPublishingRulesPath']).to.equal( + join(BACKUP, 'mapper', 'publishing-rules', 'fails.json'), + ); + }); + + it('initializes empty rules, mappers, and result arrays', () => { + expect(importPublishingRules['publishingRules']).to.deep.equal({}); + expect(importPublishingRules['publishingRulesUidMapper']).to.deep.equal({}); + expect(importPublishingRules['createdPublishingRules']).to.deep.equal([]); + expect(importPublishingRules['failedPublishingRules']).to.deep.equal([]); + expect(importPublishingRules['envUidMapper']).to.deep.equal({}); + expect(importPublishingRules['workflowUidMapper']).to.deep.equal({}); + expect(importPublishingRules['stageUidMapper']).to.deep.equal({}); + }); + }); + + describe('start()', () => { + it('returns undefined and logs missing file path when rules file does not exist', async () => { + fileHelperStub.fileExistsSync.withArgs(rulesFile).returns(false); + + const result = await importPublishingRules.start(); + + expect(result).to.equal(undefined); + expect(makeConcurrentCallStub.called).to.be.false; + expect(logStub.info.firstCall.args[0]).to.include(rulesFile); + }); + + it('returns undefined when rules file exists but payload is empty; arrays stay empty', async () => { + fileHelperStub.fileExistsSync.withArgs(rulesFile).returns(true); + fsUtilStub.readFile.withArgs(rulesFile, true).returns({}); + + const result = await importPublishingRules.start(); + + expect(result).to.equal(undefined); + expect(makeConcurrentCallStub.called).to.be.false; + expect(importPublishingRules['createdPublishingRules']).to.deep.equal([]); + expect(importPublishingRules['failedPublishingRules']).to.deep.equal([]); + }); + + it('passes one apiContent item per rule and binds serializeData to serializePublishingRules', async () => { + const rules = { + r1: { uid: 'r1', name: 'Rule 1' }, + r2: { uid: 'r2', name: 'Rule 2' }, + }; + fileHelperStub.fileExistsSync.callsFake((p: string) => { + if (p === rulesFile) return true; + if (p === workflowsExportFile || p === workflowMapperFile || p === envMapperFile || p === publishingMapperFile) { + return false; + } + return false; + }); + fsUtilStub.readFile.callsFake((p: string) => { + if (p === rulesFile) return rules; + return {}; + }); + + await importPublishingRules.start(); + + expect(makeConcurrentCallStub.calledOnce).to.be.true; + const callArgs = makeConcurrentCallStub.firstCall.args[0]; + expect(callArgs.apiContent).to.have.length(2); + expect(callArgs.processName).to.equal('import publishing rules'); + expect(callArgs.apiParams.entity).to.equal('create-publishing-rule'); + const serialized = callArgs.apiParams.serializeData({ + apiData: { uid: 'r1', name: 'Rule 1' }, + entity: 'create-publishing-rule', + }); + expect(serialized.apiData).to.deep.include({ name: 'Rule 1', uid: 'r1' }); + expect(serialized.entity).to.equal('create-publishing-rule'); + }); + + it('builds stageUidMapper from exported workflows and fetched target workflow stages by name', async () => { + fileHelperStub.fileExistsSync.callsFake((p: string) => { + if (p === rulesFile) return true; + if (p === workflowsExportFile) return true; + if (p === workflowMapperFile) return true; + if (p === envMapperFile || p === publishingMapperFile) return false; + return false; + }); + fsUtilStub.readFile.callsFake((p: string) => { + if (p === rulesFile) return { r1: { uid: 'r1', name: 'R' } }; + if (p === workflowsExportFile) { + return { + expWf: { workflow_stages: [{ uid: 'stage-old', name: 'Review' }] }, + }; + } + if (p === workflowMapperFile) return { oldWf: 'newWf' }; + return {}; + }); + + await importPublishingRules.start(); + + expect(importPublishingRules['stageUidMapper']).to.deep.equal({ 'stage-old': 'stage-new' }); + expect(mockStackClient.workflow.calledWith('newWf')).to.be.true; + }); + + it('returns { noSuccessMsg: true } when a rule fails to import (non-duplicate error)', async () => { + fileHelperStub.fileExistsSync.callsFake((p: string) => p === rulesFile); + fsUtilStub.readFile.callsFake((p: string) => (p === rulesFile ? { r1: { uid: 'r1', name: 'R' } } : {})); + + makeConcurrentCallStub.callsFake(async (env: any) => { + const { apiParams, apiContent } = env; + for (const element of apiContent) { + apiParams.apiData = element; + let opts = { ...apiParams, apiData: { ...element } }; + opts = apiParams.serializeData(opts); + if (opts.entity) { + await apiParams.reject({ error: new Error('network'), apiData: opts.apiData }); + } + } + }); + + const result = await importPublishingRules.start(); + + expect(result).to.deep.equal({ noSuccessMsg: true }); + expect(importPublishingRules['failedPublishingRules']).to.have.length(1); + expect(importPublishingRules['failedPublishingRules'][0].uid).to.equal('r1'); + expect(String(logStub.error.firstCall?.args[0] ?? '')).to.include('could not be imported'); + }); + + it('returns undefined when import succeeds with no failures', async () => { + fileHelperStub.fileExistsSync.callsFake((p: string) => p === rulesFile); + fsUtilStub.readFile.callsFake((p: string) => (p === rulesFile ? { r1: { uid: 'r1', name: 'R' } } : {})); + + makeConcurrentCallStub.callsFake(async (env: any) => { + const { apiParams, apiContent } = env; + for (const element of apiContent) { + apiParams.apiData = element; + let opts = { ...apiParams, apiData: { ...element } }; + opts = apiParams.serializeData(opts); + if (opts.entity) { + await apiParams.resolve({ response: { uid: 'new-r1' }, apiData: opts.apiData }); + } + } + }); + + const result = await importPublishingRules.start(); + + expect(result).to.equal(undefined); + expect(importPublishingRules['failedPublishingRules']).to.deep.equal([]); + expect(importPublishingRules['publishingRulesUidMapper']).to.deep.equal({ r1: 'new-r1' }); + expect(logStub.success.calledWith('Publishing rules have been imported successfully!', mockImportConfig.context)).to.be + .true; + }); + }); + + describe('serializePublishingRules', () => { + it('clears entity when rule uid already in mapper; leaves apiData.uid unchanged', () => { + importPublishingRules['publishingRulesUidMapper'] = { 'rule-1': 'mapped-1' }; + + const apiOptions: any = { + apiData: { uid: 'rule-1', name: 'N' }, + entity: 'create-publishing-rule', + }; + + const out = importPublishingRules.serializePublishingRules(apiOptions); + + expect(out.entity).to.equal(undefined); + expect(out.apiData).to.deep.equal({ uid: 'rule-1', name: 'N' }); + expect(String(logStub.info.firstCall?.args[0] ?? '')).to.match(/already exists\. Skipping/); + }); + + it('remaps workflow, environment, workflow_stage and strips approvers; apiData carries uid for completion handler', () => { + const pr = importPublishingRules as any; + pr.workflowUidMapper = { wfOld: 'wfNew' }; + pr.envUidMapper = { envOld: 'envNew' }; + Object.keys(pr.stageUidMapper).forEach((k) => delete pr.stageUidMapper[k]); + pr.stageUidMapper.stOld = 'stNew'; + + const apiOptions: any = { + apiData: { + uid: 'pr-1', + name: 'PR', + workflow: 'wfOld', + environment: 'envOld', + workflow_stage: 'stOld', + approvers: { roles: ['r1'], users: ['u1'] }, + }, + entity: 'create-publishing-rule', + }; + + const out = importPublishingRules.serializePublishingRules(apiOptions); + + expect(out.entity).to.equal('create-publishing-rule'); + expect(out.apiData).to.deep.equal({ + uid: 'pr-1', + name: 'PR', + workflow: 'wfNew', + environment: 'envNew', + workflow_stage: 'stNew', + approvers: { roles: [], users: [] }, + }); + const infoArgs = logStub.info.getCalls().map((c) => c.args[0]); + expect(infoArgs.some((msg) => String(msg).includes('Skipping import of publish rule approver'))).to.be.true; + }); + }); + + describe('importPublishingRules callbacks', () => { + beforeEach(() => { + importPublishingRules['publishingRules'] = { r1: { uid: 'r1', name: 'R' } }; + }); + + it('onSuccess updates mapper and persists uid-mapping.json with expected payload', async () => { + await (importPublishingRules as any).importPublishingRules(); + + const onSuccess = makeConcurrentCallStub.firstCall.args[0].apiParams.resolve; + await onSuccess({ response: { uid: 'created-uid', name: 'R' }, apiData: { uid: 'r1', name: 'R' } }); + + expect(importPublishingRules['createdPublishingRules']).to.deep.equal([{ uid: 'created-uid', name: 'R' }]); + expect(importPublishingRules['publishingRulesUidMapper']).to.deep.equal({ r1: 'created-uid' }); + expect(fsUtilStub.writeFile.calledWith(publishingMapperFile, { r1: 'created-uid' })).to.be.true; + }); + + it('onReject for duplicate error does not append to failedPublishingRules', async () => { + await (importPublishingRules as any).importPublishingRules(); + + const onReject = makeConcurrentCallStub.firstCall.args[0].apiParams.reject; + await onReject({ + error: { errors: { name: 'taken' } }, + apiData: { uid: 'r1', name: 'R' }, + }); + + expect(importPublishingRules['failedPublishingRules']).to.deep.equal([]); + expect(logStub.info.calledWith(`Publishing rule 'r1' already exists`, mockImportConfig.context)).to.be.true; + }); + }); +}); diff --git a/packages/contentstack-import/test/unit/utils/extension-helper.test.ts b/packages/contentstack-import/test/unit/utils/extension-helper.test.ts index c9b567218..fa537a84e 100644 --- a/packages/contentstack-import/test/unit/utils/extension-helper.test.ts +++ b/packages/contentstack-import/test/unit/utils/extension-helper.test.ts @@ -54,6 +54,11 @@ describe('Extension Helper', () => { webhooks: { dirName: 'webhooks', fileName: 'webhooks.json' }, releases: { dirName: 'releases', fileName: 'releases.json', invalidKeys: ['uid'] }, workflows: { dirName: 'workflows', fileName: 'workflows.json', invalidKeys: ['uid'] }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['uid'], + }, assets: { dirName: 'assets', assetBatchLimit: 10, diff --git a/packages/contentstack-import/test/unit/utils/publishing-rules-helper.test.ts b/packages/contentstack-import/test/unit/utils/publishing-rules-helper.test.ts new file mode 100644 index 000000000..1453b68eb --- /dev/null +++ b/packages/contentstack-import/test/unit/utils/publishing-rules-helper.test.ts @@ -0,0 +1,57 @@ +import { expect } from 'chai'; +import { parseErrorPayload, isDuplicatePublishingRuleError } from '../../../src/utils/publishing-rules-helper'; + +describe('publishing-rules-helper', () => { + describe('parseErrorPayload', () => { + it('returns the object when error has errors', () => { + const err = { errors: { name: 'taken' } }; + expect(parseErrorPayload(err)).to.deep.equal({ errors: { name: 'taken' } }); + }); + + it('parses JSON from message string', () => { + const err = { message: JSON.stringify({ error_message: 'already exists' }) }; + expect(parseErrorPayload(err)).to.deep.equal({ error_message: 'already exists' }); + }); + + it('returns null for invalid JSON in message', () => { + expect(parseErrorPayload({ message: 'not-json{' })).to.equal(null); + }); + + it('returns null for non-object', () => { + expect(parseErrorPayload(null)).to.equal(null); + expect(parseErrorPayload('x')).to.equal(null); + }); + + it('returns null when object has no errors or parseable message', () => { + expect(parseErrorPayload({ foo: 1 })).to.equal(null); + }); + }); + + describe('isDuplicatePublishingRuleError', () => { + it('returns true when errors.name is set', () => { + expect(isDuplicatePublishingRuleError({ errors: { name: 'x' } }, {})).to.equal(true); + }); + + it('returns true when errors.publishing_rule.name is set', () => { + expect(isDuplicatePublishingRuleError({ errors: { 'publishing_rule.name': 'x' } }, {})).to.equal(true); + }); + + it('returns true when errors.publish_rule.name is set', () => { + expect(isDuplicatePublishingRuleError({ errors: { 'publish_rule.name': 'x' } }, {})).to.equal(true); + }); + + it('returns true when error_message matches duplicate wording', () => { + expect(isDuplicatePublishingRuleError({ error_message: 'Rule already exists' }, {})).to.equal(true); + }); + + it('reads errors from raw when parsed is null', () => { + const raw = { errors: { name: 'dup' } }; + expect(isDuplicatePublishingRuleError(null, raw)).to.equal(true); + }); + + it('returns false when no duplicate signals', () => { + expect(isDuplicatePublishingRuleError({ errors: { other: 'x' } }, {})).to.equal(false); + expect(isDuplicatePublishingRuleError({ error_message: 'timeout' }, {})).to.equal(false); + }); + }); +}); From 42a8633d2163b81874f0e85e5bc12b30c0c24ac5 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Wed, 25 Mar 2026 00:09:08 +0530 Subject: [PATCH 3/9] chore: fix lint issues --- .talismanrc | 38 +- .../src/commands/cm/stacks/export.ts | 110 ++- .../contentstack-export/src/config/index.ts | 830 +++++++++--------- .../src/export/module-exporter.ts | 75 +- .../src/export/modules/assets.ts | 436 ++++----- .../src/export/modules/base-class.ts | 188 ++-- .../src/export/modules/composable-studio.ts | 74 +- .../src/export/modules/content-types.ts | 66 +- .../src/export/modules/custom-roles.ts | 114 +-- .../src/export/modules/entries.ts | 329 ++++--- .../src/export/modules/environments.ts | 72 +- .../src/export/modules/extensions.ts | 72 +- .../src/export/modules/global-fields.ts | 86 +- .../src/export/modules/index.ts | 1 + .../src/export/modules/labels.ts | 72 +- .../src/export/modules/locales.ts | 108 +-- .../src/export/modules/marketplace-apps.ts | 246 +++--- .../src/export/modules/personalize.ts | 16 +- .../src/export/modules/publishing-rules.ts | 10 +- .../src/export/modules/stack.ts | 176 ++-- .../src/export/modules/taxonomies.ts | 326 +++---- .../src/export/modules/webhooks.ts | 76 +- .../src/export/modules/workflows.ts | 118 +-- .../src/types/default-config.ts | 250 +++--- .../src/types/export-config.ts | 46 +- .../contentstack-export/src/types/index.ts | 91 +- .../src/types/marketplace-app.ts | 46 +- .../src/utils/basic-login.ts | 13 +- .../src/utils/common-helper.ts | 4 +- .../src/utils/export-config-handler.ts | 13 +- .../src/utils/file-helper.ts | 14 +- .../contentstack-export/src/utils/index.ts | 10 +- .../src/utils/interactive.ts | 16 +- .../contentstack-export/src/utils/logger.ts | 54 +- .../src/utils/marketplace-app-helper.ts | 8 +- .../src/utils/setup-branches.ts | 6 +- .../src/utils/setup-export-dir.ts | 2 +- .../test/unit/export/modules/assets.test.ts | 5 + .../unit/export/modules/base-class.test.ts | 5 + .../export/modules/publishing-rules.test.ts | 180 ++++ 40 files changed, 2311 insertions(+), 2091 deletions(-) create mode 100644 packages/contentstack-export/test/unit/export/modules/publishing-rules.test.ts diff --git a/.talismanrc b/.talismanrc index 2444ce1a8..b0441d15c 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,8 +1,34 @@ fileignoreconfig: - - filename: packages/contentstack-import/test/unit/utils/extension-helper.test.ts - checksum: c5aad4f28fbab6610d955490f061e647714b88f7b8f8d9cc4dbc3b4a10b9e59a - - filename: packages/contentstack-import/test/unit/import/modules/locales.test.ts - checksum: 0085926464eeb17cda0b9fb5a16853ad9c9aec9a42b54161107d0c808347498f - - filename: packages/contentstack-import/test/unit/import/modules/publishing-rules.test.ts - checksum: 0fcbff5dab2f9e594fe2a316c3c96e8d86bcd5d72e7c1f9eb35c0e3458f87817 + - filename: packages/contentstack-export/src/export/modules/environments.ts + checksum: ee579ab17a42580cd74ebfc24dcb5e0500e1f61958abe8cc9890d3144d2a8d3b + - filename: packages/contentstack-export/src/export/modules/workflows.ts + checksum: d62538c6915d14b754c2f3d1d01c71e82361fce19281f41c6b258bbe4225bfc0 + - filename: packages/contentstack-export/src/export/modules/labels.ts + checksum: bc3d0e099ff17157e4329ce41b4fb46440ebb48543e8cfc77bc30514eb325c2e + - filename: packages/contentstack-export/src/commands/cm/stacks/export.ts + checksum: 544a1384e9144c09c687152151e976f4f7cfc642abf796cd83d955fd440c6df5 + - filename: packages/contentstack-export/src/export/modules/locales.ts + checksum: fde0b7d1e9f857f09e3ae9972513ea3886e72e52fcf574e7f0613e204c29c616 + - filename: packages/contentstack-export/src/export/modules/extensions.ts + checksum: 3a130e782b2734822254c24e0ada301261aeb75bcf7338ebd90334e1e200d63f + - filename: packages/contentstack-export/src/utils/basic-login.ts + checksum: 5f654ddc90a4af5e1e65e31f18dcf41897fcd328b096fc38b5b759fb10a6189c + - filename: packages/contentstack-export/src/export/modules/custom-roles.ts + checksum: b392f2ad72f338e54cbf7dcf08290408cb5a7c91087702a429521ea2da48477e + - filename: packages/contentstack-export/src/utils/export-config-handler.ts + checksum: 83e8bef77dfe5171f5549f9e44975508bfb7bba3f8ef110611e995d4783057a8 + - filename: packages/contentstack-export/src/export/modules/webhooks.ts + checksum: 84cef1cb7a949460866465d6dc87ee7de77dd7993c72523f6b93ac4b934e611a + - filename: packages/contentstack-export/src/export/modules/stack.ts + checksum: 74c8222bc09563d6407b792fc33445d6664c50060e84d1be85e50206c565dc25 + - filename: packages/contentstack-export/src/export/modules/entries.ts + checksum: ffb79e14177a8722e0bcad9e95874cac249a17c6408915e10b1687d7a5cdcc1e + - filename: packages/contentstack-export/src/export/modules/assets.ts + checksum: 8d23c92daea085f5e4c40777f1a1b3f95cf1be0b4caf1e16658d0a763fb96e64 + - filename: packages/contentstack-export/src/types/default-config.ts + checksum: cccb5a18f1e191119a636786eb4b70d4f8bfb4cb25c96cd1981d2802ded66932 + - filename: packages/contentstack-export/test/unit/export/modules/publishing-rules.test.ts + checksum: 76068c1ca9d0837b5fd3eb98e297c7df6b89d0c2ca30d476c1eadfc6e95ac723 + - filename: packages/contentstack-export/src/config/index.ts + checksum: 9148f79ef833f6dae4bbb77c3434e41b0b3c7bfa83877837f60e5c2db888f0bf version: '1.0' diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 15f88c573..533147484 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -1,19 +1,17 @@ import { Command } from '@contentstack/cli-command'; import { - cliux, - messageHandler, - printFlagDeprecation, - managementSDKClient, - flags, ContentstackClient, FlagInput, + createLogContext, + flags, + getLogPath, + handleAndLogError, + log, + managementSDKClient, + messageHandler, pathValidator, + printFlagDeprecation, sanitizePath, - configHandler, - log, - handleAndLogError, - getLogPath, - createLogContext, } from '@contentstack/cli-utilities'; import { ModuleExporter } from '../../../export'; @@ -21,6 +19,8 @@ import { ExportConfig } from '../../../types'; import { setupExportConfig, writeExportMetaFile } from '../../../utils'; export default class ExportCommand extends Command { + static aliases: string[] = ['cm:export']; + static description: string = messageHandler.parse('Export content from a stack'); static examples: string[] = [ @@ -33,23 +33,39 @@ export default class ExportCommand extends Command { 'csdx cm:stacks:export --branch [optional] branch name', ]; - static usage: string = - 'cm:stacks:export [-c ] [-k ] [-d ] [-a ] [--module ] [--content-types ] [--branch ] [--secured-assets]'; - static flags: FlagInput = { + alias: flags.string({ + char: 'a', + description: 'The management token alias of the source stack from which you will export content.', + }), + 'auth-token': flags.boolean({ + char: 'A', + description: 'to use auth token', + hidden: true, + parse: printFlagDeprecation(['-A', '--auth-token']), + }), + branch: flags.string({ + char: 'B', + // default: 'main', + description: + "[optional] The name of the branch where you want to export your content. If you don't mention the branch name, then by default the content will be exported from all the branches of your stack.", + exclusive: ['branch-alias'], + parse: printFlagDeprecation(['-B'], ['--branch']), + }), + 'branch-alias': flags.string({ + description: '(Optional) The alias of the branch from which you want to export content.', + exclusive: ['branch'], + }), config: flags.string({ char: 'c', description: '[optional] Path of the config', }), - 'stack-uid': flags.string({ - char: 's', - description: 'API key of the source stack', - hidden: true, - parse: printFlagDeprecation(['-s', '--stack-uid'], ['-k', '--stack-api-key']), - }), - 'stack-api-key': flags.string({ - char: 'k', - description: 'API Key of the source stack', + 'content-types': flags.string({ + char: 't', + description: + '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.', + multiple: true, + parse: printFlagDeprecation(['-t'], ['--content-types']), }), data: flags.string({ description: 'path or location to store the data', @@ -60,61 +76,43 @@ export default class ExportCommand extends Command { char: 'd', description: 'The path or the location in your file system to store the exported content. For e.g., ./content', }), - alias: flags.string({ - char: 'a', - description: 'The management token alias of the source stack from which you will export content.', - }), 'management-token-alias': flags.string({ description: 'alias of the management token', hidden: true, parse: printFlagDeprecation(['--management-token-alias'], ['-a', '--alias']), }), - 'auth-token': flags.boolean({ - char: 'A', - description: 'to use auth token', - hidden: true, - parse: printFlagDeprecation(['-A', '--auth-token']), - }), module: flags.string({ char: 'm', description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, taxonomies, and studio.', parse: printFlagDeprecation(['-m'], ['--module']), }), - 'content-types': flags.string({ - char: 't', - description: - '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.', - multiple: true, - parse: printFlagDeprecation(['-t'], ['--content-types']), - }), - branch: flags.string({ - char: 'B', - // default: 'main', - description: - "[optional] The name of the branch where you want to export your content. If you don't mention the branch name, then by default the content will be exported from all the branches of your stack.", - parse: printFlagDeprecation(['-B'], ['--branch']), - exclusive: ['branch-alias'], - }), - 'branch-alias': flags.string({ - description: '(Optional) The alias of the branch from which you want to export content.', - exclusive: ['branch'], + query: flags.string({ + description: '[optional] Query object (inline JSON or file path) to filter module exports.', + hidden: true, }), 'secured-assets': flags.boolean({ description: '[optional] Use this flag for assets that are secured.', }), + 'stack-api-key': flags.string({ + char: 'k', + description: 'API Key of the source stack', + }), + 'stack-uid': flags.string({ + char: 's', + description: 'API key of the source stack', + hidden: true, + parse: printFlagDeprecation(['-s', '--stack-uid'], ['-k', '--stack-api-key']), + }), yes: flags.boolean({ char: 'y', - required: false, description: '[optional] Force override all Marketplace prompts.', - }), - query: flags.string({ - description: '[optional] Query object (inline JSON or file path) to filter module exports.', - hidden: true, + required: false, }), }; - static aliases: string[] = ['cm:export']; + static usage = + 'cm:stacks:export [-c ] [-k ] [-d ] [-a ] [--module ] [--content-types ] [--branch ] [--secured-assets]'; async run(): Promise { let exportDir: string = pathValidator('logs'); diff --git a/packages/contentstack-export/src/config/index.ts b/packages/contentstack-export/src/config/index.ts index e3c4d12a2..06b931dc3 100644 --- a/packages/contentstack-export/src/config/index.ts +++ b/packages/contentstack-export/src/config/index.ts @@ -1,17 +1,30 @@ import { DefaultConfig } from '../types'; const config: DefaultConfig = { + apis: { + assets: '/assets/', + content_types: '/content_types/', + entries: '/entries/', + environments: '/environments/', + extension: '/extensions', + globalfields: '/global_fields/', + labels: '/labels/', + locales: '/locales/', + stacks: '/stacks/', + userSession: '/user-session/', + users: '/stacks', + webhooks: '/webhooks/', + }, contentVersion: 2, - versioning: false, - host: 'https://api.contentstack.io/v3', + developerHubBaseUrl: '', developerHubUrls: { // NOTE CDA url used as developer-hub url mapper to avoid conflict if user used any custom name 'https://api.contentstack.io': 'https://developerhub-api.contentstack.com', - 'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com', - 'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com', 'https://azure-eu-api.contentstack.com': 'https://azure-eu-developerhub-api.contentstack.com', - 'https://gcp-na-api.contentstack.com': 'https://gcp-na-developerhub-api.contentstack.com', + 'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com', + 'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com', 'https://gcp-eu-api.contentstack.com': 'https://gcp-eu-developerhub-api.contentstack.com', + 'https://gcp-na-api.contentstack.com': 'https://gcp-na-developerhub-api.contentstack.com', }, // use below hosts for eu region // host:'https://eu-api.contentstack.com/v3', @@ -22,119 +35,303 @@ const config: DefaultConfig = { // use below hosts for gcp-na region // host: 'https://gcp-na-api.contentstack.com' // use below hosts for gcp-eu region + fetchConcurrency: 5, + host: 'https://api.contentstack.io/v3', + languagesCode: [ + 'af-za', + 'sq-al', + 'ar', + 'ar-dz', + 'ar-bh', + 'ar-eg', + 'ar-iq', + 'ar-jo', + 'ar-kw', + 'ar-lb', + 'ar-ly', + 'ar-ma', + 'ar-om', + 'ar-qa', + 'ar-sa', + 'ar-sy', + 'ar-tn', + 'ar-ae', + 'ar-ye', + 'hy-am', + 'az', + 'cy-az-az', + 'lt-az-az', + 'eu-es', + 'be-by', + 'bs', + 'bg-bg', + 'ca-es', + 'zh', + 'zh-au', + 'zh-cn', + 'zh-hk', + 'zh-mo', + 'zh-my', + 'zh-sg', + 'zh-tw', + 'zh-chs', + 'zh-cht', + 'hr-hr', + 'cs', + 'cs-cz', + 'da-dk', + 'div-mv', + 'nl', + 'nl-be', + 'nl-nl', + 'en', + 'en-au', + 'en-at', + 'en-be', + 'en-bz', + 'en-ca', + 'en-cb', + 'en-cn', + 'en-cz', + 'en-dk', + 'en-do', + 'en-ee', + 'en-fi', + 'en-fr', + 'en-de', + 'en-gr', + 'en-hk', + 'en-hu', + 'en-in', + 'en-id', + 'en-ie', + 'en-it', + 'en-jm', + 'en-jp', + 'en-kr', + 'en-lv', + 'en-lt', + 'en-lu', + 'en-my', + 'en-mx', + 'en-nz', + 'en-no', + 'en-ph', + 'en-pl', + 'en-pt', + 'en-pr', + 'en-ru', + 'en-sg', + 'en-sk', + 'en-si', + 'en-za', + 'en-es', + 'en-se', + 'en-ch', + 'en-th', + 'en-nl', + 'en-tt', + 'en-gb', + 'en-us', + 'en-zw', + 'et-ee', + 'fo-fo', + 'fa-ir', + 'fi', + 'fi-fi', + 'fr', + 'fr-be', + 'fr-ca', + 'fr-fr', + 'fr-lu', + 'fr-mc', + 'fr-ch', + 'fr-us', + 'gd', + 'gl-es', + 'ka-ge', + 'de', + 'de-at', + 'de-de', + 'de-li', + 'de-lu', + 'de-ch', + 'el-gr', + 'gu-in', + 'he-il', + 'hi-in', + 'hu-hu', + 'is-is', + 'id-id', + 'it', + 'it-it', + 'it-ch', + 'ja', + 'ja-jp', + 'kn-in', + 'kk-kz', + 'km-kh', + 'kok-in', + 'ko', + 'ko-kr', + 'ky-kz', + 'lv-lv', + 'lt-lt', + 'mk-mk', + 'ms', + 'ms-bn', + 'ms-my', + 'ms-sg', + 'mt', + 'mr-in', + 'mn-mn', + 'no', + 'no-no', + 'nb-no', + 'nn-no', + 'pl-pl', + 'pt', + 'pt-br', + 'pt-pt', + 'pa-in', + 'ro-ro', + 'ru', + 'ru-kz', + 'ru-ru', + 'ru-ua', + 'sa-in', + 'cy-sr-sp', + 'lt-sr-sp', + 'sr-me', + 'sk-sk', + 'sl-si', + 'es', + 'es-ar', + 'es-bo', + 'es-cl', + 'es-co', + 'es-cr', + 'es-do', + 'es-ec', + 'es-sv', + 'es-gt', + 'es-hn', + 'es-419', + 'es-mx', + 'es-ni', + 'es-pa', + 'es-py', + 'es-pe', + 'es-pr', + 'es-es', + 'es-us', + 'es-uy', + 'es-ve', + 'sw-ke', + 'sv', + 'sv-fi', + 'sv-se', + 'syr-sy', + 'tl', + 'ta-in', + 'tt-ru', + 'te-in', + 'th-th', + 'tr-tr', + 'uk-ua', + 'ur-pk', + 'uz', + 'cy-uz-uz', + 'lt-uz-uz', + 'vi-vn', + 'xh', + 'zu', + ], + marketplaceAppEncryptionKey: 'nF2ejRQcTv', // host: 'https://gcp-eu-api.contentstack.com' modules: { - types: [ - 'stack', - 'assets', - 'locales', - 'environments', - 'extensions', - 'webhooks', - 'taxonomies', - 'global-fields', - 'content-types', - 'custom-roles', - 'workflows', - 'publishing-rules', - 'personalize', - 'entries', - 'labels', - 'marketplace-apps', - 'composable-studio', - ], - locales: { - dirName: 'locales', - fileName: 'locales.json', - requiredKeys: ['code', 'uid', 'name', 'fallback_locale'], - }, - masterLocale: { - dirName: 'locales', - fileName: 'master-locale.json', - requiredKeys: ['code', 'uid', 'name'], - }, - customRoles: { - dirName: 'custom-roles', - fileName: 'custom-roles.json', - customRolesLocalesFileName: 'custom-roles-locales.json', - }, - 'custom-roles': { - dirName: 'custom-roles', - fileName: 'custom-roles.json', - customRolesLocalesFileName: 'custom-roles-locales.json', - }, - environments: { - dirName: 'environments', - fileName: 'environments.json', - }, - labels: { - dirName: 'labels', - fileName: 'labels.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], - }, - webhooks: { - dirName: 'webhooks', - fileName: 'webhooks.json', - }, - releases: { - dirName: 'releases', - fileName: 'releases.json', - releasesList: 'releasesList.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], - }, - workflows: { - dirName: 'workflows', - fileName: 'workflows.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], - }, - 'publishing-rules': { - dirName: 'workflows', - fileName: 'publishing-rules.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], - }, - globalfields: { - dirName: 'global_fields', - fileName: 'globalfields.json', - validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], - }, - 'global-fields': { - dirName: 'global_fields', - fileName: 'globalfields.json', - validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], - }, assets: { - dirName: 'assets', - fileName: 'assets.json', + assetsMetaKeys: [], // Default keys ['uid', 'url', 'filename'] // This is the total no. of asset objects fetched in each 'get assets' call batchLimit: 20, - host: 'https://images.contentstack.io', - invalidKeys: ['created_at', 'updated_at', 'created_by', 'updated_by', '_metadata', 'published'], // no of asset version files (of a single asset) that'll be downloaded parallel chunkFileSize: 1, // measured on Megabits (5mb) - downloadLimit: 5, - fetchConcurrency: 5, - assetsMetaKeys: [], // Default keys ['uid', 'url', 'filename'] - securedAssets: false, + dirName: 'assets', displayExecutionTime: false, + downloadLimit: 5, enableDownloadStatus: false, + fetchConcurrency: 5, + fileName: 'assets.json', + host: 'https://images.contentstack.io', includeVersionedAssets: false, + invalidKeys: ['created_at', 'updated_at', 'created_by', 'updated_by', '_metadata', 'published'], + securedAssets: false, + }, + attributes: { + dirName: 'attributes', + fileName: 'attributes.json', + invalidKeys: [ + 'updatedAt', + 'createdBy', + 'updatedBy', + '_id', + 'createdAt', + 'createdByUserName', + 'updatedByUserName', + ], + }, + audiences: { + dirName: 'audiences', + fileName: 'audiences.json', + invalidKeys: [ + 'updatedAt', + 'createdBy', + 'updatedBy', + '_id', + 'createdAt', + 'createdByUserName', + 'updatedByUserName', + ], + }, + 'composable-studio': { + apiBaseUrl: 'https://composable-studio-api.contentstack.com', + apiVersion: 'v1', + dirName: 'composable_studio', + fileName: 'composable_studio.json', }, content_types: { dirName: 'content_types', fileName: 'content_types.json', - validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], // total no of content types fetched in each 'get content types' call limit: 100, + validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], }, 'content-types': { dirName: 'content_types', fileName: 'content_types.json', - validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], // total no of content types fetched in each 'get content types' call limit: 100, + validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], + }, + 'custom-roles': { + customRolesLocalesFileName: 'custom-roles-locales.json', + dirName: 'custom-roles', + fileName: 'custom-roles.json', + }, + customRoles: { + customRolesLocalesFileName: 'custom-roles-locales.json', + dirName: 'custom-roles', + fileName: 'custom-roles.json', + }, + dependency: { + entries: ['stack', 'locales', 'content-types'], }, entries: { + batchLimit: 20, + dependencies: ['locales', 'content-types'], dirName: 'entries', + downloadLimit: 5, + exportVersions: false, fileName: 'entries.json', invalidKeys: [ 'stackHeaders', @@ -147,29 +344,64 @@ const config: DefaultConfig = { '_metadata', 'published', ], - batchLimit: 20, - downloadLimit: 5, // total no of entries fetched in each content type in a single call limit: 100, - dependencies: ['locales', 'content-types'], - exportVersions: false, + }, + environments: { + dirName: 'environments', + fileName: 'environments.json', + }, + events: { + dirName: 'events', + fileName: 'events.json', + invalidKeys: [ + 'updatedAt', + 'createdBy', + 'updatedBy', + '_id', + 'createdAt', + 'createdByUserName', + 'updatedByUserName', + ], + }, + extensions: { + dirName: 'extensions', + fileName: 'extensions.json', + }, + 'global-fields': { + dirName: 'global_fields', + fileName: 'globalfields.json', + validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], + }, + globalfields: { + dirName: 'global_fields', + fileName: 'globalfields.json', + validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], + }, + labels: { + dirName: 'labels', + fileName: 'labels.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, + locales: { + dirName: 'locales', + fileName: 'locales.json', + requiredKeys: ['code', 'uid', 'name', 'fallback_locale'], + }, + marketplace_apps: { + dirName: 'marketplace_apps', + fileName: 'marketplace_apps.json', + }, + 'marketplace-apps': { + dirName: 'marketplace_apps', + fileName: 'marketplace_apps.json', + }, + masterLocale: { + dirName: 'locales', + fileName: 'master-locale.json', + requiredKeys: ['code', 'uid', 'name'], }, personalize: { - baseURL: { - 'AWS-NA': 'https://personalize-api.contentstack.com', - 'AWS-EU': 'https://eu-personalize-api.contentstack.com', - 'AWS-AU': 'https://au-personalize-api.contentstack.com', - 'AZURE-NA': 'https://azure-na-personalize-api.contentstack.com', - 'AZURE-EU': 'https://azure-eu-personalize-api.contentstack.com', - 'GCP-NA': 'https://gcp-na-personalize-api.contentstack.com', - 'GCP-EU': 'https://gcp-eu-personalize-api.contentstack.com', - }, - dirName: 'personalize', - exportOrder: ['attributes', 'audiences', 'events', 'experiences'], - projects: { - dirName: 'projects', - fileName: 'projects.json', - }, attributes: { dirName: 'attributes', fileName: 'attributes.json', @@ -178,6 +410,16 @@ const config: DefaultConfig = { dirName: 'audiences', fileName: 'audiences.json', }, + baseURL: { + 'AWS-AU': 'https://au-personalize-api.contentstack.com', + 'AWS-EU': 'https://eu-personalize-api.contentstack.com', + 'AWS-NA': 'https://personalize-api.contentstack.com', + 'AZURE-EU': 'https://azure-eu-personalize-api.contentstack.com', + 'AZURE-NA': 'https://azure-na-personalize-api.contentstack.com', + 'GCP-EU': 'https://gcp-eu-personalize-api.contentstack.com', + 'GCP-NA': 'https://gcp-na-personalize-api.contentstack.com', + }, + dirName: 'personalize', events: { dirName: 'events', fileName: 'events.json', @@ -186,323 +428,81 @@ const config: DefaultConfig = { dirName: 'experiences', fileName: 'experiences.json', }, - }, - variantEntry: { - serveMockData: false, - dirName: 'variants', - fileName: 'index.json', - chunkFileSize: 1, - query: { - skip: 0, - limit: 100, - include_variant: false, - include_count: true, - include_publish_details: true, + exportOrder: ['attributes', 'audiences', 'events', 'experiences'], + projects: { + dirName: 'projects', + fileName: 'projects.json', }, - mockDataPath: './variant-mock-data.json', }, - extensions: { - dirName: 'extensions', - fileName: 'extensions.json', + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, + releases: { + dirName: 'releases', + fileName: 'releases.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + releasesList: 'releasesList.json', }, stack: { dirName: 'stack', fileName: 'stack.json', }, - dependency: { - entries: ['stack', 'locales', 'content-types'], - }, - marketplace_apps: { - dirName: 'marketplace_apps', - fileName: 'marketplace_apps.json', - }, - 'marketplace-apps': { - dirName: 'marketplace_apps', - fileName: 'marketplace_apps.json', + taxonomies: { + dirName: 'taxonomies', + fileName: 'taxonomies.json', + invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath', 'created_at'], + limit: 100, }, - 'composable-studio': { - dirName: 'composable_studio', - fileName: 'composable_studio.json', - apiBaseUrl: 'https://composable-studio-api.contentstack.com', - apiVersion: 'v1', - }, - taxonomies: { - dirName: 'taxonomies', - fileName: 'taxonomies.json', - invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath', 'created_at'], - limit: 100, - }, - events: { - dirName: 'events', - fileName: 'events.json', - invalidKeys: [ - 'updatedAt', - 'createdBy', - 'updatedBy', - '_id', - 'createdAt', - 'createdByUserName', - 'updatedByUserName', - ], + types: [ + 'stack', + 'assets', + 'locales', + 'environments', + 'extensions', + 'webhooks', + 'taxonomies', + 'global-fields', + 'content-types', + 'custom-roles', + 'workflows', + 'publishing-rules', + 'personalize', + 'entries', + 'labels', + 'marketplace-apps', + 'composable-studio', + ], + variantEntry: { + chunkFileSize: 1, + dirName: 'variants', + fileName: 'index.json', + mockDataPath: './variant-mock-data.json', + query: { + include_count: true, + include_publish_details: true, + include_variant: false, + limit: 100, + skip: 0, + }, + serveMockData: false, }, - audiences: { - dirName: 'audiences', - fileName: 'audiences.json', - invalidKeys: [ - 'updatedAt', - 'createdBy', - 'updatedBy', - '_id', - 'createdAt', - 'createdByUserName', - 'updatedByUserName', - ], + webhooks: { + dirName: 'webhooks', + fileName: 'webhooks.json', }, - attributes: { - dirName: 'attributes', - fileName: 'attributes.json', - invalidKeys: [ - 'updatedAt', - 'createdBy', - 'updatedBy', - '_id', - 'createdAt', - 'createdByUserName', - 'updatedByUserName', - ], + workflows: { + dirName: 'workflows', + fileName: 'workflows.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], }, }, - languagesCode: [ - 'af-za', - 'sq-al', - 'ar', - 'ar-dz', - 'ar-bh', - 'ar-eg', - 'ar-iq', - 'ar-jo', - 'ar-kw', - 'ar-lb', - 'ar-ly', - 'ar-ma', - 'ar-om', - 'ar-qa', - 'ar-sa', - 'ar-sy', - 'ar-tn', - 'ar-ae', - 'ar-ye', - 'hy-am', - 'az', - 'cy-az-az', - 'lt-az-az', - 'eu-es', - 'be-by', - 'bs', - 'bg-bg', - 'ca-es', - 'zh', - 'zh-au', - 'zh-cn', - 'zh-hk', - 'zh-mo', - 'zh-my', - 'zh-sg', - 'zh-tw', - 'zh-chs', - 'zh-cht', - 'hr-hr', - 'cs', - 'cs-cz', - 'da-dk', - 'div-mv', - 'nl', - 'nl-be', - 'nl-nl', - 'en', - 'en-au', - 'en-at', - 'en-be', - 'en-bz', - 'en-ca', - 'en-cb', - 'en-cn', - 'en-cz', - 'en-dk', - 'en-do', - 'en-ee', - 'en-fi', - 'en-fr', - 'en-de', - 'en-gr', - 'en-hk', - 'en-hu', - 'en-in', - 'en-id', - 'en-ie', - 'en-it', - 'en-jm', - 'en-jp', - 'en-kr', - 'en-lv', - 'en-lt', - 'en-lu', - 'en-my', - 'en-mx', - 'en-nz', - 'en-no', - 'en-ph', - 'en-pl', - 'en-pt', - 'en-pr', - 'en-ru', - 'en-sg', - 'en-sk', - 'en-si', - 'en-za', - 'en-es', - 'en-se', - 'en-ch', - 'en-th', - 'en-nl', - 'en-tt', - 'en-gb', - 'en-us', - 'en-zw', - 'et-ee', - 'fo-fo', - 'fa-ir', - 'fi', - 'fi-fi', - 'fr', - 'fr-be', - 'fr-ca', - 'fr-fr', - 'fr-lu', - 'fr-mc', - 'fr-ch', - 'fr-us', - 'gd', - 'gl-es', - 'ka-ge', - 'de', - 'de-at', - 'de-de', - 'de-li', - 'de-lu', - 'de-ch', - 'el-gr', - 'gu-in', - 'he-il', - 'hi-in', - 'hu-hu', - 'is-is', - 'id-id', - 'it', - 'it-it', - 'it-ch', - 'ja', - 'ja-jp', - 'kn-in', - 'kk-kz', - 'km-kh', - 'kok-in', - 'ko', - 'ko-kr', - 'ky-kz', - 'lv-lv', - 'lt-lt', - 'mk-mk', - 'ms', - 'ms-bn', - 'ms-my', - 'ms-sg', - 'mt', - 'mr-in', - 'mn-mn', - 'no', - 'no-no', - 'nb-no', - 'nn-no', - 'pl-pl', - 'pt', - 'pt-br', - 'pt-pt', - 'pa-in', - 'ro-ro', - 'ru', - 'ru-kz', - 'ru-ru', - 'ru-ua', - 'sa-in', - 'cy-sr-sp', - 'lt-sr-sp', - 'sr-me', - 'sk-sk', - 'sl-si', - 'es', - 'es-ar', - 'es-bo', - 'es-cl', - 'es-co', - 'es-cr', - 'es-do', - 'es-ec', - 'es-sv', - 'es-gt', - 'es-hn', - 'es-419', - 'es-mx', - 'es-ni', - 'es-pa', - 'es-py', - 'es-pe', - 'es-pr', - 'es-es', - 'es-us', - 'es-uy', - 'es-ve', - 'sw-ke', - 'sv', - 'sv-fi', - 'sv-se', - 'syr-sy', - 'tl', - 'ta-in', - 'tt-ru', - 'te-in', - 'th-th', - 'tr-tr', - 'uk-ua', - 'ur-pk', - 'uz', - 'cy-uz-uz', - 'lt-uz-uz', - 'vi-vn', - 'xh', - 'zu', - ], - apis: { - userSession: '/user-session/', - globalfields: '/global_fields/', - locales: '/locales/', - labels: '/labels/', - environments: '/environments/', - assets: '/assets/', - content_types: '/content_types/', - entries: '/entries/', - users: '/stacks', - extension: '/extensions', - webhooks: '/webhooks/', - stacks: '/stacks/', - }, - preserveStackVersion: false, + onlyTSModules: ['taxonomies'], personalizationEnabled: false, - fetchConcurrency: 5, + preserveStackVersion: false, + versioning: false, writeConcurrency: 5, - developerHubBaseUrl: '', - marketplaceAppEncryptionKey: 'nF2ejRQcTv', - onlyTSModules: ['taxonomies'], }; export default config; diff --git a/packages/contentstack-export/src/export/module-exporter.ts b/packages/contentstack-export/src/export/module-exporter.ts index 0cd1a8bea..02077334a 100644 --- a/packages/contentstack-export/src/export/module-exporter.ts +++ b/packages/contentstack-export/src/export/module-exporter.ts @@ -1,19 +1,22 @@ -import * as path from 'path'; import { ContentstackClient, + getBranchFromAlias, handleAndLogError, - messageHandler, log, - getBranchFromAlias, + messageHandler, } from '@contentstack/cli-utilities'; +import * as path from 'path'; + +import { ExportConfig, Modules } from '../types'; import { setupBranches, setupExportDir, writeExportMetaFile } from '../utils'; import startModuleExport from './modules'; +// CJS: modules-js/index.js uses module.exports (no ESM default) +// eslint-disable-next-line import/default -- resolved at runtime via module.exports import startJSModuleExport from './modules-js'; -import { ExportConfig, Modules } from '../types'; class ModuleExporter { - private managementAPIClient: ContentstackClient; private exportConfig: ExportConfig; + private managementAPIClient: ContentstackClient; private stackAPIClient: ReturnType; constructor(managementAPIClient: ContentstackClient, exportConfig: ExportConfig) { @@ -25,22 +28,19 @@ class ModuleExporter { this.exportConfig = exportConfig; } - async start(): Promise { - // setup the branches - try { - if (!this.exportConfig.branchName && this.exportConfig.branchAlias) { - this.exportConfig.branchName = await getBranchFromAlias(this.stackAPIClient, this.exportConfig.branchAlias); - } - await setupBranches(this.exportConfig, this.stackAPIClient); - await setupExportDir(this.exportConfig); - // if branches available run it export by branches - if (this.exportConfig.branches) { - this.exportConfig.branchEnabled = true; - return this.exportByBranches(); - } - return this.export(); - } catch (error) { - throw error; + async export() { + log.info(`Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context); + // checks for single module or all modules + if (this.exportConfig.singleModuleExport) { + return this.exportSingleModule(this.exportConfig.moduleName); + } + return this.exportAllModules(); + } + + async exportAllModules(): Promise { + // use the algorithm to determine the parallel and sequential execution of modules + for (const moduleName of this.exportConfig.modules.types) { + await this.exportByModuleByName(moduleName); } } @@ -66,15 +66,6 @@ class ModuleExporter { } } - async export() { - log.info(`Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context); - // checks for single module or all modules - if (this.exportConfig.singleModuleExport) { - return this.exportSingleModule(this.exportConfig.moduleName); - } - return this.exportAllModules(); - } - async exportByModuleByName(moduleName: Modules) { log.info(`Exporting module: '${moduleName}'...`, this.exportConfig.context); // export the modules by name @@ -82,17 +73,17 @@ class ModuleExporter { let exportedModuleResponse; if (this.exportConfig.contentVersion === 2) { exportedModuleResponse = await startModuleExport({ - stackAPIClient: this.stackAPIClient, exportConfig: this.exportConfig, moduleName, + stackAPIClient: this.stackAPIClient, }); } else { //NOTE - new modules support only ts if (this.exportConfig.onlyTSModules.indexOf(moduleName) === -1) { exportedModuleResponse = await startJSModuleExport({ - stackAPIClient: this.stackAPIClient, exportConfig: this.exportConfig, moduleName, + stackAPIClient: this.stackAPIClient, }); } } @@ -126,10 +117,22 @@ class ModuleExporter { } } - async exportAllModules(): Promise { - // use the algorithm to determine the parallel and sequential execution of modules - for (const moduleName of this.exportConfig.modules.types) { - await this.exportByModuleByName(moduleName); + async start(): Promise { + // setup the branches + try { + if (!this.exportConfig.branchName && this.exportConfig.branchAlias) { + this.exportConfig.branchName = await getBranchFromAlias(this.stackAPIClient, this.exportConfig.branchAlias); + } + await setupBranches(this.exportConfig, this.stackAPIClient); + await setupExportDir(this.exportConfig); + // if branches available run it export by branches + if (this.exportConfig.branches) { + this.exportConfig.branchEnabled = true; + return this.exportByBranches(); + } + return this.export(); + } catch (error) { + throw error; } } } diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 1a95d5f25..35b193f0e 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -1,34 +1,34 @@ -import map from 'lodash/map'; +import { + FsUtility, + configHandler, + getDirectories, + handleAndLogError, + log, + messageHandler, +} from '@contentstack/cli-utilities'; import chunk from 'lodash/chunk'; +import entries from 'lodash/entries'; +import filter from 'lodash/filter'; import first from 'lodash/first'; +import includes from 'lodash/includes'; +import isEmpty from 'lodash/isEmpty'; +import map from 'lodash/map'; import merge from 'lodash/merge'; -import filter from 'lodash/filter'; import uniqBy from 'lodash/uniqBy'; import values from 'lodash/values'; -import entries from 'lodash/entries'; -import isEmpty from 'lodash/isEmpty'; -import includes from 'lodash/includes'; -import progress from 'progress-stream'; import { createWriteStream } from 'node:fs'; import { resolve as pResolve } from 'node:path'; -import { - FsUtility, - getDirectories, - configHandler, - log, - handleAndLogError, - messageHandler, -} from '@contentstack/cli-utilities'; +import progress from 'progress-stream'; import config from '../../config'; import { ModuleClassParams } from '../../types'; import BaseClass, { CustomPromiseHandler, CustomPromiseHandlerInput } from './base-class'; export default class ExportAssets extends BaseClass { - private assetsRootPath: string; public assetConfig = config.modules.assets; - private assetsFolder: Record[] = []; public versionedAssets: Record[] = []; + private assetsFolder: Record[] = []; + private assetsRootPath: string; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -37,85 +37,120 @@ export default class ExportAssets extends BaseClass { get commonQueryParam(): Record { return { - skip: 0, asc: 'created_at', include_count: false, + skip: 0, }; } - async start(): Promise { - this.assetsRootPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.assetConfig.dirName, - ); + /** + * @method downloadAssets + * @returns Promise + */ + async downloadAssets(): Promise { + const fs: FsUtility = new FsUtility({ + basePath: this.assetsRootPath, + createDirIfNotExist: false, + fileExt: 'json', + }); - log.debug(`Assets root path resolved to: ${this.assetsRootPath}`, this.exportConfig.context); - log.debug('Fetching assets and folders count...', this.exportConfig.context); - // NOTE step 1: Get assets and it's folder count in parallel - const [assetsCount, assetsFolderCount] = await Promise.all([this.getAssetsCount(), this.getAssetsCount(true)]); + log.debug('Reading asset metadata for download...', this.exportConfig.context); + const assetsMetaData = fs.getPlainMeta(); - log.debug('Fetching assets and folders data...', this.exportConfig.context); - // NOTE step 2: Get assets and it's folder data in parallel - await Promise.all([this.getAssetsFolders(assetsFolderCount), this.getAssets(assetsCount)]); + let listOfAssets = values(assetsMetaData).flat(); - // NOTE step 3: Get versioned assets - if (!isEmpty(this.versionedAssets) && this.assetConfig.includeVersionedAssets) { - log.debug('Fetching versioned assets metadata...', this.exportConfig.context); - await this.getVersionedAssets(); + if (this.assetConfig.includeVersionedAssets) { + const versionedAssetsMetaData = fs.getPlainMeta(pResolve(this.assetsRootPath, 'versions', 'metadata.json')); + listOfAssets.push(...values(versionedAssetsMetaData).flat()); } - log.debug('Starting download of all assets...', this.exportConfig.context); - // NOTE step 4: Download all assets - await this.downloadAssets(); + listOfAssets = uniqBy(listOfAssets, 'url'); + log.debug(`Total unique assets to download: ${listOfAssets.length}`, this.exportConfig.context); - log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); - } + const apiBatches: Array = chunk(listOfAssets, this.assetConfig.downloadLimit); + const downloadedAssetsDirs = await getDirectories(pResolve(this.assetsRootPath, 'files')); - /** - * @method getAssetsFolders - * @param {number} totalCount number - * @returns Promise - */ - getAssetsFolders(totalCount: number | void): Promise | void> { - if (!totalCount) return Promise.resolve(); + const onSuccess = ({ additionalInfo, response: { data } }: any) => { + const { asset } = additionalInfo; + const assetFolderPath = pResolve(this.assetsRootPath, 'files', asset.uid); + const assetFilePath = pResolve(assetFolderPath, asset.filename); - const queryParam = { - ...this.commonQueryParam, - query: { is_dir: true }, - }; + log.debug(`Saving asset to: ${assetFilePath}`, this.exportConfig.context); - log.debug(`Fetching asset folders with query: ${JSON.stringify(queryParam)}`, this.exportConfig.context); + if (!includes(downloadedAssetsDirs, asset.uid)) { + fs.createFolderIfNotExist(assetFolderPath); + } - const onSuccess = ({ response: { items } }: any) => { - log.debug(`Fetched ${items?.length || 0} asset folders`, this.exportConfig.context); - if (!isEmpty(items)) this.assetsFolder.push(...items); + const assetWriterStream = createWriteStream(assetFilePath); + assetWriterStream.on('error', (error) => { + handleAndLogError( + error, + { ...this.exportConfig.context, filename: asset.fileName, uid: asset.uid }, + messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), + ); + }); + /** + * NOTE if pipe not working as expected add the following code below to fix the issue + * https://oramind.com/using-streams-efficiently-in-nodejs/ + * import * as stream from "stream"; + * import { promisify } from "util"; + * const finished = promisify(stream.finished); + * await finished(assetWriterStream); + */ + if (this.assetConfig.enableDownloadStatus) { + const str = progress({ + length: data.headers['content-length'], + time: 5000, + }); + str.on('progress', function (progressData) { + console.log(`${asset.filename}: ${Math.round(progressData.percentage)}%`); + }); + data.pipe(str).pipe(assetWriterStream); + } else { + data.pipe(assetWriterStream); + } + + log.success(messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), this.exportConfig.context); }; - const onReject = ({ error }: any) => { - handleAndLogError(error, { ...this.exportConfig.context }); + const onReject = ({ additionalInfo, error }: any) => { + const { asset } = additionalInfo; + handleAndLogError( + error, + { ...this.exportConfig.context, filename: asset.filename, uid: asset.uid }, + messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), + ); }; - return this.makeConcurrentCall({ - totalCount, - apiParams: { - queryParam, - module: 'assets', + const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { + const { batchIndex, index } = input; + const asset: any = apiBatches[batchIndex][index]; + const url = this.assetConfig.securedAssets + ? `${asset.url}?authtoken=${configHandler.get('authtoken')}` + : asset.url; + log.debug( + `Preparing to download asset: ${asset.filename} (UID: ${asset.uid}) from URL: ${url}`, + this.exportConfig.context, + ); + return this.makeAPICall({ + additionalInfo: { asset }, + module: 'download-asset', reject: onReject, resolve: onSuccess, + url: encodeURI(url), + }); + }; + + return this.makeConcurrentCall( + { + apiBatches, + concurrencyLimit: this.assetConfig.downloadLimit, + module: 'assets download', + totalCount: listOfAssets.length, }, - module: 'assets folders', - concurrencyLimit: this.assetConfig.fetchConcurrency, - }).then(() => { - if (!isEmpty(this.assetsFolder)) { - const path = pResolve(this.assetsRootPath, 'folders.json'); - log.debug(`Writing asset folders to ${path}`, this.exportConfig.context); - new FsUtility({ basePath: this.assetsRootPath }).writeFile(path, this.assetsFolder); - } - log.info( - messageHandler.parse('ASSET_FOLDERS_EXPORT_COMPLETE', this.assetsFolder.length), - this.exportConfig.context, - ); + promisifyHandler, + ).then(() => { + log.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); }); } @@ -134,8 +169,8 @@ export default class ExportAssets extends BaseClass { const queryParam = { ...this.commonQueryParam, - include_publish_details: true, except: { BASE: this.assetConfig.invalidKeys }, + include_publish_details: true, }; this.applyQueryFilters(queryParam, 'assets'); @@ -145,7 +180,7 @@ export default class ExportAssets extends BaseClass { log.debug(`Found ${versionAssets.length} versioned assets`, this.exportConfig.context); if (!isEmpty(versionAssets)) { this.versionedAssets.push( - ...map(versionAssets, ({ uid, _version }: any) => ({ + ...map(versionAssets, ({ _version, uid }: any) => ({ [uid]: _version, })), ); @@ -163,12 +198,12 @@ export default class ExportAssets extends BaseClass { if (!fs && !isEmpty(items)) { log.debug('Initializing FsUtility for writing assets metadata', this.exportConfig.context); fs = new FsUtility({ - metaHandler, - moduleName: 'assets', - indexFileName: 'assets.json', basePath: this.assetsRootPath, chunkFileSize: this.assetConfig.chunkFileSize, + indexFileName: 'assets.json', + metaHandler, metaPickKeys: merge(['uid', 'url', 'filename', 'parent_uid'], this.assetConfig.assetsMetaKeys), + moduleName: 'assets', }); } if (!isEmpty(items)) { @@ -178,20 +213,94 @@ export default class ExportAssets extends BaseClass { }; return this.makeConcurrentCall({ - module: 'assets', - totalCount, apiParams: { - queryParam, module: 'assets', + queryParam, reject: onReject, resolve: onSuccess, }, concurrencyLimit: this.assetConfig.fetchConcurrency, + module: 'assets', + totalCount, }).then(() => { fs?.completeFile(true); log.info(messageHandler.parse('ASSET_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } + + getAssetsCount(isDir = false): Promise { + const queryParam: any = { + limit: 1, + ...this.commonQueryParam, + skip: 10 ** 100, + }; + + if (isDir) queryParam.query = { is_dir: true }; + + log.debug( + `Querying count of assets${isDir ? ' (folders only)' : ''} with params: ${JSON.stringify(queryParam)}`, + this.exportConfig.context, + ); + + return this.stack + .asset() + .query(queryParam) + .count() + .then(({ assets }: any) => { + log.debug(`Received asset count: ${assets}`, this.exportConfig.context); + return assets; + }) + .catch((error: Error) => { + handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_COUNT_QUERY_FAILED')); + }); + } + /** + * @method getAssetsFolders + * @param {number} totalCount number + * @returns Promise + */ + getAssetsFolders(totalCount: number | void): Promise | void> { + if (!totalCount) return Promise.resolve(); + + const queryParam = { + ...this.commonQueryParam, + query: { is_dir: true }, + }; + + log.debug(`Fetching asset folders with query: ${JSON.stringify(queryParam)}`, this.exportConfig.context); + + const onSuccess = ({ response: { items } }: any) => { + log.debug(`Fetched ${items?.length || 0} asset folders`, this.exportConfig.context); + if (!isEmpty(items)) this.assetsFolder.push(...items); + }; + + const onReject = ({ error }: any) => { + handleAndLogError(error, { ...this.exportConfig.context }); + }; + + return this.makeConcurrentCall({ + apiParams: { + module: 'assets', + queryParam, + reject: onReject, + resolve: onSuccess, + }, + concurrencyLimit: this.assetConfig.fetchConcurrency, + module: 'assets folders', + totalCount, + }).then(() => { + if (!isEmpty(this.assetsFolder)) { + const path = pResolve(this.assetsRootPath, 'folders.json'); + log.debug(`Writing asset folders to ${path}`, this.exportConfig.context); + new FsUtility({ basePath: this.assetsRootPath }).writeFile(path, this.assetsFolder); + } + log.info( + messageHandler.parse('ASSET_FOLDERS_EXPORT_COMPLETE', this.assetsFolder.length), + this.exportConfig.context, + ); + }); + } + /** * @method getVersionedAssets * @returns Promise @@ -203,8 +312,8 @@ export default class ExportAssets extends BaseClass { const queryParam = { ...this.commonQueryParam, - include_publish_details: true, except: { BASE: this.assetConfig.invalidKeys }, + include_publish_details: true, }; const versionedAssets = map(this.versionedAssets, (element) => { @@ -222,7 +331,7 @@ export default class ExportAssets extends BaseClass { const apiBatches: Array = chunk(versionedAssets, this.assetConfig.fetchConcurrency); const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { - const { index, batchIndex, apiParams, isLastRequest } = input; + const { apiParams, batchIndex, index, isLastRequest } = input; const batch: Record = apiBatches[batchIndex][index]; const [uid, version]: any = first(entries(batch)); @@ -239,11 +348,11 @@ export default class ExportAssets extends BaseClass { const onSuccess = ({ response }: any) => { if (!fs && !isEmpty(response)) { fs = new FsUtility({ - moduleName: 'assets', - indexFileName: 'versioned-assets.json', - chunkFileSize: this.assetConfig.chunkFileSize, basePath: pResolve(this.assetsRootPath, 'versions'), + chunkFileSize: this.assetConfig.chunkFileSize, + indexFileName: 'versioned-assets.json', metaPickKeys: merge(['uid', 'url', 'filename', '_version', 'parent_uid'], this.assetConfig.assetsMetaKeys), + moduleName: 'assets', }); } if (!isEmpty(response)) { @@ -251,7 +360,7 @@ export default class ExportAssets extends BaseClass { `Writing versioned asset: UID=${response.uid}, Version=${response._version}`, this.exportConfig.context, ); - fs?.writeIntoFile([response], { mapKeyVal: true, keyName: ['uid', '_version'] }); + fs?.writeIntoFile([response], { keyName: ['uid', '_version'], mapKeyVal: true }); } }; @@ -263,14 +372,14 @@ export default class ExportAssets extends BaseClass { { apiBatches, apiParams: { - queryParam, module: 'asset', + queryParam, reject: onReject, resolve: onSuccess, }, + concurrencyLimit: this.assetConfig.fetchConcurrency, module: 'versioned assets', totalCount: versionedAssets.length, - concurrencyLimit: this.assetConfig.fetchConcurrency, }, promisifyHandler, ).then(() => { @@ -278,141 +387,32 @@ export default class ExportAssets extends BaseClass { log.info(messageHandler.parse('ASSET_VERSIONED_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } - - getAssetsCount(isDir = false): Promise { - const queryParam: any = { - limit: 1, - ...this.commonQueryParam, - skip: 10 ** 100, - }; - - if (isDir) queryParam.query = { is_dir: true }; - - log.debug( - `Querying count of assets${isDir ? ' (folders only)' : ''} with params: ${JSON.stringify(queryParam)}`, - this.exportConfig.context, + async start(): Promise { + this.assetsRootPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.assetConfig.dirName, ); - return this.stack - .asset() - .query(queryParam) - .count() - .then(({ assets }: any) => { - log.debug(`Received asset count: ${assets}`, this.exportConfig.context); - return assets; - }) - .catch((error: Error) => { - handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_COUNT_QUERY_FAILED')); - }); - } - /** - * @method downloadAssets - * @returns Promise - */ - async downloadAssets(): Promise { - const fs: FsUtility = new FsUtility({ - fileExt: 'json', - createDirIfNotExist: false, - basePath: this.assetsRootPath, - }); - - log.debug('Reading asset metadata for download...', this.exportConfig.context); - const assetsMetaData = fs.getPlainMeta(); + log.debug(`Assets root path resolved to: ${this.assetsRootPath}`, this.exportConfig.context); + log.debug('Fetching assets and folders count...', this.exportConfig.context); + // NOTE step 1: Get assets and it's folder count in parallel + const [assetsCount, assetsFolderCount] = await Promise.all([this.getAssetsCount(), this.getAssetsCount(true)]); - let listOfAssets = values(assetsMetaData).flat(); + log.debug('Fetching assets and folders data...', this.exportConfig.context); + // NOTE step 2: Get assets and it's folder data in parallel + await Promise.all([this.getAssetsFolders(assetsFolderCount), this.getAssets(assetsCount)]); - if (this.assetConfig.includeVersionedAssets) { - const versionedAssetsMetaData = fs.getPlainMeta(pResolve(this.assetsRootPath, 'versions', 'metadata.json')); - listOfAssets.push(...values(versionedAssetsMetaData).flat()); + // NOTE step 3: Get versioned assets + if (!isEmpty(this.versionedAssets) && this.assetConfig.includeVersionedAssets) { + log.debug('Fetching versioned assets metadata...', this.exportConfig.context); + await this.getVersionedAssets(); } - listOfAssets = uniqBy(listOfAssets, 'url'); - log.debug(`Total unique assets to download: ${listOfAssets.length}`, this.exportConfig.context); - - const apiBatches: Array = chunk(listOfAssets, this.assetConfig.downloadLimit); - const downloadedAssetsDirs = await getDirectories(pResolve(this.assetsRootPath, 'files')); - - const onSuccess = ({ response: { data }, additionalInfo }: any) => { - const { asset } = additionalInfo; - const assetFolderPath = pResolve(this.assetsRootPath, 'files', asset.uid); - const assetFilePath = pResolve(assetFolderPath, asset.filename); - - log.debug(`Saving asset to: ${assetFilePath}`, this.exportConfig.context); - - if (!includes(downloadedAssetsDirs, asset.uid)) { - fs.createFolderIfNotExist(assetFolderPath); - } - - const assetWriterStream = createWriteStream(assetFilePath); - assetWriterStream.on('error', (error) => { - handleAndLogError( - error, - { ...this.exportConfig.context, uid: asset.uid, filename: asset.fileName }, - messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), - ); - }); - /** - * NOTE if pipe not working as expected add the following code below to fix the issue - * https://oramind.com/using-streams-efficiently-in-nodejs/ - * import * as stream from "stream"; - * import { promisify } from "util"; - * const finished = promisify(stream.finished); - * await finished(assetWriterStream); - */ - if (this.assetConfig.enableDownloadStatus) { - const str = progress({ - time: 5000, - length: data.headers['content-length'], - }); - str.on('progress', function (progressData) { - console.log(`${asset.filename}: ${Math.round(progressData.percentage)}%`); - }); - data.pipe(str).pipe(assetWriterStream); - } else { - data.pipe(assetWriterStream); - } - - log.success(messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), this.exportConfig.context); - }; - - const onReject = ({ error, additionalInfo }: any) => { - const { asset } = additionalInfo; - handleAndLogError( - error, - { ...this.exportConfig.context, uid: asset.uid, filename: asset.filename }, - messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), - ); - }; - - const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { - const { index, batchIndex } = input; - const asset: any = apiBatches[batchIndex][index]; - const url = this.assetConfig.securedAssets - ? `${asset.url}?authtoken=${configHandler.get('authtoken')}` - : asset.url; - log.debug( - `Preparing to download asset: ${asset.filename} (UID: ${asset.uid}) from URL: ${url}`, - this.exportConfig.context, - ); - return this.makeAPICall({ - reject: onReject, - resolve: onSuccess, - url: encodeURI(url), - module: 'download-asset', - additionalInfo: { asset }, - }); - }; + log.debug('Starting download of all assets...', this.exportConfig.context); + // NOTE step 4: Download all assets + await this.downloadAssets(); - return this.makeConcurrentCall( - { - apiBatches, - module: 'assets download', - totalCount: listOfAssets.length, - concurrencyLimit: this.assetConfig.downloadLimit, - }, - promisifyHandler, - ).then(() => { - log.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); - }); + log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), 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..1a2fd9dda 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -1,54 +1,54 @@ -import map from 'lodash/map'; -import fill from 'lodash/fill'; -import last from 'lodash/last'; +import { log } from '@contentstack/cli-utilities'; import chunk from 'lodash/chunk'; -import isEmpty from 'lodash/isEmpty'; import entries from 'lodash/entries'; +import fill from 'lodash/fill'; +import isEmpty from 'lodash/isEmpty'; import isEqual from 'lodash/isEqual'; -import { log } from '@contentstack/cli-utilities'; +import last from 'lodash/last'; +import map from 'lodash/map'; import { ExportConfig, ModuleClassParams } from '../../types'; export type ApiOptions = { - uid?: string; - url?: string; + additionalInfo?: Record; module: ApiModuleType; queryParam?: Record; - resolve: (value: any) => void; reject: (error: any) => void; - additionalInfo?: Record; + resolve: (value: any) => void; + uid?: string; + url?: string; }; export type EnvType = { - module: string; - totalCount: number; apiBatches?: number[]; - concurrencyLimit: number; apiParams?: ApiOptions; + concurrencyLimit: number; + module: string; + totalCount: number; }; export type CustomPromiseHandlerInput = { - index: number; + apiParams?: ApiOptions; batchIndex: number; element?: Record; - apiParams?: ApiOptions; + index: number; isLastRequest: boolean; }; export type CustomPromiseHandler = (input: CustomPromiseHandlerInput) => Promise; export type ApiModuleType = - | 'stack' | 'asset' | 'assets' - | 'entry' - | 'entries' | 'content-type' | 'content-types' - | 'stacks' - | 'versioned-entries' | 'download-asset' - | 'export-taxonomy'; + | 'entries' + | 'entry' + | 'export-taxonomy' + | 'stack' + | 'stacks' + | 'versioned-entries'; export default abstract class BaseClass { readonly client: any; @@ -63,67 +63,25 @@ export default abstract class BaseClass { return this.client; } + protected applyQueryFilters(requestObject: any, moduleName: string): any { + if (this.exportConfig.query?.modules?.[moduleName]) { + const moduleQuery = this.exportConfig.query.modules[moduleName]; + // Merge the query parameters with existing requestObject + if (moduleQuery) { + if (!requestObject.query) { + requestObject.query = moduleQuery; + } + Object.assign(requestObject.query, moduleQuery); + } + } + return requestObject; + } + delay(ms: number): Promise { /* eslint-disable no-promise-executor-return */ return new Promise((resolve) => setTimeout(resolve, ms <= 0 ? 0 : ms)); } - makeConcurrentCall(env: EnvType, promisifyHandler?: CustomPromiseHandler): Promise { - const { module, apiBatches, totalCount, apiParams, concurrencyLimit } = env; - - /* eslint-disable no-async-promise-executor */ - return new Promise(async (resolve) => { - let batchNo = 0; - let isLastRequest = false; - const batch = fill(Array.from({ length: Number.parseInt(String(totalCount / 100), 10) }), 100); - - if (totalCount % 100) batch.push(100); - - const batches: Array = - apiBatches || - chunk( - map(batch, (skip: number, i: number) => skip * i), - concurrencyLimit, - ); - - /* eslint-disable no-promise-executor-return */ - if (isEmpty(batches)) return resolve(); - - for (const [batchIndex, batch] of entries(batches)) { - batchNo += 1; - const allPromise = []; - const start = Date.now(); - - for (const [index, element] of entries(batch)) { - let promise; - isLastRequest = isEqual(last(batch), element) && isEqual(last(batches), batch); - - if (promisifyHandler instanceof Function) { - promise = promisifyHandler({ - apiParams, - element, - isLastRequest, - index: Number(index), - batchIndex: Number(batchIndex), - }); - } else if (apiParams?.queryParam) { - apiParams.queryParam.skip = element; - promise = this.makeAPICall(apiParams, isLastRequest); - } - - allPromise.push(promise); - } - - /* eslint-disable no-await-in-loop */ - await Promise.allSettled(allPromise); - /* eslint-disable no-await-in-loop */ - await this.logMsgAndWaitIfRequired(module, start, batchNo); - - if (isLastRequest) resolve(); - } - }); - } - /** * @method logMsgAndWaitIfRequired * @param module string @@ -157,7 +115,7 @@ export default abstract class BaseClass { * @returns Promise */ makeAPICall( - { module: moduleName, reject, resolve, url = '', uid = '', additionalInfo, queryParam = {} }: ApiOptions, + { additionalInfo, module: moduleName, queryParam = {}, reject, resolve, uid = '', url = '' }: ApiOptions, isLastRequest = false, ): Promise { switch (moduleName) { @@ -165,21 +123,21 @@ export default abstract class BaseClass { return this.stack .asset(uid) .fetch(queryParam) - .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) - .catch((error: Error) => reject({ error, isLastRequest, additionalInfo })); + .then((response: any) => resolve({ additionalInfo, isLastRequest, response })) + .catch((error: Error) => reject({ additionalInfo, error, isLastRequest })); 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) => resolve({ additionalInfo, isLastRequest, response })) + .catch((error: Error) => reject({ additionalInfo, error, isLastRequest })); 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 })); + .download({ responseType: 'stream', url }) + .then((response: any) => resolve({ additionalInfo, isLastRequest, response })) + .catch((error: any) => reject({ additionalInfo, error, isLastRequest })); case 'export-taxonomy': return this.stack .taxonomy(uid) @@ -191,17 +149,59 @@ export default abstract class BaseClass { } } - protected applyQueryFilters(requestObject: any, moduleName: string): any { - if (this.exportConfig.query?.modules?.[moduleName]) { - const moduleQuery = this.exportConfig.query.modules[moduleName]; - // Merge the query parameters with existing requestObject - if (moduleQuery) { - if (!requestObject.query) { - requestObject.query = moduleQuery; + makeConcurrentCall(env: EnvType, promisifyHandler?: CustomPromiseHandler): Promise { + const { apiBatches, apiParams, concurrencyLimit, module, totalCount } = env; + + /* eslint-disable no-async-promise-executor */ + return new Promise(async (resolve) => { + let batchNo = 0; + let isLastRequest = false; + const batch = fill(Array.from({ length: Number.parseInt(String(totalCount / 100), 10) }), 100); + + if (totalCount % 100) batch.push(100); + + const batches: Array = + apiBatches || + chunk( + map(batch, (skip: number, i: number) => skip * i), + concurrencyLimit, + ); + + /* eslint-disable no-promise-executor-return */ + if (isEmpty(batches)) return resolve(); + + for (const [batchIndex, batch] of entries(batches)) { + batchNo += 1; + const allPromise = []; + const start = Date.now(); + + for (const [index, element] of entries(batch)) { + let promise; + isLastRequest = isEqual(last(batch), element) && isEqual(last(batches), batch); + + if (promisifyHandler instanceof Function) { + promise = promisifyHandler({ + apiParams, + batchIndex: Number(batchIndex), + element, + index: Number(index), + isLastRequest, + }); + } else if (apiParams?.queryParam) { + apiParams.queryParam.skip = element; + promise = this.makeAPICall(apiParams, isLastRequest); + } + + allPromise.push(promise); } - Object.assign(requestObject.query, moduleQuery); + + /* eslint-disable no-await-in-loop */ + await Promise.allSettled(allPromise); + /* eslint-disable no-await-in-loop */ + await this.logMsgAndWaitIfRequired(module, start, batchNo); + + if (isLastRequest) resolve(); } - } - return requestObject; + }); } } diff --git a/packages/contentstack-export/src/export/modules/composable-studio.ts b/packages/contentstack-export/src/export/modules/composable-studio.ts index 8faff8c2b..143932efe 100644 --- a/packages/contentstack-export/src/export/modules/composable-studio.ts +++ b/packages/contentstack-export/src/export/modules/composable-studio.ts @@ -1,25 +1,25 @@ -import { resolve as pResolve } from 'node:path'; import { + HttpClient, + authenticationHandler, cliux, + handleAndLogError, isAuthenticated, log, messageHandler, - handleAndLogError, - HttpClient, - authenticationHandler, } from '@contentstack/cli-utilities'; +import { resolve as pResolve } from 'node:path'; +import { ComposableStudioConfig, ComposableStudioProject, ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil, getOrgUid } from '../../utils'; -import { ModuleClassParams, ComposableStudioConfig, ExportConfig, ComposableStudioProject } from '../../types'; export default class ExportComposableStudio { - protected composableStudioConfig: ComposableStudioConfig; - protected composableStudioProject: ComposableStudioProject | null = null; protected apiClient: HttpClient; + protected composableStudioConfig: ComposableStudioConfig; public composableStudioPath: string; + protected composableStudioProject: ComposableStudioProject | null = null; public exportConfig: ExportConfig; - constructor({ exportConfig }: Omit) { + constructor({ exportConfig }: Omit) { this.exportConfig = exportConfig; this.composableStudioConfig = exportConfig.modules['composable-studio']; this.exportConfig.context.module = 'composable-studio'; @@ -29,34 +29,6 @@ export default class ExportComposableStudio { this.apiClient.baseUrl(`${this.composableStudioConfig.apiBaseUrl}/${this.composableStudioConfig.apiVersion}`); } - async start(): Promise { - log.debug('Starting Studio project export process...', this.exportConfig.context); - - if (!isAuthenticated()) { - cliux.print( - 'WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in', - { color: 'yellow' }, - ); - return Promise.resolve(); - } - - this.composableStudioPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.composableStudioConfig.dirName, - ); - log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.composableStudioPath); - log.debug('Created Studio directory', this.exportConfig.context); - - this.exportConfig.org_uid = this.exportConfig.org_uid || (await getOrgUid(this.exportConfig)); - log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context); - - await this.exportProjects(); - log.debug('Studio project export process completed', this.exportConfig.context); - } - /** * Export Studio projects connected to the current stack */ @@ -84,8 +56,8 @@ export default class ExportComposableStudio { // Set organization_uid header this.apiClient.headers({ - organization_uid: this.exportConfig.org_uid, Accept: 'application/json', + organization_uid: this.exportConfig.org_uid, }); const apiUrl = '/projects'; @@ -135,4 +107,32 @@ export default class ExportComposableStudio { }); } } + + async start(): Promise { + log.debug('Starting Studio project export process...', this.exportConfig.context); + + if (!isAuthenticated()) { + cliux.print( + 'WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in', + { color: 'yellow' }, + ); + return Promise.resolve(); + } + + this.composableStudioPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.composableStudioConfig.dirName, + ); + log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.composableStudioPath); + log.debug('Created Studio directory', this.exportConfig.context); + + this.exportConfig.org_uid = this.exportConfig.org_uid || (await getOrgUid(this.exportConfig)); + log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context); + + await this.exportProjects(); + log.debug('Studio project export process completed', this.exportConfig.context); + } } diff --git a/packages/contentstack-export/src/export/modules/content-types.ts b/packages/contentstack-export/src/export/modules/content-types.ts index ad571929d..04a1731e8 100644 --- a/packages/contentstack-export/src/export/modules/content-types.ts +++ b/packages/contentstack-export/src/export/modules/content-types.ts @@ -1,47 +1,47 @@ -import * as path from 'path'; import { ContentstackClient, handleAndLogError, - messageHandler, log, + messageHandler, sanitizePath, } from '@contentstack/cli-utilities'; +import * as path from 'path'; -import BaseClass from './base-class'; -import { fsUtil, executeTask } from '../../utils'; import { ExportConfig, ModuleClassParams } from '../../types'; +import { executeTask, fsUtil } from '../../utils'; +import BaseClass from './base-class'; export default class ContentTypesExport extends BaseClass { - private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - private qs: { - include_count: boolean; - asc: string; - skip?: number; - limit?: number; - include_global_field_schema: boolean; - uid?: Record; - }; + private contentTypes: Record[]; private contentTypesConfig: { dirName?: string; + fetchConcurrency?: number; fileName?: string; + limit?: number; validKeys?: string[]; - fetchConcurrency?: number; writeConcurrency?: number; - limit?: number; }; private contentTypesDirPath: string; - private contentTypes: Record[]; + private qs: { + asc: string; + include_count: boolean; + include_global_field_schema: boolean; + limit?: number; + skip?: number; + uid?: Record; + }; + private stackAPIClient: ReturnType; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.stackAPIClient = stackAPIClient; this.contentTypesConfig = exportConfig.modules['content-types']; this.qs = { - include_count: true, asc: 'updated_at', - limit: this.contentTypesConfig.limit, + include_count: true, include_global_field_schema: true, + limit: this.contentTypesConfig.limit, }; // If content type id is provided then use it as part of query @@ -61,21 +61,6 @@ export default class ContentTypesExport extends BaseClass { this.exportConfig.context.module = 'content-types'; } - async start() { - try { - log.debug('Starting content types export process...', this.exportConfig.context); - await fsUtil.makeDirectory(this.contentTypesDirPath); - log.debug(`Created directory at: '${this.contentTypesDirPath}'.`, this.exportConfig.context); - - await this.getContentTypes(); - await this.writeContentTypes(this.contentTypes); - - log.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - } - } - async getContentTypes(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -120,6 +105,21 @@ export default class ContentTypesExport extends BaseClass { return updatedContentTypes; } + async start() { + try { + log.debug('Starting content types export process...', this.exportConfig.context); + await fsUtil.makeDirectory(this.contentTypesDirPath); + log.debug(`Created directory at: '${this.contentTypesDirPath}'.`, this.exportConfig.context); + + await this.getContentTypes(); + await this.writeContentTypes(this.contentTypes); + + log.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + } + } + async writeContentTypes(contentTypes: Record[]) { log.debug(`Writing ${contentTypes?.length} content types to disk...`, this.exportConfig.context); diff --git a/packages/contentstack-export/src/export/modules/custom-roles.ts b/packages/contentstack-export/src/export/modules/custom-roles.ts index 1d9d10529..bbbe7d8bb 100644 --- a/packages/contentstack-export/src/export/modules/custom-roles.ts +++ b/packages/contentstack-export/src/export/modules/custom-roles.ts @@ -1,62 +1,39 @@ -import keys from 'lodash/keys'; +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import find from 'lodash/find'; import forEach from 'lodash/forEach'; +import keys from 'lodash/keys'; import values from 'lodash/values'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { CustomRoleConfig, ModuleClassParams } from '../../types'; +import { fsUtil } from '../../utils'; +import BaseClass from './base-class'; export default class ExportCustomRoles extends BaseClass { + public customRolesLocalesFilepath: string; + public rolesFolderPath: string; private customRoles: Record; - private existingRoles: Record; private customRolesConfig: CustomRoleConfig; - private sourceLocalesMap: Record; + private existingRoles: Record; private localesMap: Record; - public rolesFolderPath: string; - public customRolesLocalesFilepath: string; + private sourceLocalesMap: Record; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.customRoles = {}; this.customRolesConfig = exportConfig.modules.customRoles; - this.existingRoles = { Admin: 1, Developer: 1, 'Content Manager': 1 }; + this.existingRoles = { Admin: 1, 'Content Manager': 1, Developer: 1 }; this.localesMap = {}; this.sourceLocalesMap = {}; this.exportConfig.context.module = 'custom-roles'; } - async start(): Promise { - log.debug('Starting export process for custom roles...', this.exportConfig.context); - - this.rolesFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.customRolesConfig.dirName, - ); - log.debug(`Custom roles folder path is: ${this.rolesFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.rolesFolderPath); - log.debug('Custom roles directory created.', this.exportConfig.context); - - this.customRolesLocalesFilepath = pResolve(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName); - log.debug(`Custom roles locales file path is: ${this.customRolesLocalesFilepath}`, this.exportConfig.context); - - await this.getCustomRoles(); - await this.getLocales(); - await this.getCustomRolesLocales(); - - log.debug(`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`, this.exportConfig.context); - } - async getCustomRoles(): Promise { log.debug('Fetching all roles from the stack...', this.exportConfig.context); const roles = await this.stack .role() - .fetchAll({ include_rules: true, include_permissions: true }) + .fetchAll({ include_permissions: true, include_rules: true }) .then((data: any) => { log.debug(`Fetched ${data.items?.length || 0} roles from the stack.`, this.exportConfig.context); return data; @@ -85,30 +62,6 @@ export default class ExportCustomRoles extends BaseClass { fsUtil.writeFile(customRolesFilePath, this.customRoles); } - async getLocales() { - log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context); - - const locales = await this.stack - .locale() - .query({}) - .find() - .then((data: any) => { - log.debug(`Fetched ${data?.items?.length || 0} locales.`, this.exportConfig.context); - return data; - }) - .catch((err: any) => { - log.debug('An error occurred while fetching locales.', this.exportConfig.context); - return handleAndLogError(err, { ...this.exportConfig.context }); - }); - - for (const locale of locales.items) { - log.debug(`Mapping locale: ${locale?.name} (${locale?.uid})`, this.exportConfig.context); - this.sourceLocalesMap[locale.uid] = locale; - } - - log.debug(`Mapped ${Object.keys(this.sourceLocalesMap).length} source locales.`, this.exportConfig.context); - } - async getCustomRolesLocales() { log.debug('Processing custom roles locales mapping...', this.exportConfig.context); @@ -144,4 +97,51 @@ export default class ExportCustomRoles extends BaseClass { log.debug('No custom role locales found to process.', this.exportConfig.context); } } + + async getLocales() { + log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context); + + const locales = await this.stack + .locale() + .query({}) + .find() + .then((data: any) => { + log.debug(`Fetched ${data?.items?.length || 0} locales.`, this.exportConfig.context); + return data; + }) + .catch((err: any) => { + log.debug('An error occurred while fetching locales.', this.exportConfig.context); + return handleAndLogError(err, { ...this.exportConfig.context }); + }); + + for (const locale of locales.items) { + log.debug(`Mapping locale: ${locale?.name} (${locale?.uid})`, this.exportConfig.context); + this.sourceLocalesMap[locale.uid] = locale; + } + + log.debug(`Mapped ${Object.keys(this.sourceLocalesMap).length} source locales.`, this.exportConfig.context); + } + + async start(): Promise { + log.debug('Starting export process for custom roles...', this.exportConfig.context); + + this.rolesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.customRolesConfig.dirName, + ); + log.debug(`Custom roles folder path is: ${this.rolesFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.rolesFolderPath); + log.debug('Custom roles directory created.', this.exportConfig.context); + + this.customRolesLocalesFilepath = pResolve(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName); + log.debug(`Custom roles locales file path is: ${this.customRolesLocalesFilepath}`, this.exportConfig.context); + + await this.getCustomRoles(); + await this.getLocales(); + await this.getCustomRolesLocales(); + + log.debug(`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`, this.exportConfig.context); + } } diff --git a/packages/contentstack-export/src/export/modules/entries.ts b/packages/contentstack-export/src/export/modules/entries.ts index 743b471ea..5afbb2127 100644 --- a/packages/contentstack-export/src/export/modules/entries.ts +++ b/packages/contentstack-export/src/export/modules/entries.ts @@ -1,33 +1,32 @@ -import * as path from 'path'; -import { ContentstackClient, FsUtility, handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; +import { ContentstackClient, FsUtility, handleAndLogError, log, messageHandler , sanitizePath } from '@contentstack/cli-utilities'; import { Export, ExportProjects } from '@contentstack/cli-variants'; -import { sanitizePath } from '@contentstack/cli-utilities'; +import * as path from 'path'; +import { ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil } from '../../utils'; import BaseClass, { ApiOptions } from './base-class'; -import { ExportConfig, ModuleClassParams } from '../../types'; export default class EntriesExport extends BaseClass { - private stackAPIClient: ReturnType; public exportConfig: ExportConfig; + public exportVariantEntry = false; private entriesConfig: { + batchLimit?: number; + chunkFileSize?: number; dirName?: string; + exportVersions: boolean; + fetchConcurrency?: number; fileName?: string; invalidKeys?: string[]; - fetchConcurrency?: number; - writeConcurrency?: number; limit?: number; - chunkFileSize?: number; - batchLimit?: number; - exportVersions: boolean; + writeConcurrency?: number; }; - private variantEntries!: any; private entriesDirPath: string; - private localesFilePath: string; - private schemaFilePath: string; private entriesFileHelper: FsUtility; + private localesFilePath: string; private projectInstance: ExportProjects; - public exportVariantEntry: boolean = false; + private schemaFilePath: string; + private stackAPIClient: ReturnType; + private variantEntries!: any; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -55,66 +54,6 @@ export default class EntriesExport extends BaseClass { this.exportConfig.context.module = 'entries'; } - async start() { - try { - log.debug('Starting entries export process...', this.exportConfig.context); - const locales = fsUtil.readFile(this.localesFilePath) as Array>; - if (!Array.isArray(locales) || locales?.length === 0) { - log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); - } else { - log.debug(`Loaded ${locales?.length} locales from ${this.localesFilePath}`, this.exportConfig.context); - } - - const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; - if (contentTypes?.length === 0) { - log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); - return; - } - log.debug(`Loaded ${contentTypes?.length} content types from ${this.schemaFilePath}`, this.exportConfig.context); - - // NOTE Check if variant is enabled in specific stack - if (this.exportConfig.personalizationEnabled) { - log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context); - let project_id; - try { - const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey }); - - if (project && project[0]?.uid) { - project_id = project[0].uid; - this.exportVariantEntry = true; - log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context); - } - - this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - } - } - - const entryRequestOptions = this.createRequestObjects(locales, contentTypes); - log.debug( - `Created ${entryRequestOptions.length} entry request objects for processing`, - this.exportConfig.context, - ); - - for (let entryRequestOption of entryRequestOptions) { - log.debug( - `Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, - this.exportConfig.context, - ); - await this.getEntries(entryRequestOption); - this.entriesFileHelper?.completeFile(true); - log.success( - messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), - this.exportConfig.context, - ); - } - log.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - } - } - createRequestObjects( locales: Array>, contentTypes: Array>, @@ -131,10 +70,10 @@ export default class EntriesExport extends BaseClass { log.debug(`Found ${contentTypes.length} content types for export`, this.exportConfig.context); } - let requestObjects: Array> = []; + const requestObjects: Array> = []; contentTypes.forEach((contentType) => { if (Object.keys(locales).length !== 0) { - for (let locale in locales) { + for (const locale in locales) { requestObjects.push({ contentType: contentType.uid, locale: locales[locale].code, @@ -151,17 +90,96 @@ export default class EntriesExport extends BaseClass { return requestObjects; } + async entryVersionHandler({ + apiParams, + element: entry, + }: { + apiParams: ApiOptions; + element: Record; + isLastRequest: boolean; + }) { + log.debug(`Processing versioned entry: ${entry.uid}`, this.exportConfig.context); + + return new Promise(async (resolve, reject) => { + return await this.getEntryByVersion(apiParams.queryParam, entry) + .then((response) => { + log.debug(`Successfully fetched versions for entry UID: ${entry.uid}`, this.exportConfig.context); + apiParams.resolve({ + apiData: entry, + response, + }); + resolve(true); + }) + .catch((error) => { + log.debug(`Failed to fetch versions for entry UID: ${entry.uid}`, this.exportConfig.context); + apiParams.reject({ + apiData: entry, + error, + }); + reject(true); + }); + }); + } + + async fetchEntriesVersions( + entries: any, + options: { contentType: string; locale: string; versionedEntryPath: string }, + ): Promise { + log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context); + + const onSuccess = ({ apiData: entry, response }: any) => { + const versionFilePath = path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)); + log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context); + fsUtil.writeFile(versionFilePath, response); + log.success( + messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), + this.exportConfig.context, + ); + }; + const onReject = ({ apiData: { uid } = undefined, error }: any) => { + log.debug(`Failed to fetch versioned entry for uid: ${uid}`, this.exportConfig.context); + handleAndLogError( + error, + { + ...this.exportConfig.context, + uid, + }, + messageHandler.parse('ENTRIES_EXPORT_VERSIONS_FAILED', uid), + ); + }; + + log.debug( + `Starting concurrent calls for versioned entries with batch limit: ${this.entriesConfig.batchLimit}`, + this.exportConfig.context, + ); + return await this.makeConcurrentCall( + { + apiBatches: [entries], + apiParams: { + module: 'versioned-entries', + queryParam: options, + reject: onReject, + resolve: onSuccess, + }, + concurrencyLimit: this.entriesConfig.batchLimit, + module: 'versioned-entries', + totalCount: entries.length, + }, + this.entryVersionHandler.bind(this), + ); + } + async getEntries(options: Record): Promise { options.skip = options.skip || 0; - let requestObject = { - locale: options.locale, - skip: options.skip, - limit: this.entriesConfig.limit, + const requestObject = { include_count: true, include_publish_details: true, + limit: this.entriesConfig.limit, + locale: options.locale, query: { locale: options.locale, }, + skip: options.skip, }; this.applyQueryFilters(requestObject, 'entries'); @@ -198,11 +216,11 @@ export default class EntriesExport extends BaseClass { log.debug(`Creating directory for entries at: ${entryBasePath}`, this.exportConfig.context); await fsUtil.makeDirectory(entryBasePath); this.entriesFileHelper = new FsUtility({ - moduleName: 'entries', - indexFileName: 'index.json', basePath: entryBasePath, chunkFileSize: this.entriesConfig.chunkFileSize, + indexFileName: 'index.json', keepMetadata: false, + moduleName: 'entries', omitKeys: this.entriesConfig.invalidKeys, }); log.debug('Initialized FsUtility for writing entries', this.exportConfig.context); @@ -213,7 +231,7 @@ export default class EntriesExport extends BaseClass { if (this.entriesConfig.exportVersions) { log.debug('Exporting entry versions is enabled.', this.exportConfig.context); - let versionedEntryPath = path.join( + const versionedEntryPath = path.join( sanitizePath(this.entriesDirPath), sanitizePath(options.contentType), sanitizePath(options.locale), @@ -222,8 +240,8 @@ export default class EntriesExport extends BaseClass { log.debug(`Creating versioned entries directory at: ${versionedEntryPath}.`, this.exportConfig.context); fsUtil.makeDirectory(versionedEntryPath); await this.fetchEntriesVersions(entriesSearchResponse.items, { - locale: options.locale, contentType: options.contentType, + locale: options.locale, versionedEntryPath, }); } @@ -232,9 +250,9 @@ export default class EntriesExport extends BaseClass { if (this.exportVariantEntry) { log.debug('Exporting variant entries for base entries', this.exportConfig.context); await this.variantEntries.exportVariantEntry({ - locale: options.locale, contentTypeUid: options.contentType, entries: entriesSearchResponse.items, + locale: options.locale, }); } @@ -251,95 +269,16 @@ export default class EntriesExport extends BaseClass { } } - async fetchEntriesVersions( - entries: any, - options: { locale: string; contentType: string; versionedEntryPath: string }, - ): Promise { - log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context); - - const onSuccess = ({ response, apiData: entry }: any) => { - const versionFilePath = path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)); - log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context); - fsUtil.writeFile(versionFilePath, response); - log.success( - messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), - this.exportConfig.context, - ); - }; - const onReject = ({ error, apiData: { uid } = undefined }: any) => { - log.debug(`Failed to fetch versioned entry for uid: ${uid}`, this.exportConfig.context); - handleAndLogError( - error, - { - ...this.exportConfig.context, - uid, - }, - messageHandler.parse('ENTRIES_EXPORT_VERSIONS_FAILED', uid), - ); - }; - - log.debug( - `Starting concurrent calls for versioned entries with batch limit: ${this.entriesConfig.batchLimit}`, - this.exportConfig.context, - ); - return await this.makeConcurrentCall( - { - apiBatches: [entries], - module: 'versioned-entries', - totalCount: entries.length, - concurrencyLimit: this.entriesConfig.batchLimit, - apiParams: { - module: 'versioned-entries', - queryParam: options, - resolve: onSuccess, - reject: onReject, - }, - }, - this.entryVersionHandler.bind(this), - ); - } - - async entryVersionHandler({ - apiParams, - element: entry, - }: { - apiParams: ApiOptions; - element: Record; - isLastRequest: boolean; - }) { - log.debug(`Processing versioned entry: ${entry.uid}`, this.exportConfig.context); - - return new Promise(async (resolve, reject) => { - return await this.getEntryByVersion(apiParams.queryParam, entry) - .then((response) => { - log.debug(`Successfully fetched versions for entry UID: ${entry.uid}`, this.exportConfig.context); - apiParams.resolve({ - response, - apiData: entry, - }); - resolve(true); - }) - .catch((error) => { - log.debug(`Failed to fetch versions for entry UID: ${entry.uid}`, this.exportConfig.context); - apiParams.reject({ - error, - apiData: entry, - }); - reject(true); - }); - }); - } - async getEntryByVersion( options: any, entry: Record, entries: Array> = [], ): Promise { const queryRequestObject = { - locale: options.locale, except: { BASE: this.entriesConfig.invalidKeys, }, + locale: options.locale, version: entry._version, }; @@ -365,4 +304,64 @@ export default class EntriesExport extends BaseClass { ); return entries; } + + async start() { + try { + log.debug('Starting entries export process...', this.exportConfig.context); + const locales = fsUtil.readFile(this.localesFilePath) as Array>; + if (!Array.isArray(locales) || locales?.length === 0) { + log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); + } else { + log.debug(`Loaded ${locales?.length} locales from ${this.localesFilePath}`, this.exportConfig.context); + } + + const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; + if (contentTypes?.length === 0) { + log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); + return; + } + log.debug(`Loaded ${contentTypes?.length} content types from ${this.schemaFilePath}`, this.exportConfig.context); + + // NOTE Check if variant is enabled in specific stack + if (this.exportConfig.personalizationEnabled) { + log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context); + let project_id; + try { + const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey }); + + if (project && project[0]?.uid) { + project_id = project[0].uid; + this.exportVariantEntry = true; + log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context); + } + + this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + } + } + + const entryRequestOptions = this.createRequestObjects(locales, contentTypes); + log.debug( + `Created ${entryRequestOptions.length} entry request objects for processing`, + this.exportConfig.context, + ); + + for (const entryRequestOption of entryRequestOptions) { + log.debug( + `Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, + this.exportConfig.context, + ); + await this.getEntries(entryRequestOption); + this.entriesFileHelper?.completeFile(true); + log.success( + messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), + this.exportConfig.context, + ); + } + log.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + } + } } diff --git a/packages/contentstack-export/src/export/modules/environments.ts b/packages/contentstack-export/src/export/modules/environments.ts index 85e9f8af3..b0538c839 100644 --- a/packages/contentstack-export/src/export/modules/environments.ts +++ b/packages/contentstack-export/src/export/modules/environments.ts @@ -1,16 +1,16 @@ -import { resolve as pResolve } from 'node:path'; -import omit from 'lodash/omit'; +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; +import omit from 'lodash/omit'; +import { resolve as pResolve } from 'node:path'; -import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { EnvironmentConfig, ModuleClassParams } from '../../types'; +import { fsUtil } from '../../utils'; +import BaseClass from './base-class'; export default class ExportEnvironments extends BaseClass { - private environments: Record; - private environmentConfig: EnvironmentConfig; public environmentsFolderPath: string; + private environmentConfig: EnvironmentConfig; + private environments: Record; private qs: { include_count: boolean; skip?: number; @@ -24,34 +24,6 @@ export default class ExportEnvironments extends BaseClass { this.exportConfig.context.module = 'environments'; } - async start(): Promise { - log.debug('Starting environment export process...', this.exportConfig.context); - this.environmentsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.environmentConfig.dirName, - ); - log.debug(`Environments folder path is: ${this.environmentsFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.environmentsFolderPath); - log.debug('Environments directory created.', this.exportConfig.context); - - await this.getEnvironments(); - log.debug(`Retrieved ${Object.keys(this.environments).length} environments.`, this.exportConfig.context); - - if (this.environments === undefined || isEmpty(this.environments)) { - log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); - } else { - const environmentsFilePath = pResolve(this.environmentsFolderPath, this.environmentConfig.fileName); - log.debug(`Writing environments to: ${environmentsFilePath}.`, this.exportConfig.context); - fsUtil.writeFile(environmentsFilePath, this.environments); - log.success( - messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), - this.exportConfig.context, - ); - } - } - async getEnvironments(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -67,7 +39,7 @@ export default class ExportEnvironments extends BaseClass { .query(this.qs) .find() .then(async (data: any) => { - const { items, count } = data; + const { count, items } = data; log.debug(`Fetched ${items?.length || 0} environments out of ${count} total.`, this.exportConfig.context); if (items?.length) { @@ -104,4 +76,32 @@ export default class ExportEnvironments extends BaseClass { log.debug(`Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`, this.exportConfig.context); } + + async start(): Promise { + log.debug('Starting environment export process...', this.exportConfig.context); + this.environmentsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.environmentConfig.dirName, + ); + log.debug(`Environments folder path is: ${this.environmentsFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.environmentsFolderPath); + log.debug('Environments directory created.', this.exportConfig.context); + + await this.getEnvironments(); + log.debug(`Retrieved ${Object.keys(this.environments).length} environments.`, this.exportConfig.context); + + if (this.environments === undefined || isEmpty(this.environments)) { + log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); + } else { + const environmentsFilePath = pResolve(this.environmentsFolderPath, this.environmentConfig.fileName); + log.debug(`Writing environments to: ${environmentsFilePath}.`, this.exportConfig.context); + fsUtil.writeFile(environmentsFilePath, this.environments); + log.success( + messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), + this.exportConfig.context, + ); + } + } } diff --git a/packages/contentstack-export/src/export/modules/extensions.ts b/packages/contentstack-export/src/export/modules/extensions.ts index 5da610ec2..2abfa827b 100644 --- a/packages/contentstack-export/src/export/modules/extensions.ts +++ b/packages/contentstack-export/src/export/modules/extensions.ts @@ -1,16 +1,16 @@ -import omit from 'lodash/omit'; +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; +import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { ExtensionsConfig, ModuleClassParams } from '../../types'; +import { fsUtil } from '../../utils'; +import BaseClass from './base-class'; export default class ExportExtensions extends BaseClass { - private extensionsFolderPath: string; - private extensions: Record; public extensionConfig: ExtensionsConfig; + private extensions: Record; + private extensionsFolderPath: string; private qs: { include_count: boolean; skip?: number; @@ -25,35 +25,6 @@ export default class ExportExtensions extends BaseClass { this.exportConfig.context.module = 'extensions'; } - async start(): Promise { - log.debug('Starting extensions export process...', this.exportConfig.context); - - this.extensionsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.extensionConfig.dirName, - ); - log.debug(`Extensions folder path is: ${this.extensionsFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.extensionsFolderPath); - log.debug('Extensions directory created.', this.exportConfig.context); - - await this.getExtensions(); - log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions.`, this.exportConfig.context); - - if (this.extensions === undefined || isEmpty(this.extensions)) { - log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); - } else { - const extensionsFilePath = pResolve(this.extensionsFolderPath, this.extensionConfig.fileName); - log.debug(`Writing extensions to: ${extensionsFilePath}.`, this.exportConfig.context); - fsUtil.writeFile(extensionsFilePath, this.extensions); - log.success( - messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ), - this.exportConfig.context, - ); - } - } - async getExtensions(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -69,7 +40,7 @@ export default class ExportExtensions extends BaseClass { .query(this.qs) .find() .then(async (data: any) => { - const { items, count } = data; + const { count, items } = data; log.debug(`Fetched ${items?.length || 0} extensions out of ${count}.`, this.exportConfig.context); if (items?.length) { @@ -106,4 +77,33 @@ export default class ExportExtensions extends BaseClass { log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}.`, this.exportConfig.context); } + + async start(): Promise { + log.debug('Starting extensions export process...', this.exportConfig.context); + + this.extensionsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.extensionConfig.dirName, + ); + log.debug(`Extensions folder path is: ${this.extensionsFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.extensionsFolderPath); + log.debug('Extensions directory created.', this.exportConfig.context); + + await this.getExtensions(); + log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions.`, this.exportConfig.context); + + if (this.extensions === undefined || isEmpty(this.extensions)) { + log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); + } else { + const extensionsFilePath = pResolve(this.extensionsFolderPath, this.extensionConfig.fileName); + log.debug(`Writing extensions to: ${extensionsFilePath}.`, this.exportConfig.context); + fsUtil.writeFile(extensionsFilePath, this.extensions); + log.success( + messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ), + this.exportConfig.context, + ); + } + } } diff --git a/packages/contentstack-export/src/export/modules/global-fields.ts b/packages/contentstack-export/src/export/modules/global-fields.ts index 421665cfc..93c4e5a45 100644 --- a/packages/contentstack-export/src/export/modules/global-fields.ts +++ b/packages/contentstack-export/src/export/modules/global-fields.ts @@ -1,47 +1,47 @@ -import * as path from 'path'; import { ContentstackClient, handleAndLogError, - messageHandler, log, + messageHandler, sanitizePath, } from '@contentstack/cli-utilities'; +import * as path from 'path'; -import { fsUtil } from '../../utils'; import { ExportConfig, ModuleClassParams } from '../../types'; +import { fsUtil } from '../../utils'; import BaseClass from './base-class'; export default class GlobalFieldsExport extends BaseClass { - private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - private qs: { - include_count: boolean; - asc: string; - skip?: number; - limit?: number; - include_global_field_schema?: boolean; - }; + private globalFields: Record[]; private globalFieldsConfig: { dirName?: string; + fetchConcurrency?: number; fileName?: string; + limit?: number; validKeys?: string[]; - fetchConcurrency?: number; writeConcurrency?: number; - limit?: number; }; private globalFieldsDirPath: string; - private globalFields: Record[]; + private qs: { + asc: string; + include_count: boolean; + include_global_field_schema?: boolean; + limit?: number; + skip?: number; + }; + private stackAPIClient: ReturnType; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.stackAPIClient = stackAPIClient; this.globalFieldsConfig = exportConfig.modules['global-fields']; this.qs = { - skip: 0, asc: 'updated_at', include_count: true, - limit: this.globalFieldsConfig.limit, include_global_field_schema: true, + limit: this.globalFieldsConfig.limit, + skip: 0, }; this.globalFieldsDirPath = path.resolve( sanitizePath(exportConfig.data), @@ -53,38 +53,14 @@ export default class GlobalFieldsExport extends BaseClass { this.exportConfig.context.module = 'global-fields'; } - async start() { - try { - log.debug('Starting export process for global fields...', this.exportConfig.context); - log.debug(`Global fields directory path: '${this.globalFieldsDirPath}'`, this.exportConfig.context); - await fsUtil.makeDirectory(this.globalFieldsDirPath); - log.debug('Created global fields directory.', this.exportConfig.context); - - await this.getGlobalFields(); - log.debug(`Retrieved ${this.globalFields.length} global fields.`, this.exportConfig.context); - - const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName); - log.debug(`Writing global fields to: '${globalFieldsFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(globalFieldsFilePath, this.globalFields); - - log.success( - messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), - this.exportConfig.context, - ); - } catch (error) { - log.debug('An error occurred during global fields export.', this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context }); - } - } - - async getGlobalFields(skip: number = 0): Promise { + async getGlobalFields(skip = 0): Promise { if (skip) { this.qs.skip = skip; log.debug(`Fetching global fields with skip: ${skip}.`, this.exportConfig.context); } log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context); - let globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find(); + const globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find(); log.debug(`Fetched ${globalFieldsFetchResponse.items?.length || 0} global fields out of ${globalFieldsFetchResponse.count}.`, this.exportConfig.context); @@ -109,7 +85,7 @@ export default class GlobalFieldsExport extends BaseClass { globalFields.forEach((globalField: Record) => { log.debug(`Processing global field: '${globalField.uid || 'unknown'}'...`, this.exportConfig.context); - for (let key in globalField) { + for (const key in globalField) { if (this.globalFieldsConfig.validKeys.indexOf(key) === -1) { delete globalField[key]; } @@ -119,4 +95,28 @@ export default class GlobalFieldsExport extends BaseClass { log.debug(`Sanitization complete. Total global fields processed: ${this.globalFields.length}.`, this.exportConfig.context); } + + async start() { + try { + log.debug('Starting export process for global fields...', this.exportConfig.context); + log.debug(`Global fields directory path: '${this.globalFieldsDirPath}'`, this.exportConfig.context); + await fsUtil.makeDirectory(this.globalFieldsDirPath); + log.debug('Created global fields directory.', this.exportConfig.context); + + await this.getGlobalFields(); + log.debug(`Retrieved ${this.globalFields.length} global fields.`, this.exportConfig.context); + + const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName); + log.debug(`Writing global fields to: '${globalFieldsFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(globalFieldsFilePath, this.globalFields); + + log.success( + messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), + this.exportConfig.context, + ); + } catch (error) { + log.debug('An error occurred during global fields export.', this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); + } + } } diff --git a/packages/contentstack-export/src/export/modules/index.ts b/packages/contentstack-export/src/export/modules/index.ts index f13bc4fa3..e9025b1cd 100644 --- a/packages/contentstack-export/src/export/modules/index.ts +++ b/packages/contentstack-export/src/export/modules/index.ts @@ -1,4 +1,5 @@ import { handleAndLogError } from '@contentstack/cli-utilities'; + import { ModuleClassParams } from '../../types'; export default async function startModuleExport(modulePayload: ModuleClassParams) { diff --git a/packages/contentstack-export/src/export/modules/labels.ts b/packages/contentstack-export/src/export/modules/labels.ts index 414f13077..a9c773973 100644 --- a/packages/contentstack-export/src/export/modules/labels.ts +++ b/packages/contentstack-export/src/export/modules/labels.ts @@ -1,16 +1,16 @@ -import omit from 'lodash/omit'; +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; +import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { LabelConfig, ModuleClassParams } from '../../types'; +import { fsUtil } from '../../utils'; +import BaseClass from './base-class'; export default class ExportLabels extends BaseClass { - private labels: Record>; - private labelConfig: LabelConfig; public labelsFolderPath: string; + private labelConfig: LabelConfig; + private labels: Record>; private qs: { include_count: boolean; skip?: number; @@ -24,35 +24,6 @@ export default class ExportLabels extends BaseClass { this.exportConfig.context.module = 'labels'; } - async start(): Promise { - log.debug('Starting export process for labels...', this.exportConfig.context); - - this.labelsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.labelConfig.dirName, - ); - log.debug(`Labels folder path: '${this.labelsFolderPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.labelsFolderPath); - log.debug('Created labels directory.', this.exportConfig.context); - - await this.getLabels(); - log.debug(`Retrieved ${Object.keys(this.labels).length} labels.`, this.exportConfig.context); - - if (this.labels === undefined || isEmpty(this.labels)) { - log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); - } else { - const labelsFilePath = pResolve(this.labelsFolderPath, this.labelConfig.fileName); - log.debug(`Writing labels to: '${labelsFilePath}'.`, this.exportConfig.context); - fsUtil.writeFile(labelsFilePath, this.labels); - log.success( - messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), - this.exportConfig.context, - ); - } - } - async getLabels(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -68,7 +39,7 @@ export default class ExportLabels extends BaseClass { .query(this.qs) .find() .then(async (data: any) => { - const { items, count } = data; + const { count, items } = data; log.debug(`Fetched ${items?.length || 0} labels out of ${count}.`, this.exportConfig.context); if (items?.length) { @@ -105,4 +76,33 @@ export default class ExportLabels extends BaseClass { log.debug(`Sanitization complete. Total labels processed: ${Object.keys(this.labels).length}.`, this.exportConfig.context); } + + async start(): Promise { + log.debug('Starting export process for labels...', this.exportConfig.context); + + this.labelsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.labelConfig.dirName, + ); + log.debug(`Labels folder path: '${this.labelsFolderPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.labelsFolderPath); + log.debug('Created labels directory.', this.exportConfig.context); + + await this.getLabels(); + log.debug(`Retrieved ${Object.keys(this.labels).length} labels.`, this.exportConfig.context); + + if (this.labels === undefined || isEmpty(this.labels)) { + log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); + } else { + const labelsFilePath = pResolve(this.labelsFolderPath, this.labelConfig.fileName); + log.debug(`Writing labels to: '${labelsFilePath}'.`, this.exportConfig.context); + fsUtil.writeFile(labelsFilePath, this.labels); + log.success( + messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), + this.exportConfig.context, + ); + } + } } diff --git a/packages/contentstack-export/src/export/modules/locales.ts b/packages/contentstack-export/src/export/modules/locales.ts index 97f8d16fe..9f522f6d9 100644 --- a/packages/contentstack-export/src/export/modules/locales.ts +++ b/packages/contentstack-export/src/export/modules/locales.ts @@ -1,39 +1,39 @@ -import * as path from 'path'; import { ContentstackClient, handleAndLogError, - messageHandler, log, + messageHandler, sanitizePath, } from '@contentstack/cli-utilities'; +import * as path from 'path'; +import { ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil } from '../../utils'; import BaseClass from './base-class'; -import { ExportConfig, ModuleClassParams } from '../../types'; export default class LocaleExport extends BaseClass { - private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - private masterLocaleConfig: { dirName: string; fileName: string; requiredKeys: string[] }; - private qs: { - include_count: boolean; - asc: string; - only: { - BASE: string[]; - }; - skip?: number; - }; private localeConfig: { dirName?: string; + fetchConcurrency?: number; fileName?: string; + limit?: number; requiredKeys?: string[]; - fetchConcurrency?: number; writeConcurrency?: number; - limit?: number; }; + private locales: Record>; private localesPath: string; private masterLocale: Record>; - private locales: Record>; + private masterLocaleConfig: { dirName: string; fileName: string; requiredKeys: string[] }; + private qs: { + asc: string; + include_count: boolean; + only: { + BASE: string[]; + }; + skip?: number; + }; + private stackAPIClient: ReturnType; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -41,8 +41,8 @@ export default class LocaleExport extends BaseClass { this.localeConfig = exportConfig.modules.locales; this.masterLocaleConfig = exportConfig.modules.masterLocale; this.qs = { - include_count: true, asc: 'updated_at', + include_count: true, only: { BASE: this.localeConfig.requiredKeys, }, @@ -57,48 +57,14 @@ export default class LocaleExport extends BaseClass { this.exportConfig.context.module = 'locales'; } - async start() { - try { - log.debug('Starting export process for locales...', this.exportConfig.context); - log.debug(`Locales path: '${this.localesPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.localesPath); - log.debug('Created locales directory.', this.exportConfig.context); - - await this.getLocales(); - log.debug(`Retrieved ${Object.keys(this.locales).length} locales and ${Object.keys(this.masterLocale).length} master locales.`, this.exportConfig.context); - - const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName); - const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName); - - log.debug(`Writing locales to: '${localesFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(localesFilePath, this.locales); - - log.debug(`Writing master locale to: '${masterLocaleFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(masterLocaleFilePath, this.masterLocale); - - log.success( - messageHandler.parse( - 'LOCALES_EXPORT_COMPLETE', - Object.keys(this.locales).length, - Object.keys(this.masterLocale).length, - ), - this.exportConfig.context, - ); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - throw error; - } - } - - async getLocales(skip: number = 0): Promise { + async getLocales(skip = 0): Promise { if (skip) { this.qs.skip = skip; log.debug(`Fetching locales with skip: ${skip}.`, this.exportConfig.context); } log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context); - let localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find(); + const localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find(); log.debug(`Fetched ${localesFetchResponse.items?.length || 0} locales out of ${localesFetchResponse.count}.`, this.exportConfig.context); @@ -122,7 +88,7 @@ export default class LocaleExport extends BaseClass { log.debug(`Sanitizing ${locales.length} locales...`, this.exportConfig.context); locales.forEach((locale: Record) => { - for (let key in locale) { + for (const key in locale) { if (this.localeConfig.requiredKeys.indexOf(key) === -1) { delete locale[key]; } @@ -139,4 +105,38 @@ export default class LocaleExport extends BaseClass { log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale).length}, Regular locales: ${Object.keys(this.locales).length}.`, this.exportConfig.context); } + + async start() { + try { + log.debug('Starting export process for locales...', this.exportConfig.context); + log.debug(`Locales path: '${this.localesPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.localesPath); + log.debug('Created locales directory.', this.exportConfig.context); + + await this.getLocales(); + log.debug(`Retrieved ${Object.keys(this.locales).length} locales and ${Object.keys(this.masterLocale).length} master locales.`, this.exportConfig.context); + + const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName); + const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName); + + log.debug(`Writing locales to: '${localesFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(localesFilePath, this.locales); + + log.debug(`Writing master locale to: '${masterLocaleFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(masterLocaleFilePath, this.masterLocale); + + log.success( + messageHandler.parse( + 'LOCALES_EXPORT_COMPLETE', + Object.keys(this.locales).length, + Object.keys(this.masterLocale).length, + ), + this.exportConfig.context, + ); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + throw error; + } + } } diff --git a/packages/contentstack-export/src/export/modules/marketplace-apps.ts b/packages/contentstack-export/src/export/modules/marketplace-apps.ts index 094c05a22..0e08ae2e9 100644 --- a/packages/contentstack-export/src/export/modules/marketplace-apps.ts +++ b/packages/contentstack-export/src/export/modules/marketplace-apps.ts @@ -1,79 +1,42 @@ -import map from 'lodash/map'; -import has from 'lodash/has'; -import find from 'lodash/find'; -import omitBy from 'lodash/omitBy'; -import entries from 'lodash/entries'; -import isEmpty from 'lodash/isEmpty'; -import { resolve as pResolve } from 'node:path'; import { Command } from '@contentstack/cli-command'; import { - cliux, + ContentstackMarketplaceClient, NodeCrypto, + cliux, + handleAndLogError, isAuthenticated, - marketplaceSDKClient, - ContentstackMarketplaceClient, log, + marketplaceSDKClient, messageHandler, - handleAndLogError, } from '@contentstack/cli-utilities'; +import entries from 'lodash/entries'; +import find from 'lodash/find'; +import has from 'lodash/has'; +import isEmpty from 'lodash/isEmpty'; +import map from 'lodash/map'; +import omitBy from 'lodash/omitBy'; +import { resolve as pResolve } from 'node:path'; -import { fsUtil, getOrgUid, createNodeCryptoInstance, getDeveloperHubUrl } from '../../utils'; -import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation, Manifest } from '../../types'; +import { ExportConfig, Installation, Manifest, MarketplaceAppsConfig, ModuleClassParams } from '../../types'; +import { createNodeCryptoInstance, fsUtil, getDeveloperHubUrl, getOrgUid } from '../../utils'; export default class ExportMarketplaceApps { - protected marketplaceAppConfig: MarketplaceAppsConfig; - protected installedApps: Installation[] = []; + public appSdk: ContentstackMarketplaceClient; + public command: Command; public developerHubBaseUrl: string; + public exportConfig: ExportConfig; + protected installedApps: Installation[] = []; + protected marketplaceAppConfig: MarketplaceAppsConfig; public marketplaceAppPath: string; public nodeCrypto: NodeCrypto; - public appSdk: ContentstackMarketplaceClient; - public exportConfig: ExportConfig; - public command: Command; public query: Record; - constructor({ exportConfig }: Omit) { + constructor({ exportConfig }: Omit) { this.exportConfig = exportConfig; this.marketplaceAppConfig = exportConfig.modules.marketplace_apps; this.exportConfig.context.module = 'marketplace-apps'; } - async start(): Promise { - log.debug('Starting export process for Marketplace Apps...', this.exportConfig.context); - - if (!isAuthenticated()) { - cliux.print( - 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', - { color: 'yellow' }, - ); - return Promise.resolve(); - } - - this.marketplaceAppPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.marketplaceAppConfig.dirName, - ); - log.debug(`Marketplace apps folder path: '${this.marketplaceAppPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.marketplaceAppPath); - log.debug('Created Marketplace Apps directory.', this.exportConfig.context); - - this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await getDeveloperHubUrl(this.exportConfig)); - log.debug(`Developer Hub base URL: '${this.developerHubBaseUrl}'`, this.exportConfig.context); - - this.exportConfig.org_uid = await getOrgUid(this.exportConfig); - this.query = { target_uids: this.exportConfig.source_stack }; - log.debug(`Organization UID: '${this.exportConfig.org_uid}'.`, this.exportConfig.context); - - // NOTE init marketplace app sdk - const host = this.developerHubBaseUrl.split('://').pop(); - log.debug(`Initializing Marketplace SDK with host: '${host}'...`, this.exportConfig.context); - this.appSdk = await marketplaceSDKClient({ host }); - - await this.exportApps(); - log.debug('Marketplace apps export process completed.', this.exportConfig.context); - } - /** * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto * library if it is available. @@ -113,72 +76,6 @@ export default class ExportMarketplaceApps { log.debug(`Processed ${this.installedApps.length} Marketplace Apps.`, this.exportConfig.context); } - /** - * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed - * marketplace apps. - */ - async getAppManifestAndAppConfig(): Promise { - if (isEmpty(this.installedApps)) { - log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); - } else { - log.debug(`Processing ${this.installedApps.length} installed apps...`, this.exportConfig.context); - - for (const [index, app] of entries(this.installedApps)) { - if (app.manifest.visibility === 'private') { - log.debug(`Processing private app manifest: '${app.manifest.name}'...`, this.exportConfig.context); - await this.getPrivateAppsManifest(+index, app); - } - } - - for (const [index, app] of entries(this.installedApps)) { - log.debug(`Processing app configurations for: '${app.manifest?.name || app.uid}'...`, this.exportConfig.context); - await this.getAppConfigurations(+index, app); - } - - const marketplaceAppsFilePath = pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName); - log.debug(`Writing Marketplace Apps to: '${marketplaceAppsFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps); - - log.success( - messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), - this.exportConfig.context, - ); - } - } - - /** - * The function `getPrivateAppsManifest` fetches the manifest of a private app and assigns it to the - * `manifest` property of the corresponding installed app. - * @param {number} index - The `index` parameter is a number that represents the position of the app - * in an array or list. It is used to identify the specific app in the `installedApps` array. - * @param {App} appInstallation - The `appInstallation` parameter is an object that represents the - * installation details of an app. It contains information such as the UID (unique identifier) of the - * app's manifest. - */ - async getPrivateAppsManifest(index: number, appInstallation: Installation) { - log.debug(`Fetching private app manifest for: '${appInstallation.manifest.name}' (UID: ${appInstallation.manifest.uid})...`, this.exportConfig.context); - - const manifest = await this.appSdk - .marketplace(this.exportConfig.org_uid) - .app(appInstallation.manifest.uid) - .fetch({ include_oauth: true }) - .catch((error) => { - log.debug(`Failed to fetch private app manifest for: '${appInstallation.manifest.name}'.`, this.exportConfig.context); - handleAndLogError( - error, - { - ...this.exportConfig.context, - }, - messageHandler.parse('MARKETPLACE_APP_MANIFEST_EXPORT_FAILED', appInstallation.manifest.name), - ); - }); - - if (manifest) { - log.debug(`Successfully fetched private app manifest for: '${appInstallation.manifest.name}'.`, this.exportConfig.context); - this.installedApps[index].manifest = manifest as unknown as Manifest; - } - } - /** * The function `getAppConfigurations` exports the configuration of an app installation and encrypts * the server configuration if it exists. @@ -246,6 +143,72 @@ export default class ExportMarketplaceApps { }); } + /** + * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed + * marketplace apps. + */ + async getAppManifestAndAppConfig(): Promise { + if (isEmpty(this.installedApps)) { + log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); + } else { + log.debug(`Processing ${this.installedApps.length} installed apps...`, this.exportConfig.context); + + for (const [index, app] of entries(this.installedApps)) { + if (app.manifest.visibility === 'private') { + log.debug(`Processing private app manifest: '${app.manifest.name}'...`, this.exportConfig.context); + await this.getPrivateAppsManifest(+index, app); + } + } + + for (const [index, app] of entries(this.installedApps)) { + log.debug(`Processing app configurations for: '${app.manifest?.name || app.uid}'...`, this.exportConfig.context); + await this.getAppConfigurations(+index, app); + } + + const marketplaceAppsFilePath = pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName); + log.debug(`Writing Marketplace Apps to: '${marketplaceAppsFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps); + + log.success( + messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), + this.exportConfig.context, + ); + } + } + + /** + * The function `getPrivateAppsManifest` fetches the manifest of a private app and assigns it to the + * `manifest` property of the corresponding installed app. + * @param {number} index - The `index` parameter is a number that represents the position of the app + * in an array or list. It is used to identify the specific app in the `installedApps` array. + * @param {App} appInstallation - The `appInstallation` parameter is an object that represents the + * installation details of an app. It contains information such as the UID (unique identifier) of the + * app's manifest. + */ + async getPrivateAppsManifest(index: number, appInstallation: Installation) { + log.debug(`Fetching private app manifest for: '${appInstallation.manifest.name}' (UID: ${appInstallation.manifest.uid})...`, this.exportConfig.context); + + const manifest = await this.appSdk + .marketplace(this.exportConfig.org_uid) + .app(appInstallation.manifest.uid) + .fetch({ include_oauth: true }) + .catch((error) => { + log.debug(`Failed to fetch private app manifest for: '${appInstallation.manifest.name}'.`, this.exportConfig.context); + handleAndLogError( + error, + { + ...this.exportConfig.context, + }, + messageHandler.parse('MARKETPLACE_APP_MANIFEST_EXPORT_FAILED', appInstallation.manifest.name), + ); + }); + + if (manifest) { + log.debug(`Successfully fetched private app manifest for: '${appInstallation.manifest.name}'.`, this.exportConfig.context); + this.installedApps[index].manifest = manifest as unknown as Manifest; + } + } + /** * The function `getStackSpecificApps` retrieves a collection of marketplace apps specific to a stack * and stores them in the `installedApps` array. @@ -267,7 +230,7 @@ export default class ExportMarketplaceApps { }); if (collection) { - const { items: apps, count } = collection; + const { count, items: apps } = collection; log.debug(`Fetched ${apps?.length || 0} apps out of ${count}.`, this.exportConfig.context); // NOTE Remove all the chain functions @@ -289,4 +252,41 @@ export default class ExportMarketplaceApps { } } } + + async start(): Promise { + log.debug('Starting export process for Marketplace Apps...', this.exportConfig.context); + + if (!isAuthenticated()) { + cliux.print( + 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', + { color: 'yellow' }, + ); + return Promise.resolve(); + } + + this.marketplaceAppPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.marketplaceAppConfig.dirName, + ); + log.debug(`Marketplace apps folder path: '${this.marketplaceAppPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.marketplaceAppPath); + log.debug('Created Marketplace Apps directory.', this.exportConfig.context); + + this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await getDeveloperHubUrl(this.exportConfig)); + log.debug(`Developer Hub base URL: '${this.developerHubBaseUrl}'`, this.exportConfig.context); + + this.exportConfig.org_uid = await getOrgUid(this.exportConfig); + this.query = { target_uids: this.exportConfig.source_stack }; + log.debug(`Organization UID: '${this.exportConfig.org_uid}'.`, this.exportConfig.context); + + // NOTE init marketplace app sdk + const host = this.developerHubBaseUrl.split('://').pop(); + log.debug(`Initializing Marketplace SDK with host: '${host}'...`, this.exportConfig.context); + this.appSdk = await marketplaceSDKClient({ host }); + + await this.exportApps(); + log.debug('Marketplace apps export process completed.', this.exportConfig.context); + } } diff --git a/packages/contentstack-export/src/export/modules/personalize.ts b/packages/contentstack-export/src/export/modules/personalize.ts index 51656635c..e154321c5 100644 --- a/packages/contentstack-export/src/export/modules/personalize.ts +++ b/packages/contentstack-export/src/export/modules/personalize.ts @@ -1,18 +1,18 @@ +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import { - ExportProjects, - ExportExperiences, - ExportEvents, + AnyProperty, ExportAttributes, ExportAudiences, - AnyProperty, + ExportEvents, + ExportExperiences, + ExportProjects, } from '@contentstack/cli-variants'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { ModuleClassParams, ExportConfig } from '../../types'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class ExportPersonalize { public exportConfig: ExportConfig; - public personalizeConfig: { dirName: string; baseURL: Record } & AnyProperty; + public personalizeConfig: { baseURL: Record; dirName: string } & AnyProperty; constructor({ exportConfig }: ModuleClassParams) { this.exportConfig = exportConfig; this.personalizeConfig = exportConfig.modules.personalize; @@ -44,9 +44,9 @@ export default class ExportPersonalize { log.debug('Personalization is enabled, processing personalize modules... ' + this.exportConfig.modules.personalize.exportOrder.join(', '), this.exportConfig.context); const moduleMapper = { - events: new ExportEvents(this.exportConfig), attributes: new ExportAttributes(this.exportConfig), audiences: new ExportAudiences(this.exportConfig), + events: new ExportEvents(this.exportConfig), experiences: new ExportExperiences(this.exportConfig), }; diff --git a/packages/contentstack-export/src/export/modules/publishing-rules.ts b/packages/contentstack-export/src/export/modules/publishing-rules.ts index 483189994..fee752b10 100644 --- a/packages/contentstack-export/src/export/modules/publishing-rules.ts +++ b/packages/contentstack-export/src/export/modules/publishing-rules.ts @@ -1,11 +1,11 @@ -import omit from 'lodash/omit'; +import { handleAndLogError, log } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; +import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; +import { ModuleClassParams, PublishingRulesConfig } from '../../types'; import { fsUtil } from '../../utils'; -import { PublishingRulesConfig, ModuleClassParams } from '../../types'; +import BaseClass from './base-class'; export default class ExportPublishingRules extends BaseClass { private readonly publishingRules: Record> = {}; @@ -52,7 +52,7 @@ export default class ExportPublishingRules extends BaseClass { this.qs.skip = skip; } - const data: { items?: Record[]; count?: number } = await this.stack + const data: { count?: number; items?: Record[] } = await this.stack .workflow() .publishRule() .fetchAll(this.qs); diff --git a/packages/contentstack-export/src/export/modules/stack.ts b/packages/contentstack-export/src/export/modules/stack.ts index cb1d75fb0..92ee1f9b3 100644 --- a/packages/contentstack-export/src/export/modules/stack.ts +++ b/packages/contentstack-export/src/export/modules/stack.ts @@ -1,18 +1,18 @@ +import { handleAndLogError, isAuthenticated, log, managementSDKClient } from '@contentstack/cli-utilities'; import find from 'lodash/find'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, isAuthenticated, managementSDKClient, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; +import { ModuleClassParams, StackConfig } from '../../types'; import { fsUtil } from '../../utils'; -import { StackConfig, ModuleClassParams } from '../../types'; +import BaseClass from './base-class'; export default class ExportStack extends BaseClass { - private stackConfig: StackConfig; - private stackFolderPath: string; private qs: { include_count: boolean; skip?: number; }; + private stackConfig: StackConfig; + private stackFolderPath: string; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -26,67 +26,47 @@ export default class ExportStack extends BaseClass { this.exportConfig.context.module = 'stack'; } - async start(): Promise { - log.debug('Starting stack export process...', this.exportConfig.context); + async exportStack(): Promise { + log.debug(`Starting stack export for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); - if (isAuthenticated()) { - log.debug('User authenticated.', this.exportConfig.context); - const stackData = await this.getStack(); - if (stackData?.org_uid) { - log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context); - this.exportConfig.org_uid = stackData.org_uid; - this.exportConfig.sourceStackName = stackData.name; - log.debug(`Set source stack name: '${stackData.name}'.`, this.exportConfig.context); - } else { - log.debug('No stack data found or missing organization UID.', this.exportConfig.context); - } - } else { - log.debug('User is not authenticated.', this.exportConfig.context); - } + await fsUtil.makeDirectory(this.stackFolderPath); + log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context); - if (this.exportConfig.management_token) { - log.info( - 'Skipping stack settings export: Operation is not supported when using a management token.', - this.exportConfig.context, - ); - } else { - await this.exportStackSettings(); - } - if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { - log.debug( - 'Preserve stack version is false and master locale not set, fetching locales...', - this.exportConfig.context, - ); - //fetch master locale details - return this.getLocales(); - } else if (this.exportConfig.preserveStackVersion) { - log.debug('Preserve stack version is set to true.', this.exportConfig.context); - return this.exportStack(); - } else { - log.debug('Master locale is already set.', this.exportConfig.context); - } + return this.stack + .fetch() + .then((resp: any) => { + const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName); + log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(stackFilePath, resp); + log.success( + `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, + this.exportConfig.context, + ); + log.debug('Stack export completed successfully.', this.exportConfig.context); + return resp; + }) + .catch((error: any) => { + log.debug(`An error occurred while exporting stack: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); + }); } - async getStack(): Promise { - log.debug(`Fetching stack data for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); - - const tempAPIClient = await managementSDKClient({ host: this.exportConfig.host }); - log.debug(`Created Management SDK client with host: '${this.exportConfig.host}'.`, this.exportConfig.context); - - return await tempAPIClient - .stack({ api_key: this.exportConfig.source_stack }) - .fetch() - .then((data: any) => { - log.debug(`Successfully fetched stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); - return data; + async exportStackSettings(): Promise { + log.info('Exporting stack settings...', this.exportConfig.context); + await fsUtil.makeDirectory(this.stackFolderPath); + return this.stack + .settings() + .then((resp: any) => { + fsUtil.writeFile(pResolve(this.stackFolderPath, 'settings.json'), resp); + log.success('Exported stack settings successfully!', this.exportConfig.context); + return resp; }) .catch((error: any) => { - log.debug(`Failed to fetch stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); - return {}; + handleAndLogError(error, { ...this.exportConfig.context }); }); } - async getLocales(skip: number = 0) { + async getLocales(skip = 0) { if (skip) { this.qs.skip = skip; log.debug(`Fetching locales with skip: ${skip}.`, this.exportConfig.context); @@ -101,7 +81,7 @@ export default class ExportStack extends BaseClass { .query(this.qs) .find() .then(async (data: any) => { - const { items, count } = data; + const { count, items } = data; log.debug(`Fetched ${items?.length || 0} locales out of ${count}.`, this.exportConfig.context); if (items?.length) { @@ -148,43 +128,63 @@ export default class ExportStack extends BaseClass { }); } - async exportStack(): Promise { - log.debug(`Starting stack export for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); + async getStack(): Promise { + log.debug(`Fetching stack data for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); - await fsUtil.makeDirectory(this.stackFolderPath); - log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context); + const tempAPIClient = await managementSDKClient({ host: this.exportConfig.host }); + log.debug(`Created Management SDK client with host: '${this.exportConfig.host}'.`, this.exportConfig.context); - return this.stack + return await tempAPIClient + .stack({ api_key: this.exportConfig.source_stack }) .fetch() - .then((resp: any) => { - const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName); - log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(stackFilePath, resp); - log.success( - `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, - this.exportConfig.context, - ); - log.debug('Stack export completed successfully.', this.exportConfig.context); - return resp; + .then((data: any) => { + log.debug(`Successfully fetched stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); + return data; }) .catch((error: any) => { - log.debug(`An error occurred while exporting stack: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context }); + log.debug(`Failed to fetch stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); + return {}; }); } - async exportStackSettings(): Promise { - log.info('Exporting stack settings...', this.exportConfig.context); - await fsUtil.makeDirectory(this.stackFolderPath); - return this.stack - .settings() - .then((resp: any) => { - fsUtil.writeFile(pResolve(this.stackFolderPath, 'settings.json'), resp); - log.success('Exported stack settings successfully!', this.exportConfig.context); - return resp; - }) - .catch((error: any) => { - handleAndLogError(error, { ...this.exportConfig.context }); - }); + async start(): Promise { + log.debug('Starting stack export process...', this.exportConfig.context); + + if (isAuthenticated()) { + log.debug('User authenticated.', this.exportConfig.context); + const stackData = await this.getStack(); + if (stackData?.org_uid) { + log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context); + this.exportConfig.org_uid = stackData.org_uid; + this.exportConfig.sourceStackName = stackData.name; + log.debug(`Set source stack name: '${stackData.name}'.`, this.exportConfig.context); + } else { + log.debug('No stack data found or missing organization UID.', this.exportConfig.context); + } + } else { + log.debug('User is not authenticated.', this.exportConfig.context); + } + + if (this.exportConfig.management_token) { + log.info( + 'Skipping stack settings export: Operation is not supported when using a management token.', + this.exportConfig.context, + ); + } else { + await this.exportStackSettings(); + } + if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { + log.debug( + 'Preserve stack version is false and master locale not set, fetching locales...', + this.exportConfig.context, + ); + //fetch master locale details + return this.getLocales(); + } else if (this.exportConfig.preserveStackVersion) { + log.debug('Preserve stack version is set to true.', this.exportConfig.context); + return this.exportStack(); + } else { + log.debug('Master locale is already set.', this.exportConfig.context); + } } } diff --git a/packages/contentstack-export/src/export/modules/taxonomies.ts b/packages/contentstack-export/src/export/modules/taxonomies.ts index 69acea863..ae8cbc287 100644 --- a/packages/contentstack-export/src/export/modules/taxonomies.ts +++ b/packages/contentstack-export/src/export/modules/taxonomies.ts @@ -1,30 +1,30 @@ -import omit from 'lodash/omit'; -import keys from 'lodash/keys'; +import { handleAndLogError, log, messageHandler, sanitizePath } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; +import keys from 'lodash/keys'; +import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; +import { ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil } from '../../utils'; -import { ModuleClassParams, ExportConfig } from '../../types'; +import BaseClass from './base-class'; export default class ExportTaxonomies extends BaseClass { - private taxonomies: Record>; - private taxonomiesByLocale: Record>; - private taxonomiesConfig: ExportConfig['modules']['taxonomies']; - private isLocaleBasedExportSupported: boolean = true; // Flag to track if locale-based export is supported + public taxonomiesFolderPath: string; + private isLocaleBasedExportSupported = true; + private localesFilePath: string; private qs: { - include_count: boolean; - skip: number; asc?: string; - limit: number; - locale?: string; branch?: string; - include_fallback?: boolean; fallback_locale?: string; - }; - public taxonomiesFolderPath: string; - private localesFilePath: string; + include_count: boolean; + include_fallback?: boolean; + limit: number; + locale?: string; + skip: number; + }; // Flag to track if locale-based export is supported + private taxonomies: Record>; + private taxonomiesByLocale: Record>; + private taxonomiesConfig: ExportConfig['modules']['taxonomies']; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -43,87 +43,57 @@ export default class ExportTaxonomies extends BaseClass { ); } - async start(): Promise { - log.debug('Starting export process for taxonomies...', this.exportConfig.context); - - //create taxonomies folder - this.taxonomiesFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.taxonomiesConfig.dirName, - ); - log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.taxonomiesFolderPath); - log.debug('Created taxonomies directory.', this.exportConfig.context); - - const localesToExport = this.getLocalesToExport(); - log.debug( - `Will attempt to export taxonomies for ${localesToExport.length} locale(s): ${localesToExport.join(', ')}`, - this.exportConfig.context, - ); + /** + * Export taxonomies - supports both locale-based and legacy export + */ + async exportTaxonomies(localeCode?: string): Promise { + const taxonomiesUID = localeCode ? Array.from(this.taxonomiesByLocale[localeCode] || []) : keys(this.taxonomies); - if (localesToExport.length === 0) { - log.warn('No locales found to export', this.exportConfig.context); + const localeInfo = localeCode ? ` for locale: ${localeCode}` : ''; + if (taxonomiesUID.length === 0) { + log.debug(`No taxonomies to export${localeInfo}`, this.exportConfig.context); return; } + log.debug(`Exporting detailed data for ${taxonomiesUID.length} taxonomies${localeInfo}`, this.exportConfig.context); - // Test locale-based export support with master locale - const masterLocale = this.exportConfig.master_locale?.code; - await this.fetchTaxonomies(masterLocale, true); - - if (!this.isLocaleBasedExportSupported) { - this.taxonomies = {}; - this.taxonomiesByLocale = {}; - - // Fetch taxonomies without locale parameter - await this.fetchTaxonomies(); - await this.exportTaxonomies(); - await this.writeTaxonomiesMetadata(); - } else { - // Process all locales with locale-based export - log.debug('Localization enabled, proceeding with locale-based export', this.exportConfig.context); - - for (const localeCode of localesToExport) { - await this.fetchTaxonomies(localeCode); - await this.processLocaleExport(localeCode); - } - - await this.writeTaxonomiesMetadata(); + const exportFolderPath = localeCode ? pResolve(this.taxonomiesFolderPath, localeCode) : this.taxonomiesFolderPath; + if (localeCode) { + await fsUtil.makeDirectory(exportFolderPath); + log.debug(`Created locale folder: ${exportFolderPath}`, this.exportConfig.context); } - log.success( - messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies || {}).length), - this.exportConfig.context, - ); - } + const onSuccess = ({ response, uid }: any) => { + const filePath = pResolve(exportFolderPath, `${uid}.json`); + log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context); + fsUtil.writeFile(filePath, response); + log.success(messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), this.exportConfig.context); + }; - /** - * Process and export taxonomies for a specific locale - */ - async processLocaleExport(localeCode: string): Promise { - const localeTaxonomies = this.taxonomiesByLocale[localeCode]; + const onReject = ({ error, uid }: any) => { + log.debug(`Failed to export detailed data for taxonomy: ${uid}${localeInfo}`, this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context, uid, ...(localeCode && { locale: localeCode }) }); + }; - if (localeTaxonomies?.size > 0) { - log.info(`Found ${localeTaxonomies.size} taxonomies for locale: ${localeCode}`, this.exportConfig.context); - await this.exportTaxonomies(localeCode); - } else { - log.debug(`No taxonomies found for locale: ${localeCode}`, this.exportConfig.context); - } - } + for (const taxonomyUID of taxonomiesUID) { + log.debug(`Processing detailed export for taxonomy: ${taxonomyUID}${localeInfo}`, this.exportConfig.context); - /** - * Write taxonomies metadata file - */ - async writeTaxonomiesMetadata(): Promise { - if (!this.taxonomies || isEmpty(this.taxonomies)) { - log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); - return; - } + const exportParams: any = { format: 'json' }; + if (localeCode) { + exportParams.locale = localeCode; + if (this.qs.include_fallback !== undefined) exportParams.include_fallback = this.qs.include_fallback; + if (this.qs.fallback_locale) exportParams.fallback_locale = this.qs.fallback_locale; + } + if (this.qs.branch) exportParams.branch = this.qs.branch; - const taxonomiesFilePath = pResolve(this.taxonomiesFolderPath, 'taxonomies.json'); - log.debug(`Writing taxonomies metadata to: ${taxonomiesFilePath}`, this.exportConfig.context); - fsUtil.writeFile(taxonomiesFilePath, this.taxonomies); + await this.makeAPICall({ + module: 'export-taxonomy', + queryParam: exportParams, + reject: onReject, + resolve: onSuccess, + uid: taxonomyUID, + }); + } + log.debug(`Completed detailed taxonomy export process${localeInfo}`, this.exportConfig.context); } /** @@ -134,7 +104,7 @@ export default class ExportTaxonomies extends BaseClass { * @param {boolean} [checkLocaleSupport=false] * @returns {Promise} */ - async fetchTaxonomies(localeCode?: string, checkLocaleSupport: boolean = false): Promise { + async fetchTaxonomies(localeCode?: string, checkLocaleSupport = false): Promise { let skip = 0; const localeInfo = localeCode ? `for locale: ${localeCode}` : ''; @@ -152,7 +122,7 @@ export default class ExportTaxonomies extends BaseClass { try { const data = await this.stack.taxonomy().query(queryParams).find(); - const { items, count } = data; + const { count, items } = data; const taxonomiesCount = count ?? items?.length ?? 0; log.debug( @@ -204,6 +174,58 @@ export default class ExportTaxonomies extends BaseClass { } while (true); } + /** + * Get all locales to export + */ + getLocalesToExport(): string[] { + log.debug('Determining locales to export...', this.exportConfig.context); + + const masterLocaleCode = this.exportConfig.master_locale?.code || 'en-us'; + const localeSet = new Set([masterLocaleCode]); + + try { + const locales = fsUtil.readFile(this.localesFilePath) as Record>; + + if (locales && keys(locales || {}).length > 0) { + log.debug( + `Loaded ${keys(locales || {}).length} locales from ${this.localesFilePath}`, + this.exportConfig.context, + ); + + for (const localeUid of keys(locales)) { + const localeCode = locales[localeUid].code; + if (localeCode && !localeSet.has(localeCode)) { + localeSet.add(localeCode); + log.debug(`Added locale: ${localeCode} (uid: ${localeUid})`, this.exportConfig.context); + } + } + } else { + log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); + } + } catch (error) { + log.warn(`Failed to read locales file: ${this.localesFilePath}`, this.exportConfig.context); + } + + const localesToExport = Array.from(localeSet); + log.debug(`Total unique locales to export: ${localesToExport.length}`, this.exportConfig.context); + + return localesToExport; + } + + /** + * Process and export taxonomies for a specific locale + */ + async processLocaleExport(localeCode: string): Promise { + const localeTaxonomies = this.taxonomiesByLocale[localeCode]; + + if (localeTaxonomies?.size > 0) { + log.info(`Found ${localeTaxonomies.size} taxonomies for locale: ${localeCode}`, this.exportConfig.context); + await this.exportTaxonomies(localeCode); + } else { + log.debug(`No taxonomies found for locale: ${localeCode}`, this.exportConfig.context); + } + } + /** * remove invalid keys and write data into taxonomies * @function sanitizeTaxonomiesAttribs @@ -237,95 +259,73 @@ export default class ExportTaxonomies extends BaseClass { ); } - /** - * Export taxonomies - supports both locale-based and legacy export - */ - async exportTaxonomies(localeCode?: string): Promise { - const taxonomiesUID = localeCode ? Array.from(this.taxonomiesByLocale[localeCode] || []) : keys(this.taxonomies); + async start(): Promise { + log.debug('Starting export process for taxonomies...', this.exportConfig.context); + + //create taxonomies folder + this.taxonomiesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.taxonomiesConfig.dirName, + ); + log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.taxonomiesFolderPath); + log.debug('Created taxonomies directory.', this.exportConfig.context); - const localeInfo = localeCode ? ` for locale: ${localeCode}` : ''; - if (taxonomiesUID.length === 0) { - log.debug(`No taxonomies to export${localeInfo}`, this.exportConfig.context); - return; - } - log.debug(`Exporting detailed data for ${taxonomiesUID.length} taxonomies${localeInfo}`, this.exportConfig.context); + const localesToExport = this.getLocalesToExport(); + log.debug( + `Will attempt to export taxonomies for ${localesToExport.length} locale(s): ${localesToExport.join(', ')}`, + this.exportConfig.context, + ); - const exportFolderPath = localeCode ? pResolve(this.taxonomiesFolderPath, localeCode) : this.taxonomiesFolderPath; - if (localeCode) { - await fsUtil.makeDirectory(exportFolderPath); - log.debug(`Created locale folder: ${exportFolderPath}`, this.exportConfig.context); + if (localesToExport.length === 0) { + log.warn('No locales found to export', this.exportConfig.context); + return; } - const onSuccess = ({ response, uid }: any) => { - const filePath = pResolve(exportFolderPath, `${uid}.json`); - log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context); - fsUtil.writeFile(filePath, response); - log.success(messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), this.exportConfig.context); - }; + // Test locale-based export support with master locale + const masterLocale = this.exportConfig.master_locale?.code; + await this.fetchTaxonomies(masterLocale, true); - const onReject = ({ error, uid }: any) => { - log.debug(`Failed to export detailed data for taxonomy: ${uid}${localeInfo}`, this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context, uid, ...(localeCode && { locale: localeCode }) }); - }; + if (!this.isLocaleBasedExportSupported) { + this.taxonomies = {}; + this.taxonomiesByLocale = {}; - for (const taxonomyUID of taxonomiesUID) { - log.debug(`Processing detailed export for taxonomy: ${taxonomyUID}${localeInfo}`, this.exportConfig.context); + // Fetch taxonomies without locale parameter + await this.fetchTaxonomies(); + await this.exportTaxonomies(); + await this.writeTaxonomiesMetadata(); + } else { + // Process all locales with locale-based export + log.debug('Localization enabled, proceeding with locale-based export', this.exportConfig.context); - const exportParams: any = { format: 'json' }; - if (localeCode) { - exportParams.locale = localeCode; - if (this.qs.include_fallback !== undefined) exportParams.include_fallback = this.qs.include_fallback; - if (this.qs.fallback_locale) exportParams.fallback_locale = this.qs.fallback_locale; + for (const localeCode of localesToExport) { + await this.fetchTaxonomies(localeCode); + await this.processLocaleExport(localeCode); } - if (this.qs.branch) exportParams.branch = this.qs.branch; - await this.makeAPICall({ - reject: onReject, - resolve: onSuccess, - uid: taxonomyUID, - module: 'export-taxonomy', - queryParam: exportParams, - }); + await this.writeTaxonomiesMetadata(); } - log.debug(`Completed detailed taxonomy export process${localeInfo}`, this.exportConfig.context); + + log.success( + messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies || {}).length), + this.exportConfig.context, + ); } /** - * Get all locales to export + * Write taxonomies metadata file */ - getLocalesToExport(): string[] { - log.debug('Determining locales to export...', this.exportConfig.context); - - const masterLocaleCode = this.exportConfig.master_locale?.code || 'en-us'; - const localeSet = new Set([masterLocaleCode]); - - try { - const locales = fsUtil.readFile(this.localesFilePath) as Record>; - - if (locales && keys(locales || {}).length > 0) { - log.debug( - `Loaded ${keys(locales || {}).length} locales from ${this.localesFilePath}`, - this.exportConfig.context, - ); - - for (const localeUid of keys(locales)) { - const localeCode = locales[localeUid].code; - if (localeCode && !localeSet.has(localeCode)) { - localeSet.add(localeCode); - log.debug(`Added locale: ${localeCode} (uid: ${localeUid})`, this.exportConfig.context); - } - } - } else { - log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); - } - } catch (error) { - log.warn(`Failed to read locales file: ${this.localesFilePath}`, this.exportConfig.context); + async writeTaxonomiesMetadata(): Promise { + if (!this.taxonomies || isEmpty(this.taxonomies)) { + log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); + return; } - const localesToExport = Array.from(localeSet); - log.debug(`Total unique locales to export: ${localesToExport.length}`, this.exportConfig.context); - - return localesToExport; + const taxonomiesFilePath = pResolve(this.taxonomiesFolderPath, 'taxonomies.json'); + log.debug(`Writing taxonomies metadata to: ${taxonomiesFilePath}`, this.exportConfig.context); + fsUtil.writeFile(taxonomiesFilePath, this.taxonomies); } private isLocalePlanLimitationError(error: any): boolean { diff --git a/packages/contentstack-export/src/export/modules/webhooks.ts b/packages/contentstack-export/src/export/modules/webhooks.ts index 42d657490..f4d797230 100644 --- a/packages/contentstack-export/src/export/modules/webhooks.ts +++ b/packages/contentstack-export/src/export/modules/webhooks.ts @@ -1,59 +1,30 @@ -import omit from 'lodash/omit'; +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; +import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; +import { ModuleClassParams, WebhookConfig } from '../../types'; import { fsUtil } from '../../utils'; -import { WebhookConfig, ModuleClassParams } from '../../types'; +import BaseClass from './base-class'; export default class ExportWebhooks extends BaseClass { - private webhooks: Record>; - private webhookConfig: WebhookConfig; public webhooksFolderPath: string; private qs: { + asc: string; include_count: boolean; skip?: number; - asc: string; }; + private webhookConfig: WebhookConfig; + private webhooks: Record>; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.webhooks = {}; this.webhookConfig = exportConfig.modules.webhooks; - this.qs = { include_count: true, asc: 'updated_at' }; + this.qs = { asc: 'updated_at', include_count: true }; this.exportConfig.context.module = 'webhooks'; } - async start(): Promise { - log.debug('Starting webhooks export process...', this.exportConfig.context); - - this.webhooksFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.webhookConfig.dirName, - ); - log.debug(`Webhooks folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.webhooksFolderPath); - log.debug('Created webhooks directory', this.exportConfig.context); - - await this.getWebhooks(); - log.debug(`Retrieved ${Object.keys(this.webhooks).length} webhooks`, this.exportConfig.context); - - if (this.webhooks === undefined || isEmpty(this.webhooks)) { - log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); - } else { - const webhooksFilePath = pResolve(this.webhooksFolderPath, this.webhookConfig.fileName); - log.debug(`Writing webhooks to: ${webhooksFilePath}`, this.exportConfig.context); - fsUtil.writeFile(webhooksFilePath, this.webhooks); - log.success( - messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), - this.exportConfig.context, - ); - } - } - async getWebhooks(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -68,7 +39,7 @@ export default class ExportWebhooks extends BaseClass { .webhook() .fetchAll(this.qs) .then(async (data: any) => { - const { items, count } = data; + const { count, items } = data; log.debug(`Fetched ${items?.length || 0} webhooks out of total ${count}`, this.exportConfig.context); if (items?.length) { @@ -105,4 +76,33 @@ export default class ExportWebhooks extends BaseClass { log.debug(`Sanitization complete. Total webhooks processed: ${Object.keys(this.webhooks).length}`, this.exportConfig.context); } + + async start(): Promise { + log.debug('Starting webhooks export process...', this.exportConfig.context); + + this.webhooksFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.webhookConfig.dirName, + ); + log.debug(`Webhooks folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.webhooksFolderPath); + log.debug('Created webhooks directory', this.exportConfig.context); + + await this.getWebhooks(); + log.debug(`Retrieved ${Object.keys(this.webhooks).length} webhooks`, this.exportConfig.context); + + if (this.webhooks === undefined || isEmpty(this.webhooks)) { + log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); + } else { + const webhooksFilePath = pResolve(this.webhooksFolderPath, this.webhookConfig.fileName); + log.debug(`Writing webhooks to: ${webhooksFilePath}`, this.exportConfig.context); + fsUtil.writeFile(webhooksFilePath, this.webhooks); + log.success( + messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), + this.exportConfig.context, + ); + } + } } diff --git a/packages/contentstack-export/src/export/modules/workflows.ts b/packages/contentstack-export/src/export/modules/workflows.ts index 6a9fedb8a..d3aacf3a8 100644 --- a/packages/contentstack-export/src/export/modules/workflows.ts +++ b/packages/contentstack-export/src/export/modules/workflows.ts @@ -1,20 +1,20 @@ -import omit from 'lodash/omit'; +import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import isEmpty from 'lodash/isEmpty'; +import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import BaseClass from './base-class'; +import { ModuleClassParams, WorkflowConfig } from '../../types'; import { fsUtil } from '../../utils'; -import { WorkflowConfig, ModuleClassParams } from '../../types'; +import BaseClass from './base-class'; export default class ExportWorkFlows extends BaseClass { - private workflows: Record>; - private workflowConfig: WorkflowConfig; public webhooksFolderPath: string; private qs: { include_count: boolean; skip?: number; }; + private workflowConfig: WorkflowConfig; + private workflows: Record>; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -24,30 +24,37 @@ export default class ExportWorkFlows extends BaseClass { this.exportConfig.context.module = 'workflows'; } - async start(): Promise { - this.webhooksFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.workflowConfig.dirName, - ); - log.debug(`Workflows folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.webhooksFolderPath); - log.debug('Created workflows directory', this.exportConfig.context); + async getRoles(roleUid: number): Promise { + log.debug(`Fetching role with UID: ${roleUid}`, this.exportConfig.context); - await this.getWorkflows(); - log.debug(`Retrieved ${Object.keys(this.workflows).length} workflows`, this.exportConfig.context); + return await this.stack + .role(roleUid) + .fetch({ include_permissions: true, include_rules: true }) + .then((data: any) => { + log.debug(`Successfully fetched role data for UID: ${roleUid}`, this.exportConfig.context); + return data; + }) + .catch((err: any) => { + log.debug(`Failed to fetch role data for UID: ${roleUid}`, this.exportConfig.context); + handleAndLogError( + err, + { ...this.exportConfig.context } + ); + }); + } - if (this.workflows === undefined || isEmpty(this.workflows)) { - log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); - } else { - const workflowsFilePath = pResolve(this.webhooksFolderPath, this.workflowConfig.fileName); - log.debug(`Writing workflows to: ${workflowsFilePath}`, this.exportConfig.context); - fsUtil.writeFile(workflowsFilePath, this.workflows); - log.success( - messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length ), - this.exportConfig.context, - ); + async getWorkflowRoles(workflow: Record) { + log.debug(`Processing workflow roles for workflow: ${workflow.uid}`, this.exportConfig.context); + + for (const stage of workflow?.workflow_stages) { + log.debug(`Processing workflow stage: ${stage.name}`, this.exportConfig.context); + + for (let i = 0; i < stage?.SYS_ACL?.roles?.uids?.length; i++) { + const roleUid = stage.SYS_ACL.roles.uids[i]; + log.debug(`Fetching role data for role UID: ${roleUid}`, this.exportConfig.context); + const roleData = await this.getRoles(roleUid); + stage.SYS_ACL.roles.uids[i] = roleData; + } } } @@ -62,7 +69,7 @@ export default class ExportWorkFlows extends BaseClass { .workflow() .fetchAll(this.qs) .then(async (data: any) => { - const { items, count } = data; + const { count, items } = data; //NOTE - Handle the case where old workflow api is enabled in that case getting responses as objects. const workflowCount = count !== undefined ? count : items.length; log.debug(`Fetched ${items?.length || 0} workflows out of total ${workflowCount}`, this.exportConfig.context); @@ -106,37 +113,30 @@ export default class ExportWorkFlows extends BaseClass { log.debug(`Sanitization complete. Total workflows processed: ${Object.keys(this.workflows).length}`, this.exportConfig.context); } - async getWorkflowRoles(workflow: Record) { - log.debug(`Processing workflow roles for workflow: ${workflow.uid}`, this.exportConfig.context); - - for (const stage of workflow?.workflow_stages) { - log.debug(`Processing workflow stage: ${stage.name}`, this.exportConfig.context); - - for (let i = 0; i < stage?.SYS_ACL?.roles?.uids?.length; i++) { - const roleUid = stage.SYS_ACL.roles.uids[i]; - log.debug(`Fetching role data for role UID: ${roleUid}`, this.exportConfig.context); - const roleData = await this.getRoles(roleUid); - stage.SYS_ACL.roles.uids[i] = roleData; - } - } - } + async start(): Promise { + this.webhooksFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.workflowConfig.dirName, + ); + log.debug(`Workflows folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - async getRoles(roleUid: number): Promise { - log.debug(`Fetching role with UID: ${roleUid}`, this.exportConfig.context); + await fsUtil.makeDirectory(this.webhooksFolderPath); + log.debug('Created workflows directory', this.exportConfig.context); - return await this.stack - .role(roleUid) - .fetch({ include_rules: true, include_permissions: true }) - .then((data: any) => { - log.debug(`Successfully fetched role data for UID: ${roleUid}`, this.exportConfig.context); - return data; - }) - .catch((err: any) => { - log.debug(`Failed to fetch role data for UID: ${roleUid}`, this.exportConfig.context); - handleAndLogError( - err, - { ...this.exportConfig.context } - ); - }); + await this.getWorkflows(); + log.debug(`Retrieved ${Object.keys(this.workflows).length} workflows`, this.exportConfig.context); + + if (this.workflows === undefined || isEmpty(this.workflows)) { + log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); + } else { + const workflowsFilePath = pResolve(this.webhooksFolderPath, this.workflowConfig.fileName); + log.debug(`Writing workflows to: ${workflowsFilePath}`, this.exportConfig.context); + fsUtil.writeFile(workflowsFilePath, this.workflows); + log.success( + messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length ), + this.exportConfig.context, + ); + } } } diff --git a/packages/contentstack-export/src/types/default-config.ts b/packages/contentstack-export/src/types/default-config.ts index 01cb84c89..61aebe620 100644 --- a/packages/contentstack-export/src/types/default-config.ts +++ b/packages/contentstack-export/src/types/default-config.ts @@ -5,10 +5,23 @@ interface AnyProperty { } export default interface DefaultConfig { - contentVersion: number; - versioning: boolean; - host: string; + apis: { + assets: string; + content_types: string; + entries: string; + environments: string; + extension: string; + globalfields: string; + labels: string; + locales: string; + stacks: string; + userSession: string; + users: string; + webhooks: string; + }; cdn?: string; + contentVersion: number; + developerHubBaseUrl: string; developerHubUrls: any; // use below hosts for eu region // host:'https://eu-api.contentstack.com/v3', @@ -17,216 +30,203 @@ export default interface DefaultConfig { // use below hosts for gcp-na region // host: 'https://gcp-na-api.contentstack.com' // use below hosts for gcp-eu region + fetchConcurrency: number; + host: string; + languagesCode: string[]; + marketplaceAppEncryptionKey: string; // host: 'https://gcp-eu-api.contentstack.com' modules: { - types: Modules[]; - locales: { - dirName: string; - fileName: string; - requiredKeys: string[]; - dependencies?: Modules[]; - }; - customRoles: { - dirName: string; - fileName: string; - customRolesLocalesFileName: string; + assets: { + assetsMetaKeys: string[]; // Default keys ['uid', 'url', 'filename'] + // This is the total no. of asset objects fetched in each 'get assets' call + batchLimit: number; + // no of asset version files (of a single asset) that'll be downloaded parallel + chunkFileSize: number; // measured on Megabits (5mb) dependencies?: Modules[]; - }; - 'custom-roles': { dirName: string; + displayExecutionTime: boolean; + downloadLimit: number; + enableDownloadStatus: boolean; + fetchConcurrency: number; fileName: string; - customRolesLocalesFileName: string; - dependencies?: Modules[]; + host: string; + includeVersionedAssets: boolean; + invalidKeys: string[]; + securedAssets: boolean; }; - environments: { - dirName: string; - fileName: string; + attributes: { dependencies?: Modules[]; - }; - labels: { dirName: string; fileName: string; invalidKeys: string[]; - dependencies?: Modules[]; }; - webhooks: { - dirName: string; - fileName: string; + audiences: { dependencies?: Modules[]; - }; - releases: { dirName: string; fileName: string; - releasesList: string; invalidKeys: string[]; - dependencies?: Modules[]; }; - workflows: { + 'composable-studio': { + apiBaseUrl: string; + apiVersion: string; dirName: string; fileName: string; - invalidKeys: string[]; - dependencies?: Modules[]; }; - 'publishing-rules': { - dirName: string; - fileName: string; - invalidKeys: string[]; + content_types: { dependencies?: Modules[]; - limit?: number; - }; - globalfields: { dirName: string; fileName: string; + // total no of content types fetched in each 'get content types' call + limit: number; validKeys: string[]; - dependencies?: Modules[]; }; - 'global-fields': { + 'content-types': { + dependencies?: Modules[]; dirName: string; fileName: string; + // total no of content types fetched in each 'get content types' call + limit: number; validKeys: string[]; - dependencies?: Modules[]; }; - assets: { - dirName: string; - fileName: string; - // This is the total no. of asset objects fetched in each 'get assets' call - batchLimit: number; - host: string; - invalidKeys: string[]; - // no of asset version files (of a single asset) that'll be downloaded parallel - chunkFileSize: number; // measured on Megabits (5mb) - downloadLimit: number; - fetchConcurrency: number; - assetsMetaKeys: string[]; // Default keys ['uid', 'url', 'filename'] - securedAssets: boolean; - displayExecutionTime: boolean; - enableDownloadStatus: boolean; - includeVersionedAssets: boolean; + 'custom-roles': { + customRolesLocalesFileName: string; dependencies?: Modules[]; - }; - content_types: { dirName: string; fileName: string; - validKeys: string[]; - // total no of content types fetched in each 'get content types' call - limit: number; - dependencies?: Modules[]; }; - 'content-types': { + customRoles: { + customRolesLocalesFileName: string; + dependencies?: Modules[]; dirName: string; fileName: string; - validKeys: string[]; - // total no of content types fetched in each 'get content types' call - limit: number; - dependencies?: Modules[]; + }; + dependency: { + entries: string[]; }; entries: { + batchLimit: number; + dependencies?: Modules[]; dirName: string; + downloadLimit: number; + exportVersions: boolean; fileName: string; invalidKeys: string[]; - batchLimit: number; - downloadLimit: number; // total no of entries fetched in each content type in a single call limit: number; - dependencies?: Modules[]; - exportVersions: boolean; }; - personalize: { + environments: { + dependencies?: Modules[]; dirName: string; - baseURL: Record; - } & AnyProperty; - variantEntry: { + fileName: string; + }; + events: { + dependencies?: Modules[]; dirName: string; fileName: string; - chunkFileSize: number; - query: { - skip: number; - limit: number; - include_variant: boolean; - include_count: boolean; - include_publish_details: boolean; - } & AnyProperty; - } & AnyProperty; + invalidKeys: string[]; + }; extensions: { + dependencies?: Modules[]; dirName: string; fileName: string; + }; + 'global-fields': { dependencies?: Modules[]; + dirName: string; + fileName: string; + validKeys: string[]; }; - stack: { + globalfields: { + dependencies?: Modules[]; dirName: string; fileName: string; + validKeys: string[]; + }; + labels: { dependencies?: Modules[]; + dirName: string; + fileName: string; + invalidKeys: string[]; }; - dependency: { - entries: string[]; + locales: { + dependencies?: Modules[]; + dirName: string; + fileName: string; + requiredKeys: string[]; }; marketplace_apps: { + dependencies?: Modules[]; dirName: string; fileName: string; - dependencies?: Modules[]; }; 'marketplace-apps': { - dirName: string; - fileName: string; dependencies?: Modules[]; - }; - 'composable-studio': { dirName: string; fileName: string; - apiBaseUrl: string; - apiVersion: string; }; masterLocale: { dirName: string; fileName: string; requiredKeys: string[]; }; - taxonomies: { + personalize: { + baseURL: Record; + dirName: string; + } & AnyProperty; + 'publishing-rules': { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; - dependencies?: Modules[]; - limit: number; + limit?: number; }; - events: { + releases: { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; + releasesList: string; + }; + stack: { dependencies?: Modules[]; + dirName: string; + fileName: string; }; - audiences: { + taxonomies: { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; + limit: number; + }; + types: Modules[]; + variantEntry: { + chunkFileSize: number; + dirName: string; + fileName: string; + query: { + include_count: boolean; + include_publish_details: boolean; + include_variant: boolean; + limit: number; + skip: number; + } & AnyProperty; + } & AnyProperty; + webhooks: { dependencies?: Modules[]; + dirName: string; + fileName: string; }; - attributes: { + workflows: { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; - dependencies?: Modules[]; }; }; - languagesCode: string[]; - apis: { - userSession: string; - globalfields: string; - locales: string; - labels: string; - environments: string; - assets: string; - content_types: string; - entries: string; - users: string; - extension: string; - webhooks: string; - stacks: string; - }; - preserveStackVersion: boolean; + onlyTSModules: string[]; personalizationEnabled: boolean; - fetchConcurrency: number; + preserveStackVersion: boolean; + versioning: boolean; writeConcurrency: number; - developerHubBaseUrl: string; - marketplaceAppEncryptionKey: string; - onlyTSModules: string[]; } diff --git a/packages/contentstack-export/src/types/export-config.ts b/packages/contentstack-export/src/types/export-config.ts index 8b0e1b37b..7e0ce6892 100644 --- a/packages/contentstack-export/src/types/export-config.ts +++ b/packages/contentstack-export/src/types/export-config.ts @@ -2,45 +2,45 @@ import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; export default interface ExportConfig extends DefaultConfig { - context: Context; - cliLogsPath: string; - exportDir: string; - data: string; - management_token?: string; + access_token?: string; apiKey: string; - forceStopMarketplaceAppsPrompt: boolean; auth_token?: string; - branchName?: string; + authenticationMethod?: string; branchAlias?: string; - securedAssets?: boolean; - contentTypes?: string[]; - branches?: branch[]; - branchEnabled?: boolean; branchDir?: string; - singleModuleExport?: boolean; - moduleName?: Modules; - master_locale: masterLocale; - query?: any; // Added query field + branchEnabled?: boolean; + branchName?: string; + branches?: branch[]; + cliLogsPath: string; + contentTypes?: string[]; + context: Context; + data: string; + exportDir: string; + forceStopMarketplaceAppsPrompt: boolean; headers?: { - api_key: string; + 'X-User-Agent': string; access_token?: string; + api_key: string; authtoken?: string; - 'X-User-Agent': string; organization_uid?: string; }; - access_token?: string; + management_token?: string; + master_locale: masterLocale; + moduleName?: Modules; org_uid?: string; - source_stack?: string; - sourceStackName?: string; + query?: any; // Added query field region: Region; - skipStackSettings?: boolean; + securedAssets?: boolean; + singleModuleExport?: boolean; skipDependencies?: boolean; - authenticationMethod?: string; + skipStackSettings?: boolean; + source_stack?: string; + sourceStackName?: string; } type branch = { - uid: string; source: string; + uid: string; }; type masterLocale = { diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index fd13364a5..592aae960 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -1,4 +1,5 @@ import { ContentstackClient } from '@contentstack/cli-utilities'; + import ExportConfig from './export-config'; // eslint-disable-next-line @typescript-eslint/no-redeclare @@ -15,144 +16,147 @@ export interface PrintOptions { } export interface InquirePayload { - type: string; - name: string; - message: string; choices?: Array; - transformer?: Function; + message: string; + name: string; + transformer?: (value: string, answers: Record) => boolean | string; + type: string; } export interface User { - email: string; authtoken: string; + email: string; } export interface Region { - name: string; - cma: string; cda: string; + cma: string; + name: string; uiHost: string; } export type Modules = - | 'stack' | 'assets' - | 'locales' + | 'composable-studio' + | 'content-types' + | 'custom-roles' + | 'entries' | 'environments' | 'extensions' - | 'webhooks' | 'global-fields' - | 'entries' - | 'content-types' - | 'custom-roles' - | 'workflows' - | 'publishing-rules' | 'labels' + | 'locales' | 'marketplace-apps' - | 'taxonomies' | 'personalize' - | 'composable-studio'; + | 'publishing-rules' + | 'stack' + | 'taxonomies' + | 'webhooks' + | 'workflows'; export type ModuleClassParams = { - stackAPIClient: ReturnType; exportConfig: ExportConfig; moduleName: Modules; + stackAPIClient: ReturnType; }; export interface ExternalConfig extends ExportConfig { + branchName: string; + data: string; + email?: string; + fetchConcurrency: number; master_locale: { - name: string; code: string; + name: string; }; - source_stack?: string; - data: string; - branchName: string; moduleName: Modules; - fetchConcurrency: number; - writeConcurrency: number; - securedAssets: boolean; - email?: string; password?: string; + securedAssets: boolean; + source_stack?: string; + writeConcurrency: number; } export interface ExtensionsConfig { + dependencies?: Modules[]; dirName: string; fileName: string; - dependencies?: Modules[]; limit?: number; } export interface MarketplaceAppsConfig { + dependencies?: Modules[]; dirName: string; fileName: string; - dependencies?: Modules[]; } export interface EnvironmentConfig { + dependencies?: Modules[]; dirName: string; fileName: string; - dependencies?: Modules[]; limit?: number; } export interface LabelConfig { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; - dependencies?: Modules[]; limit?: number; } export interface WebhookConfig { + dependencies?: Modules[]; dirName: string; fileName: string; - dependencies?: Modules[]; limit?: number; } export interface WorkflowConfig { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; - dependencies?: Modules[]; limit?: number; } export interface PublishingRulesConfig { + dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; - dependencies?: Modules[]; limit?: number; } export interface CustomRoleConfig { - dirName: string; - fileName: string; customRolesLocalesFileName: string; dependencies?: Modules[]; + dirName: string; + fileName: string; } export interface StackConfig { + dependencies?: Modules[]; dirName: string; fileName: string; - dependencies?: Modules[]; limit?: number; } export interface ComposableStudioConfig { - dirName: string; - fileName: string; apiBaseUrl: string; apiVersion: string; + dirName: string; + fileName: string; } export interface ComposableStudioProject { - name: string; - description: string; canvasUrl: string; connectedStackApiKey: string; contentTypeUid: string; + createdAt: string; + createdBy: string; + deletedAt: boolean; + description: string; + name: string; organizationUid: string; settings: { configuration: { @@ -160,12 +164,9 @@ export interface ComposableStudioProject { locale: string; }; }; - createdBy: string; - updatedBy: string; - deletedAt: boolean; - createdAt: string; - updatedAt: string; uid: string; + updatedAt: string; + updatedBy: string; } export interface Context { module: string; diff --git a/packages/contentstack-export/src/types/marketplace-app.ts b/packages/contentstack-export/src/types/marketplace-app.ts index 684d9015a..ec7497a2d 100644 --- a/packages/contentstack-export/src/types/marketplace-app.ts +++ b/packages/contentstack-export/src/types/marketplace-app.ts @@ -1,35 +1,35 @@ type AppLocation = + | 'cs.cm.stack.asset_sidebar' | 'cs.cm.stack.config' - | 'cs.cm.stack.dashboard' - | 'cs.cm.stack.sidebar' | 'cs.cm.stack.custom_field' + | 'cs.cm.stack.dashboard' | 'cs.cm.stack.rte' - | 'cs.cm.stack.asset_sidebar' + | 'cs.cm.stack.sidebar' | 'cs.org.config'; interface ExtensionMeta { - uid?: string; - name?: string; + blur?: boolean; + data_type?: string; + default_width?: 'full' | 'half'; description?: string; + enabled?: boolean; + extension_uid?: string; + name?: string; path?: string; signed: boolean; - extension_uid?: string; - data_type?: string; - enabled?: boolean; + uid?: string; width?: number; - blur?: boolean; - default_width?: 'full' | 'half'; } interface Extension { - type: AppLocation; meta: ExtensionMeta[]; + type: AppLocation; } interface LocationConfiguration { - signed: boolean; base_url: string; locations: Extension[]; + signed: boolean; } interface AnyProperty { @@ -37,29 +37,29 @@ interface AnyProperty { } type Manifest = { - uid: string; - name: string; - icon?: string; - hosting?: any; - version?: number; description: string; - organization_uid: string; framework_version?: string; + hosting?: any; + icon?: string; + name: string; oauth?: any; - webhook?: any; + organization_uid: string; + target_type: 'organization' | 'stack'; ui_location: LocationConfiguration; - target_type: 'stack' | 'organization'; + uid: string; + version?: number; visibility: 'private' | 'public' | 'public_unlisted'; + webhook?: any; } & AnyProperty; type Installation = { - uid: string; - status: string; - manifest: Manifest; configuration: any; + manifest: Manifest; server_configuration: any; + status: string; target: { type: string; uid: string }; ui_location: LocationConfiguration; + uid: string; } & AnyProperty; export { Installation, Manifest }; diff --git a/packages/contentstack-export/src/utils/basic-login.ts b/packages/contentstack-export/src/utils/basic-login.ts index 6a9d9cabd..584b5debc 100644 --- a/packages/contentstack-export/src/utils/basic-login.ts +++ b/packages/contentstack-export/src/utils/basic-login.ts @@ -7,7 +7,8 @@ * MIT Licensed */ -import { log, managementSDKClient, authHandler } from '@contentstack/cli-utilities'; +import { authHandler, log, managementSDKClient } from '@contentstack/cli-utilities'; + import { ExternalConfig } from '../types'; const login = async (config: ExternalConfig): Promise => { @@ -16,16 +17,18 @@ const login = async (config: ExternalConfig): Promise => { const response = await client.login({ email: config.email, password: config.password }).catch(Promise.reject); if (response?.user?.authtoken) { config.headers = { - api_key: config.source_stack, + 'X-User-Agent': 'contentstack-export/v', access_token: config.access_token, + api_key: config.source_stack, authtoken: response.user.authtoken, - 'X-User-Agent': 'contentstack-export/v', }; await authHandler.setConfigData('basicAuth', response.user); log.success(`Contentstack account authenticated successfully!`, config.context); return config; } else { log.error(`Failed to log in!`, config.context); + // CLI: exit after unrecoverable auth failure (same behavior as before lint pass) + // eslint-disable-next-line n/no-process-exit -- intentional CLI termination process.exit(1); } } else if (!config.email && !config.password && config.source_stack && config.access_token) { @@ -38,9 +41,9 @@ const login = async (config: ExternalConfig): Promise => { config.context, ); config.headers = { - api_key: config.source_stack, - access_token: config.access_token, 'X-User-Agent': 'contentstack-export/v', + access_token: config.access_token, + api_key: config.source_stack, }; return config; } diff --git a/packages/contentstack-export/src/utils/common-helper.ts b/packages/contentstack-export/src/utils/common-helper.ts index 6c3de9a5b..9a4bd34fc 100644 --- a/packages/contentstack-export/src/utils/common-helper.ts +++ b/packages/contentstack-export/src/utils/common-helper.ts @@ -4,12 +4,12 @@ * MIT Licensed */ +import { getLogPath, isAuthenticated, sanitizePath } from '@contentstack/cli-utilities'; import * as path from 'path'; import promiseLimit from 'promise-limit'; -import { isAuthenticated, getLogPath, sanitizePath } from '@contentstack/cli-utilities'; +import { ExportConfig, ExternalConfig } from '../types'; import { fsUtil } from './file-helper'; -import { ExternalConfig, ExportConfig } from '../types'; export const validateConfig = function (config: ExternalConfig) { if (!config.host || !config.cdn) { diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index c67b6c12b..fbfcbfaad 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -1,12 +1,13 @@ +import { cliux, configHandler,isAuthenticated, log, sanitizePath } from '@contentstack/cli-utilities'; +import { filter, includes } from 'lodash'; import merge from 'merge'; import * as path from 'path'; -import { configHandler, isAuthenticated,cliux, sanitizePath, log } from '@contentstack/cli-utilities'; + import defaultConfig from '../config'; -import { readFile } from './file-helper'; -import { askExportDir, askAPIKey } from './interactive'; -import login from './basic-login'; -import { filter, includes } from 'lodash'; import { ExportConfig } from '../types'; +import login from './basic-login'; +import { readFile } from './file-helper'; +import { askAPIKey, askExportDir } from './interactive'; const setupConfig = async (exportCmdFlags: any): Promise => { let config = merge({}, defaultConfig); @@ -43,7 +44,7 @@ const setupConfig = async (exportCmdFlags: any): Promise => { if (managementTokenAlias) { log.debug('Using management token alias', { alias: managementTokenAlias }); - const { token, apiKey } = configHandler.get(`tokens.${managementTokenAlias}`) || {}; + const { apiKey, token } = configHandler.get(`tokens.${managementTokenAlias}`) || {}; config.management_token = token; config.apiKey = apiKey; authenticationMethod = 'Management Token'; diff --git a/packages/contentstack-export/src/utils/file-helper.ts b/packages/contentstack-export/src/utils/file-helper.ts index b96ee98c1..52a4541a7 100644 --- a/packages/contentstack-export/src/utils/file-helper.ts +++ b/packages/contentstack-export/src/utils/file-helper.ts @@ -1,8 +1,8 @@ +import { FsUtility, sanitizePath } from '@contentstack/cli-utilities'; +import bigJSON from 'big-json'; import * as fs from 'fs'; -import * as path from 'path'; import mkdirp from 'mkdirp'; -import bigJSON from 'big-json'; -import { FsUtility, sanitizePath } from '@contentstack/cli-utilities'; +import * as path from 'path'; export const readFileSync = function (filePath: string, parse: boolean): unknown { let data; @@ -81,7 +81,7 @@ export const writeLargeFile = function (filePath: string, data: any): Promise { resolve(''); @@ -92,9 +92,9 @@ export const writeLargeFile = function (filePath: string, data: any): Promise { return cliux.inquire({ - type: 'input', message: 'CLI_AUTH_LOGIN_ENTER_PASSWORD', name: 'password', transformer: (pswd: string) => { @@ -13,42 +12,43 @@ export const askPassword = async () => { } return pswdMasked; }, + type: 'input', }); }; export const askOTPChannel = async (): Promise => { return cliux.inquire({ - type: 'list', - name: 'otpChannel', - message: 'CLI_AUTH_LOGIN_ASK_CHANNEL_FOR_OTP', choices: [ { name: 'Authy App', value: 'authy' }, { name: 'SMS', value: 'sms' }, ], + message: 'CLI_AUTH_LOGIN_ASK_CHANNEL_FOR_OTP', + name: 'otpChannel', + type: 'list', }); }; export const askOTP = async (): Promise => { return cliux.inquire({ - type: 'input', message: 'CLI_AUTH_LOGIN_ENTER_SECURITY_CODE', name: 'tfaToken', + type: 'input', }); }; export const askUsername = async (): Promise => { return cliux.inquire({ - type: 'input', message: 'CLI_AUTH_LOGIN_ENTER_EMAIL_ADDRESS', name: 'username', + type: 'input', }); }; export const askExportDir = async (): Promise => { let result = await cliux.inquire({ - type: 'input', message: 'Enter the path for storing the content: (current folder)', name: 'dir', + type: 'input', validate: validatePath, }); if (!result) { @@ -61,8 +61,8 @@ export const askExportDir = async (): Promise => { export const askAPIKey = async (): Promise => { return await cliux.inquire({ - type: 'input', message: 'Enter the stack api key', name: 'apiKey', + type: 'input', }); }; diff --git a/packages/contentstack-export/src/utils/logger.ts b/packages/contentstack-export/src/utils/logger.ts index 07aa897b8..821be1d65 100644 --- a/packages/contentstack-export/src/utils/logger.ts +++ b/packages/contentstack-export/src/utils/logger.ts @@ -4,12 +4,12 @@ * MIT Licensed */ -import * as winston from 'winston'; -import * as path from 'path'; +import { redactObject, sanitizePath } from '@contentstack/cli-utilities'; import mkdirp from 'mkdirp'; +import * as path from 'path'; +import * as winston from 'winston'; + import { ExportConfig } from '../types'; -import { sanitizePath, redactObject } from '@contentstack/cli-utilities'; -const slice = Array.prototype.slice; const ansiRegexPattern = [ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', @@ -24,7 +24,7 @@ function returnString(args: unknown[]) { if (item && typeof item === 'object') { try { const redactedObject = redactObject(item); - if(redactedObject && typeof redactedObject === 'object') { + if (redactedObject && typeof redactedObject === 'object') { return JSON.stringify(redactedObject); } } catch (error) {} @@ -39,17 +39,17 @@ function returnString(args: unknown[]) { return returnStr; } const myCustomLevels = { - levels: { - warn: 1, - info: 2, - debug: 3, - }, colors: { + debug: 'green', + error: 'red', //colors aren't being used anywhere as of now, we're using chalk to add colors while logging info: 'blue', - debug: 'green', warn: 'yellow', - error: 'red', + }, + levels: { + debug: 3, + info: 2, + warn: 1, }, }; @@ -67,70 +67,66 @@ function init(_logPath: string) { successTransport = { filename: path.join(sanitizePath(logsDir), 'success.log'), + level: 'info', maxFiles: 20, maxsize: 1000000, tailable: true, - level: 'info', }; errorTransport = { filename: path.join(sanitizePath(logsDir), 'error.log'), + level: 'error', maxFiles: 20, maxsize: 1000000, tailable: true, - level: 'error', }; logger = winston.createLogger({ + levels: myCustomLevels.levels, transports: [ new winston.transports.File(successTransport), new winston.transports.Console({ format: winston.format.simple() }), ], - levels: myCustomLevels.levels, }); errorLogger = winston.createLogger({ + levels: { error: 0 }, transports: [ new winston.transports.File(errorTransport), new winston.transports.Console({ - level: 'error', format: winston.format.combine( winston.format.colorize({ all: true, colors: { error: 'red' } }), winston.format.simple(), ), + level: 'error', }), ], - levels: { error: 0 }, }); } return { - log: function (message: any) { - const args = slice.call(arguments); + debug: function (...args: unknown[]) { const logString = returnString(args); if (logString) { - logger.log('info', logString); + logger.log('debug', logString); } }, - warn: function () { - const args = slice.call(arguments); + error: function (...args: unknown[]) { const logString = returnString(args); if (logString) { - logger.log('warn', logString); + errorLogger.log('error', logString); } }, - error: function (message: any) { - const args = slice.call(arguments); + log: function (...args: unknown[]) { const logString = returnString(args); if (logString) { - errorLogger.log('error', logString); + logger.log('info', logString); } }, - debug: function () { - const args = slice.call(arguments); + warn: function (...args: unknown[]) { const logString = returnString(args); if (logString) { - logger.log('debug', logString); + logger.log('warn', logString); } }, }; diff --git a/packages/contentstack-export/src/utils/marketplace-app-helper.ts b/packages/contentstack-export/src/utils/marketplace-app-helper.ts index 970f35527..efbe1dc3f 100644 --- a/packages/contentstack-export/src/utils/marketplace-app-helper.ts +++ b/packages/contentstack-export/src/utils/marketplace-app-helper.ts @@ -1,4 +1,4 @@ -import { cliux, handleAndLogError, NodeCrypto, managementSDKClient, createDeveloperHubUrl } from '@contentstack/cli-utilities'; +import { NodeCrypto, cliux, createDeveloperHubUrl, handleAndLogError, managementSDKClient } from '@contentstack/cli-utilities'; import { ExportConfig } from '../types'; @@ -25,15 +25,15 @@ export async function createNodeCryptoInstance(config: ExportConfig): Promise { if (!url) return "Encryption key can't be empty."; return true; }, - message: 'Enter Marketplace app configurations encryption key', }); } diff --git a/packages/contentstack-export/src/utils/setup-branches.ts b/packages/contentstack-export/src/utils/setup-branches.ts index e5097800c..d9183901c 100644 --- a/packages/contentstack-export/src/utils/setup-branches.ts +++ b/packages/contentstack-export/src/utils/setup-branches.ts @@ -1,8 +1,8 @@ -import * as path from 'path'; import { sanitizePath } from '@contentstack/cli-utilities'; +import * as path from 'path'; import { ExportConfig } from '../types'; -import { writeFileSync, makeDirectory } from './file-helper'; +import { makeDirectory, writeFileSync } from './file-helper'; const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { if (typeof config !== 'object') { @@ -15,6 +15,7 @@ const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { const result = await stackAPIClient .branch(config.branchName) .fetch() + // eslint-disable-next-line @typescript-eslint/no-empty-function -- ignore branch fetch failure; handled below .catch((_err: Error) => {}); if (result && typeof result === 'object') { branches.push(result); @@ -27,6 +28,7 @@ const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { .branch() .query() .find() + // eslint-disable-next-line @typescript-eslint/no-empty-function -- ignore list fetch failure; handled below .catch((_err: Error) => {}); if (result && result.items && Array.isArray(result.items) && result.items.length > 0) { branches = result.items; diff --git a/packages/contentstack-export/src/utils/setup-export-dir.ts b/packages/contentstack-export/src/utils/setup-export-dir.ts index 76de5b364..5d8332ab0 100644 --- a/packages/contentstack-export/src/utils/setup-export-dir.ts +++ b/packages/contentstack-export/src/utils/setup-export-dir.ts @@ -1,5 +1,5 @@ -import path from 'path'; import { sanitizePath } from '@contentstack/cli-utilities'; +import path from 'path'; import { ExportConfig } from '../types'; import { makeDirectory } from './file-helper'; 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 56ef04ef7..408c9a63c 100644 --- a/packages/contentstack-export/test/unit/export/modules/assets.test.ts +++ b/packages/contentstack-export/test/unit/export/modules/assets.test.ts @@ -113,6 +113,11 @@ describe('ExportAssets', () => { fileName: 'workflows.json', invalidKeys: [] }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: [], + }, globalfields: { dirName: 'global_fields', fileName: 'globalfields.json', diff --git a/packages/contentstack-export/test/unit/export/modules/base-class.test.ts b/packages/contentstack-export/test/unit/export/modules/base-class.test.ts index 0ffe4187f..4b62b5230 100644 --- a/packages/contentstack-export/test/unit/export/modules/base-class.test.ts +++ b/packages/contentstack-export/test/unit/export/modules/base-class.test.ts @@ -131,6 +131,11 @@ describe('BaseClass', () => { fileName: 'workflows.json', invalidKeys: [] }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: [], + }, globalfields: { dirName: 'global_fields', fileName: 'globalfields.json', diff --git a/packages/contentstack-export/test/unit/export/modules/publishing-rules.test.ts b/packages/contentstack-export/test/unit/export/modules/publishing-rules.test.ts new file mode 100644 index 000000000..e6ab1321b --- /dev/null +++ b/packages/contentstack-export/test/unit/export/modules/publishing-rules.test.ts @@ -0,0 +1,180 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import { resolve as pResolve } from 'node:path'; +import { FsUtility } from '@contentstack/cli-utilities'; +import ExportPublishingRules from '../../../../src/export/modules/publishing-rules'; +import ExportConfig from '../../../../src/types/export-config'; + +describe('ExportPublishingRules', () => { + let exportPublishingRules: ExportPublishingRules; + let mockStackClient: any; + let mockExportConfig: ExportConfig; + + beforeEach(() => { + mockStackClient = { + workflow: sinon.stub().returns({ + publishRule: sinon.stub().returns({ + fetchAll: sinon.stub().resolves({ items: [], count: 0 }), + }), + }), + }; + + mockExportConfig = { + contentVersion: 1, + versioning: false, + host: 'https://api.contentstack.io', + developerHubUrls: {}, + apiKey: 'test-api-key', + exportDir: '/test/export', + data: '/test/data', + branchName: '', + context: { + command: 'cm:stacks:export', + module: 'publishing-rules', + userId: 'user-123', + email: 'test@example.com', + sessionId: 'session-123', + apiKey: 'test-api-key', + orgId: 'org-123', + authenticationMethod: 'Basic Auth', + }, + cliLogsPath: '/test/logs', + forceStopMarketplaceAppsPrompt: false, + master_locale: { code: 'en-us' }, + region: { + name: 'us', + cma: 'https://api.contentstack.io', + cda: 'https://cdn.contentstack.io', + uiHost: 'https://app.contentstack.com', + }, + skipStackSettings: false, + skipDependencies: false, + languagesCode: ['en'], + apis: {}, + preserveStackVersion: false, + personalizationEnabled: false, + fetchConcurrency: 5, + writeConcurrency: 5, + developerHubBaseUrl: '', + marketplaceAppEncryptionKey: '', + onlyTSModules: [], + modules: { + types: ['publishing-rules'], + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['stackHeaders', 'created_at'], + }, + }, + } as any; + + exportPublishingRules = new ExportPublishingRules({ + exportConfig: mockExportConfig, + stackAPIClient: mockStackClient, + moduleName: 'publishing-rules', + }); + + sinon.stub(FsUtility.prototype, 'writeFile').resolves(); + sinon.stub(FsUtility.prototype, 'makeDirectory').resolves(); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('Constructor', () => { + it('sets context.module to publishing-rules and reads module config', () => { + expect(exportPublishingRules).to.be.instanceOf(ExportPublishingRules); + expect(exportPublishingRules.exportConfig.context.module).to.equal('publishing-rules'); + expect((exportPublishingRules as any).publishingRulesConfig.fileName).to.equal('publishing-rules.json'); + expect((exportPublishingRules as any).publishingRulesConfig.dirName).to.equal('workflows'); + }); + }); + + describe('start()', () => { + it('resolves output path from data, branchName, and publishing-rules dirName', async () => { + const fetchAll = sinon.stub().resolves({ items: [], count: 0 }); + mockStackClient.workflow.returns({ + publishRule: sinon.stub().returns({ fetchAll }), + }); + + await exportPublishingRules.start(); + + const expectedFolder = pResolve(mockExportConfig.data, mockExportConfig.branchName || '', 'workflows'); + expect((FsUtility.prototype.makeDirectory as sinon.SinonStub).calledWith(expectedFolder)).to.be.true; + }); + + it('writes publishing-rules.json with rules omitting invalidKeys when API returns items', async () => { + const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub; + const items = [ + { + uid: 'pr-1', + name: 'Rule 1', + stackHeaders: { h: 1 }, + created_at: '2020-01-01', + }, + ]; + mockStackClient.workflow.returns({ + publishRule: sinon.stub().returns({ + fetchAll: sinon.stub().resolves({ items, count: 1 }), + }), + }); + + await exportPublishingRules.start(); + + const expectedPath = pResolve( + mockExportConfig.data, + mockExportConfig.branchName || '', + 'workflows', + 'publishing-rules.json', + ); + expect(writeFileStub.calledOnce).to.be.true; + expect(writeFileStub.firstCall.args[0]).to.equal(expectedPath); + const written = writeFileStub.firstCall.args[1] as Record>; + expect(written['pr-1']).to.deep.equal({ uid: 'pr-1', name: 'Rule 1' }); + expect(written['pr-1'].stackHeaders).to.equal(undefined); + expect(written['pr-1'].created_at).to.equal(undefined); + }); + + it('does not write the rules file when no rules are returned', async () => { + const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub; + mockStackClient.workflow.returns({ + publishRule: sinon.stub().returns({ + fetchAll: sinon.stub().resolves({ items: [], count: 0 }), + }), + }); + + await exportPublishingRules.start(); + + expect(writeFileStub.called).to.be.false; + }); + + it('requests the next page when count exceeds items length (pagination)', async () => { + const fetchAll = sinon.stub(); + fetchAll.onFirstCall().resolves({ + items: [ + { uid: 'a', name: 'A' }, + { uid: 'b', name: 'B' }, + ], + count: 3, + }); + fetchAll.onSecondCall().resolves({ + items: [{ uid: 'c', name: 'C' }], + count: 3, + }); + + mockStackClient.workflow.returns({ + publishRule: sinon.stub().returns({ fetchAll }), + }); + + await exportPublishingRules.start(); + + expect(fetchAll.callCount).to.equal(2); + expect(fetchAll.secondCall.args[0]).to.deep.include({ skip: 2, include_count: true }); + + const writeFileStub = FsUtility.prototype.writeFile as sinon.SinonStub; + const written = writeFileStub.firstCall.args[1] as Record>; + expect(Object.keys(written).sort((x, y) => x.localeCompare(y))).to.deep.equal(['a', 'b', 'c']); + }); + }); +}); From f143fb2b1536e5468a9f2efa247930fafe26bf53 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Thu, 9 Apr 2026 15:26:00 +0530 Subject: [PATCH 4/9] update script --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7c2e9e7a7..79857b2db 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "private": true, "scripts": { - "clean:packages": "pnpm -r --filter './packages/*' run clean:packages", + "clean:packages": "pnpm -r --filter './packages/*' run clean", "build": "pnpm -r --filter './packages/*' run build", "test": "pnpm -r --filter './packages/*' run test", "prepack": "pnpm -r --filter './packages/*' run prepack", @@ -27,4 +27,4 @@ "workspaces": [ "packages/*" ] -} +} \ No newline at end of file From 53505812f791dbd73fc5900d6eafc2903e8adbc9 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Tue, 14 Apr 2026 12:46:04 +0530 Subject: [PATCH 5/9] update lockfile --- .talismanrc | 20 +- pnpm-lock.yaml | 3252 ++++++++++++++++++++++++------------------------ 2 files changed, 1660 insertions(+), 1612 deletions(-) diff --git a/.talismanrc b/.talismanrc index 214186788..3715ab066 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,22 +1,4 @@ fileignoreconfig: - filename: pnpm-lock.yaml - checksum: 116a6a58661750ea27750f5e51939513168005c3d72720201934c6a0e9dc48bf - - filename: .cursor/rules/dev-workflow.md - checksum: 3c3a483b44901bb440b4ce311a40d6e8c11decf9795f6d2d1d3a3787aa9981c3 - - filename: .cursor/skills/code-review/SKILL.md - checksum: 29d812ac5c2ed4c55490f8d31e15eb592851601a6a141354cb458b1b9f1daa7a - - filename: .cursor/skills/code-review/references/code-review-checklist.md - checksum: bdf7453f08d7209deaee411f47a1132ee872b28f0eb082563dfe20aa56eab057 - - filename: .cursor/skills/contentstack-cli/SKILL.md - checksum: 45f0d0c81086eaee850311e0caae198cf6dd2a7bc73bd1340b320b15047c6dae - - filename: .cursor/rules/contentstack-plugin.mdc - checksum: 4d41211088c2302a533559bb1e7e80fe69e6980f23c9a2e90b8ea9d03ba3f040 - - filename: .cursor/rules/oclif-commands.mdc - checksum: 8e269309cbfc9687e4a889c4a7983f145e77066d515dae53968d7553ae726b41 - - filename: .cursor/commands/code-review.md - checksum: a2737c43d58de842cf48c06b0471648a7c38b5fa8854d7c30f3d9258cd8b48f9 - - filename: .cursor/skills/contentstack-cli/references/contentstack-patterns.md - checksum: 9888d481b6a1ae8c7102d9efed0fdbae2b7592f582a62c8bff6deccf03fdf341 - - filename: .cursor/skills/testing/references/testing-patterns.md - checksum: 0a6cb66f27eda46b40508517063a2f43fea1b4b8df878e7ddff404ab7fc126f8 + checksum: fa2b1ffabad41301ba5d336eb52c02b94ab4b4a573533f1b6e79e7c37ebeef5e version: '1.0' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 592bdbb0e..693487ca9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,25 +17,25 @@ importers: version: 9.1.7 pnpm: specifier: ^10.28.0 - version: 10.30.3 + version: 10.33.0 packages/contentstack-audit: dependencies: '@contentstack/cli-command': specifier: ~1.8.0 - version: 1.8.0(@types/node@20.19.34) + version: 1.8.0(@types/node@20.19.39) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@20.19.34) + version: 1.18.1(@types/node@20.19.39) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 '@oclif/plugin-plugins': specifier: ^5.4.54 - version: 5.4.56 + version: 5.4.60 chalk: specifier: ^4.1.2 version: 4.1.2 @@ -44,7 +44,7 @@ importers: version: 4.3.6 fs-extra: specifier: ^11.3.0 - version: 11.3.3 + version: 11.3.4 lodash: specifier: 4.18.1 version: 4.18.1 @@ -57,7 +57,7 @@ importers: devDependencies: '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/chai': specifier: ^4.3.20 version: 4.3.20 @@ -69,7 +69,7 @@ importers: version: 10.0.10 '@types/node': specifier: ^20.17.50 - version: 20.19.34 + version: 20.19.39 '@types/uuid': specifier: ^9.0.8 version: 9.0.8 @@ -81,7 +81,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@5.9.3) + version: 6.0.157(eslint@8.57.1)(typescript@5.9.3) eslint-config-oclif-typescript: specifier: ^3.1.14 version: 3.1.14(eslint@8.57.1)(typescript@5.9.3) @@ -93,16 +93,16 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@20.19.34) + version: 4.23.0(@types/node@20.19.39) shx: specifier: ^0.4.0 version: 0.4.0 sinon: specifier: ^21.0.1 - version: 21.0.1 + version: 21.1.2 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.19.34)(typescript@5.9.3) + version: 10.9.2(@types/node@20.19.39)(typescript@5.9.3) typescript: specifier: ^5.8.3 version: 5.9.3 @@ -117,16 +117,16 @@ importers: version: 1.8.0(@types/node@14.18.63) '@contentstack/cli-config': specifier: ~1.20.0 - version: 1.20.0(@types/node@14.18.63) + version: 1.20.1(@types/node@14.18.63) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@14.18.63)(debug@4.4.3) + version: 1.18.1(@types/node@14.18.63)(debug@4.4.3) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.37 - version: 6.2.37 + version: 6.2.44 inquirer: specifier: 8.2.7 version: 8.2.7(@types/node@14.18.63) @@ -135,11 +135,11 @@ importers: version: 1.0.4 tar: specifier: ^7.5.11 - version: 7.5.11 + version: 7.5.13 devDependencies: '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/inquirer': specifier: ^9.0.8 version: 9.0.9 @@ -160,7 +160,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) eslint-config-oclif-typescript: specifier: ^3.1.14 version: 3.1.14(eslint@8.57.1)(typescript@4.9.5) @@ -172,7 +172,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@14.18.63) + version: 4.23.0(@types/node@14.18.63) tmp: specifier: ^0.2.3 version: 0.2.5 @@ -187,16 +187,16 @@ importers: dependencies: '@contentstack/cli-command': specifier: ~1.8.0 - version: 1.8.0(@types/node@22.19.12) + version: 1.8.0(@types/node@22.19.17) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@22.19.12) + version: 1.18.1(@types/node@22.19.17) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 chalk: specifier: ^4.1.2 version: 4.1.2 @@ -227,7 +227,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) mocha: specifier: 10.8.2 version: 10.8.2 @@ -236,13 +236,13 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@22.19.12) + version: 4.23.0(@types/node@22.19.17) sinon: specifier: ^21.0.1 - version: 21.0.1 + version: 21.1.2 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.19.12)(typescript@4.9.5) + version: 10.9.2(@types/node@22.19.17)(typescript@4.9.5) typescript: specifier: ^4.9.5 version: 4.9.5 @@ -251,19 +251,19 @@ importers: dependencies: '@contentstack/cli-command': specifier: ~1.8.0 - version: 1.8.0(@types/node@22.19.12) + version: 1.8.0(@types/node@22.19.17) '@contentstack/cli-config': specifier: ~1.20.0 - version: 1.20.0(@types/node@22.19.12) + version: 1.20.1(@types/node@22.19.17) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@22.19.12) + version: 1.18.1(@types/node@22.19.17) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 chalk: specifier: ^4.1.2 version: 4.1.2 @@ -272,7 +272,7 @@ importers: version: 16.6.1 inquirer: specifier: 8.2.7 - version: 8.2.7(@types/node@22.19.12) + version: 8.2.7(@types/node@22.19.17) lodash: specifier: 4.18.1 version: 4.18.1 @@ -282,7 +282,7 @@ importers: devDependencies: '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) chai: specifier: ^4.5.0 version: 4.5.0 @@ -291,7 +291,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@5.9.3) + version: 6.0.157(eslint@8.57.1)(typescript@5.9.3) mocha: specifier: ^10.8.2 version: 10.8.2 @@ -300,7 +300,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@22.19.12) + version: 4.23.0(@types/node@22.19.17) packages/contentstack-clone: dependencies: @@ -318,13 +318,13 @@ importers: version: 1.8.0(@types/node@14.18.63) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@14.18.63)(debug@4.4.3) + version: 1.18.1(@types/node@14.18.63)(debug@4.4.3) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 chalk: specifier: ^4.1.2 version: 4.1.2 @@ -349,7 +349,7 @@ importers: devDependencies: '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/chai': specifier: ^4.3.0 version: 4.3.20 @@ -364,7 +364,7 @@ importers: version: 10.0.20 '@typescript-eslint/eslint-plugin': specifier: ^5.62.0 - version: 5.62.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + version: 5.62.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) chai: specifier: ^4.5.0 version: 4.5.0 @@ -373,7 +373,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) mocha: specifier: ^10.8.2 version: 10.8.2 @@ -382,10 +382,10 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@14.18.63) + version: 4.23.0(@types/node@14.18.63) sinon: specifier: ^21.0.1 - version: 21.0.1 + version: 21.1.2 ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@14.18.63)(typescript@4.9.5) @@ -397,16 +397,16 @@ importers: dependencies: '@contentstack/cli-command': specifier: ~1.8.0 - version: 1.8.0(@types/node@22.19.12) + version: 1.8.0(@types/node@22.19.17) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@22.19.12) + version: 1.18.1(@types/node@22.19.17) '@contentstack/cli-variants': specifier: ~1.4.0 version: link:../contentstack-variants '@oclif/core': specifier: ^4.3.3 - version: 4.8.1 + version: 4.10.5 async: specifier: ^3.2.6 version: 3.2.6 @@ -440,19 +440,19 @@ importers: devDependencies: '@contentstack/cli-auth': specifier: ~1.8.0 - version: 1.8.0(@types/node@22.19.12) + version: 1.8.0(@types/node@22.19.17) '@contentstack/cli-config': specifier: ~1.20.0 - version: 1.20.0(@types/node@22.19.12) + version: 1.20.1(@types/node@22.19.17) '@contentstack/cli-dev-dependencies': specifier: ^1.3.1 version: 1.3.1 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/big-json': specifier: ^3.2.5 version: 3.2.5 @@ -485,7 +485,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.68 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) mocha: specifier: 10.8.2 version: 10.8.2 @@ -494,7 +494,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@22.19.12) + version: 4.23.0(@types/node@22.19.17) sinon: specifier: ^17.0.1 version: 17.0.2 @@ -503,7 +503,7 @@ importers: version: 0.5.21 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.19.12)(typescript@4.9.5) + version: 10.9.2(@types/node@22.19.17)(typescript@4.9.5) typescript: specifier: ^4.9.5 version: 4.9.5 @@ -512,32 +512,32 @@ importers: dependencies: '@contentstack/cli-command': specifier: ~1.8.0 - version: 1.8.0(@types/node@20.19.34) + version: 1.8.0(@types/node@20.19.39) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@20.19.34) + version: 1.18.1(@types/node@20.19.39) '@oclif/core': specifier: ^4.8.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.32 - version: 6.2.37 + version: 6.2.44 fast-csv: specifier: ^4.3.6 version: 4.3.6 inquirer: specifier: 8.2.7 - version: 8.2.7(@types/node@20.19.34) + version: 8.2.7(@types/node@20.19.39) inquirer-checkbox-plus-prompt: specifier: 1.4.2 - version: 1.4.2(inquirer@8.2.7(@types/node@20.19.34)) + version: 1.4.2(inquirer@8.2.7(@types/node@20.19.39)) mkdirp: specifier: ^3.0.1 version: 3.0.1 devDependencies: '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/chai': specifier: ^4.3.20 version: 4.3.20 @@ -552,7 +552,7 @@ importers: version: 10.0.10 '@types/node': specifier: ^20.17.50 - version: 20.19.34 + version: 20.19.39 chai: specifier: ^4.5.0 version: 4.5.0 @@ -561,7 +561,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@5.9.3) + version: 6.0.157(eslint@8.57.1)(typescript@5.9.3) eslint-config-oclif-typescript: specifier: ^3.1.14 version: 3.1.14(eslint@8.57.1)(typescript@5.9.3) @@ -576,13 +576,13 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@20.19.34) + version: 4.23.0(@types/node@20.19.39) sinon: specifier: ^19.0.5 version: 19.0.5 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.19.34)(typescript@5.9.3) + version: 10.9.2(@types/node@20.19.39)(typescript@5.9.3) typescript: specifier: ^5.8.3 version: 5.9.3 @@ -597,13 +597,13 @@ importers: version: 1.8.0(@types/node@14.18.63)(debug@4.4.3) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@14.18.63)(debug@4.4.3) + version: 1.18.1(@types/node@14.18.63)(debug@4.4.3) '@contentstack/cli-variants': specifier: ~1.4.0 version: link:../contentstack-variants '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 big-json: specifier: ^3.2.0 version: 3.2.0 @@ -618,7 +618,7 @@ importers: version: 4.4.3(supports-color@8.1.1) fs-extra: specifier: ^11.3.3 - version: 11.3.3 + version: 11.3.4 lodash: specifier: 4.18.1 version: 4.18.1 @@ -643,7 +643,7 @@ importers: devDependencies: '@oclif/test': specifier: ^4.1.16 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/big-json': specifier: ^3.2.5 version: 3.2.5 @@ -673,13 +673,13 @@ importers: version: 9.0.8 '@typescript-eslint/eslint-plugin': specifier: ^5.62.0 - version: 5.62.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + version: 5.62.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) eslint: specifier: ^8.57.1 version: 8.57.1 eslint-config-oclif: specifier: ^6.0.89 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) mocha: specifier: ^10.8.2 version: 10.8.2 @@ -688,7 +688,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@14.18.63) + version: 4.23.0(@types/node@14.18.63) rewire: specifier: ^9.0.1 version: 9.0.1 @@ -706,10 +706,10 @@ importers: version: 1.8.0(@types/node@14.18.63) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@14.18.63)(debug@4.4.3) + version: 1.18.1(@types/node@14.18.63)(debug@4.4.3) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 big-json: specifier: ^3.2.0 version: 3.2.0 @@ -718,7 +718,7 @@ importers: version: 4.1.2 fs-extra: specifier: ^11.3.0 - version: 11.3.3 + version: 11.3.4 lodash: specifier: 4.18.1 version: 4.18.1 @@ -764,7 +764,7 @@ importers: version: 9.0.8 '@typescript-eslint/eslint-plugin': specifier: ^5.62.0 - version: 5.62.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + version: 5.62.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) chai: specifier: ^4.5.0 version: 4.5.0 @@ -773,7 +773,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) mocha: specifier: ^10.8.2 version: 10.8.2 @@ -782,7 +782,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@14.18.63) + version: 4.23.0(@types/node@14.18.63) rewire: specifier: ^9.0.1 version: 9.0.1 @@ -803,13 +803,13 @@ importers: version: 1.8.0(@types/node@14.18.63) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@14.18.63)(debug@4.4.3) + version: 1.18.1(@types/node@14.18.63)(debug@4.4.3) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 async: specifier: ^3.2.6 version: 3.2.6 @@ -834,7 +834,7 @@ importers: devDependencies: '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/mocha': specifier: ^8.2.3 version: 8.2.3 @@ -849,7 +849,7 @@ importers: version: 8.57.1 eslint-config-oclif: specifier: ^6.0.62 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) jsdoc-to-markdown: specifier: ^8.0.3 version: 8.0.3 @@ -864,7 +864,7 @@ importers: version: 15.1.0 oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@14.18.63) + version: 4.23.0(@types/node@14.18.63) sinon: specifier: ^19.0.5 version: 19.0.5 @@ -888,7 +888,7 @@ importers: version: 1.8.0(@types/node@14.18.63) '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@14.18.63)(debug@4.4.3) + version: 1.18.1(@types/node@14.18.63)(debug@4.4.3) inquirer: specifier: 8.2.7 version: 8.2.7(@types/node@14.18.63) @@ -897,7 +897,7 @@ importers: version: 1.0.4 tar: specifier: ^7.5.11 - version: 7.5.11 + version: 7.5.13 tmp: specifier: ^0.2.5 version: 0.2.5 @@ -922,13 +922,13 @@ importers: version: 0.2.6 axios: specifier: ^1.13.5 - version: 1.13.5(debug@4.4.3) + version: 1.15.0(debug@4.4.3) eslint: specifier: ^8.57.1 version: 8.57.1 eslint-config-oclif: specifier: ^6.0.137 - version: 6.0.144(eslint@8.57.1)(typescript@4.9.5) + version: 6.0.157(eslint@8.57.1)(typescript@4.9.5) eslint-config-oclif-typescript: specifier: ^3.1.14 version: 3.1.14(eslint@8.57.1)(typescript@4.9.5) @@ -937,10 +937,10 @@ importers: version: 29.7.0(@types/node@14.18.63)(ts-node@8.10.2(typescript@4.9.5)) oclif: specifier: ^4.17.46 - version: 4.22.81(@types/node@14.18.63) + version: 4.23.0(@types/node@14.18.63) ts-jest: specifier: ^29.4.6 - version: 29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@14.18.63)(ts-node@8.10.2(typescript@4.9.5)))(typescript@4.9.5) + version: 29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@14.18.63)(ts-node@8.10.2(typescript@4.9.5)))(typescript@4.9.5) ts-node: specifier: ^8.10.2 version: 8.10.2(typescript@4.9.5) @@ -952,13 +952,13 @@ importers: dependencies: '@contentstack/cli-utilities': specifier: ~1.18.0 - version: 1.18.0(@types/node@20.19.34) + version: 1.18.1(@types/node@20.19.39) '@oclif/core': specifier: ^4.3.0 - version: 4.8.1 + version: 4.10.5 '@oclif/plugin-help': specifier: ^6.2.28 - version: 6.2.37 + version: 6.2.44 lodash: specifier: 4.18.1 version: 4.18.1 @@ -974,10 +974,10 @@ importers: version: 1.3.1 '@oclif/test': specifier: ^4.1.13 - version: 4.1.16(@oclif/core@4.8.1) + version: 4.1.18(@oclif/core@4.10.5) '@types/node': specifier: ^20.17.50 - version: 20.19.34 + version: 20.19.39 mocha: specifier: ^10.8.2 version: 10.8.2 @@ -986,7 +986,7 @@ importers: version: 15.1.0 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.19.34)(typescript@5.9.3) + version: 10.9.2(@types/node@20.19.39)(typescript@5.9.3) typescript: specifier: ^5.8.3 version: 5.9.3 @@ -1016,131 +1016,131 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-cloudfront@3.998.0': - resolution: {integrity: sha512-febsjtoh9Weumw1kCHBk9XC8kpL3aDpjZK8U/U6VfW11/yJ6lCjF6c8GxJ8kLZXEB9cgO5bn2B6FsRHBXMKMsQ==} + '@aws-sdk/client-cloudfront@3.1009.0': + resolution: {integrity: sha512-KRac+gkuj3u49IyWkrudHRlP/q/faTto+1xRS7Aj6cDGewMIzgdQArrdZEJoVntbaVZHLM5s/NVmWORzBWNcSw==} engines: {node: '>=20.0.0'} - '@aws-sdk/client-s3@3.998.0': - resolution: {integrity: sha512-XkJ6GN+egutEHSa9+t4OngCRyyP6Zl+4FX+hN7rDqlLjPuK++NHdMVrRSaVq1/H1m0+Nif0Rtz1BiTYP/htmvg==} + '@aws-sdk/client-s3@3.1014.0': + resolution: {integrity: sha512-0XLrOT4Cm3NEhhiME7l/8LbTXS4KdsbR4dSrY207KNKTcHLLTZ9EXt4ZpgnTfLvWQF3pGP2us4Zi1fYLo0N+Ow==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.973.14': - resolution: {integrity: sha512-iAQ1jIGESTVjoqNNY9VlsE9FnCz+Hc8s+dgurF6WrgFyVIw+uggH+V102RFhwjRv4dLSSLfzjDwvQnLszov7TQ==} + '@aws-sdk/core@3.973.27': + resolution: {integrity: sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A==} engines: {node: '>=20.0.0'} - '@aws-sdk/crc64-nvme@3.972.2': - resolution: {integrity: sha512-mhTYqkvoC9pm8Lm7KWmH/BDXylzwOTnqqbix4mUG/AODazcigIKRYkzPc2bld6q4h9q1asQCiPC2S1Q6rvSjIQ==} + '@aws-sdk/crc64-nvme@3.972.6': + resolution: {integrity: sha512-NMbiqKdruhwwgI6nzBVe2jWMkXjaoQz2YOs3rFX+2F3gGyrJDkDPwMpV/RsTFeq2vAQ055wZNtOXFK4NYSkM8g==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.12': - resolution: {integrity: sha512-WPtj/iAYHHd+NDM6AZoilZwUz0nMaPxbTPGLA7nhyIYRZN2L8trqfbNvm7g/Jr3gzfKp1LpO6AtBTnrhz9WW2g==} + '@aws-sdk/credential-provider-env@3.972.25': + resolution: {integrity: sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.14': - resolution: {integrity: sha512-umtjCicH2o/Fcc8Fu1562UkDyt6gql4czTYVlUfHfAM8S4QEKggzmtHYYYpPfQcjFj1ajyy68ahYSuF67x4ptQ==} + '@aws-sdk/credential-provider-http@3.972.27': + resolution: {integrity: sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.12': - resolution: {integrity: sha512-qjzgnMl6GIBbVeK74jBqSF07+s6kyeZl5R88qjMs302JlqkxE57jkvflDmZ9I017ffEWqIUa9/M4Hfp28qyu1g==} + '@aws-sdk/credential-provider-ini@3.972.29': + resolution: {integrity: sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.12': - resolution: {integrity: sha512-AO57y46PzG24bJzxWLk+FYJG6MzxvXoFXnOKnmKUGV43ub4/FS/4Rz7zCC6ThqUotgqEFd30l5LTAd65RP65pg==} + '@aws-sdk/credential-provider-login@3.972.29': + resolution: {integrity: sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.13': - resolution: {integrity: sha512-ME2sgus+gFRtiudy5Xqj9iT/tj8lHOIGrFgktuO5skJU4EngOvTZ1Hpj8mknrW4FgWXmpWhc88NtEscUuuDpKw==} + '@aws-sdk/credential-provider-node@3.972.30': + resolution: {integrity: sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.12': - resolution: {integrity: sha512-msxrHBpVP5AOIDohNPCINUtL47f7XI1TEru3N13uM3nWUMvIRA1vFa8Tlxbxm1EntPPvLAxRmvE5EbjDjOZkbw==} + '@aws-sdk/credential-provider-process@3.972.25': + resolution: {integrity: sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.12': - resolution: {integrity: sha512-D5iC5546hJyhobJN0szOT4KVeJQ8z/meZq2B3lEDZFcvHONKw+tzq36DAJUy3qLTueeB2geSxiHXngQlA11eoA==} + '@aws-sdk/credential-provider-sso@3.972.29': + resolution: {integrity: sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.12': - resolution: {integrity: sha512-yluBahBVsduoA/zgV0NAXtwwXvQ6tNn95dNA3Hg+vISdiPWA46QY0d9PLO2KpNbjtm+1oGcWxemS4fYTwJ0W1w==} + '@aws-sdk/credential-provider-web-identity@3.972.29': + resolution: {integrity: sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-bucket-endpoint@3.972.5': - resolution: {integrity: sha512-4+PMX1vuPoALVhuyW7M2GkV9XrkUeuqhuXPs1IkGo2/5dFM8TxM7gnB/evSNVF/o6NXwnO4Sc+6UtGCDhI6RLg==} + '@aws-sdk/middleware-bucket-endpoint@3.972.9': + resolution: {integrity: sha512-COToYKgquDyligbcAep7ygs48RK+mwe/IYprq4+TSrVFzNOYmzWvHf6werpnKV5VYpRiwdn+Wa5ZXkPqLVwcTg==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-expect-continue@3.972.5': - resolution: {integrity: sha512-8dM11mmRZ8ZrDdkBL5q7Rslhua/nASrUhis2BJuwz2hJ+QsyyuOtr2vvc83fM91YXq18oe26bZI9tboroSo4NA==} + '@aws-sdk/middleware-expect-continue@3.972.9': + resolution: {integrity: sha512-V/FNCjFxnh4VGu+HdSiW4Yg5GELihA1MIDSAdsEPvuayXBVmr0Jaa6jdLAZLH38KYXl/vVjri9DQJWnTAujHEA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.973.0': - resolution: {integrity: sha512-RAYonYq4Tk93fB+QlLlCEaB1nHSM4lTWq4KBJ7s5bh6y30uGaVTmFELSeWlfLVJipyJ/T1FBWmrYETMcNsESoQ==} + '@aws-sdk/middleware-flexible-checksums@3.974.7': + resolution: {integrity: sha512-uU4/ch2CLHB8Phu1oTKnnQ4e8Ujqi49zEnQYBhWYT53zfFvtJCdGsaOoypBr8Fm/pmCBssRmGoIQ4sixgdLP9w==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-host-header@3.972.5': - resolution: {integrity: sha512-dVA0m1cEQ2iA6yB19aHvWNeUVTuvTt3AXzT0aiIu2uxk0S7AcmwDCDaRgYa/v+eFHcJVxEnpYTozqA7X62xinw==} + '@aws-sdk/middleware-host-header@3.972.9': + resolution: {integrity: sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-location-constraint@3.972.5': - resolution: {integrity: sha512-BC8MQUaG78oEGOjDdyGBLQCbio/KNeeMcbN8GZumW6yowe5MHyt//FJr8sipA1/hLOZ++lfpGk9bdaSo7LUpOw==} + '@aws-sdk/middleware-location-constraint@3.972.9': + resolution: {integrity: sha512-TyfOi2XNdOZpNKeTJwRUsVAGa+14nkyMb2VVGG+eDgcWG/ed6+NUo72N3hT6QJioxym80NSinErD+LBRF0Ir1w==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-logger@3.972.5': - resolution: {integrity: sha512-03RqplLZjUTkYi0dDPR/bbOLnDLFNdaVvNENgA3XK7Ph1MhEBhUYlgoGfOyRAKApDZ+WG4ykOoA8jI8J04jmFA==} + '@aws-sdk/middleware-logger@3.972.9': + resolution: {integrity: sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-recursion-detection@3.972.5': - resolution: {integrity: sha512-2QSuuVkpHTe84+mDdnFjHX8rAP3g0yYwLVAhS3lQN1rW5Z/zNsf8/pYQrLjLO4n4sPCsUAkTa0Vrod0lk+o1Tg==} + '@aws-sdk/middleware-recursion-detection@3.972.10': + resolution: {integrity: sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.14': - resolution: {integrity: sha512-qnNWgL2WLZbWQmrr+yB23ivo/L7POJxxFlQxhfDGM/NQ4OfG7YORtqwLps0mOMI8pH22kVeoNu+PB8cgRXLoqQ==} + '@aws-sdk/middleware-sdk-s3@3.972.28': + resolution: {integrity: sha512-qJHcJQH9UNPUrnPlRtCozKjtqAaypQ5IgQxTNoPsVYIQeuwNIA8Rwt3NvGij1vCDYDfCmZaPLpnJEHlZXeFqmg==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-ssec@3.972.5': - resolution: {integrity: sha512-AfQgwVjK071d1F75jX49CE5KJTlAWwMKqHJoGzf8nUD04iSHw+93rzKSGAFHu3v06k32algI6pF+ctqV/Fjc1A==} + '@aws-sdk/middleware-ssec@3.972.9': + resolution: {integrity: sha512-wSA2BR7L0CyBNDJeSrleIIzC+DzL93YNTdfU0KPGLiocK6YsRv1nPAzPF+BFSdcs0Qa5ku5Kcf4KvQcWwKGenQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.14': - resolution: {integrity: sha512-PzDz+yRAQuIzd+4ZY3s6/TYRzlNKAn4Gae3E5uLV7NnYHqrZHFoAfKE4beXcu3C51pA2/FQ3X2qOGSYqUoN1WQ==} + '@aws-sdk/middleware-user-agent@3.972.29': + resolution: {integrity: sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.996.2': - resolution: {integrity: sha512-W+u6EM8WRxOIhAhR2mXMHSaUygqItpTehkgxLwJngXqr9RlAR4t6CtECH7o7QK0ct3oyi5Z8ViDHtPbel+D2Rg==} + '@aws-sdk/nested-clients@3.996.19': + resolution: {integrity: sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.5': - resolution: {integrity: sha512-AOitrygDwfTNCLCW7L+GScDy1p49FZ6WutTUFWROouoPetfVNmpL4q8TWD3MhfY/ynhoGhleUQENrBH374EU8w==} + '@aws-sdk/region-config-resolver@3.972.11': + resolution: {integrity: sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.2': - resolution: {integrity: sha512-fUWHKtgeTfTEML5gi3yugy7caaoe7/8YdM/H0gQXuSDYNL3hORyGST5RyLnhfVDeNgypANLpIP6wzzIq74kEwQ==} + '@aws-sdk/signature-v4-multi-region@3.996.16': + resolution: {integrity: sha512-EMdXYB4r/k5RWq86fugjRhid5JA+Z6MpS7n4sij4u5/C+STrkvuf9aFu41rJA9MjUzxCLzv8U2XL8cH2GSRYpQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.998.0': - resolution: {integrity: sha512-JFzi44tQnENZQ+1DYcHfoa/wTRKkccz0VsNMow0rvsxZtqUEkeV2pYFbir35mHTyUKju9995ay1MAGxLt1dpRA==} + '@aws-sdk/token-providers@3.1026.0': + resolution: {integrity: sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA==} engines: {node: '>=20.0.0'} - '@aws-sdk/types@3.973.3': - resolution: {integrity: sha512-tma6D8/xHZHJEUqmr6ksZjZ0onyIUqKDQLyp50ttZJmS0IwFYzxBgp5CxFvpYAnah52V3UtgrqGA6E83gtT7NQ==} + '@aws-sdk/types@3.973.7': + resolution: {integrity: sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-arn-parser@3.972.2': - resolution: {integrity: sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==} + '@aws-sdk/util-arn-parser@3.972.3': + resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.996.2': - resolution: {integrity: sha512-83E6T1CKi0/IozPzqRBKqduW0mS4UQdI3soBH6CG7UgupTADWunqEMOTuPWCs9XGjpJJ4ujj+yu7pn8svhp5yg==} + '@aws-sdk/util-endpoints@3.996.6': + resolution: {integrity: sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-locate-window@3.965.4': - resolution: {integrity: sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog==} + '@aws-sdk/util-locate-window@3.965.5': + resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-user-agent-browser@3.972.5': - resolution: {integrity: sha512-2ja1WqtuBaEAMgVoHYuWx393DF6ULqdt3OozeO7BosqouYaoU47Adtp9vEF+GImSG/Q8A+dqfwDULTTdMkHGUQ==} + '@aws-sdk/util-user-agent-browser@3.972.9': + resolution: {integrity: sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw==} - '@aws-sdk/util-user-agent-node@3.972.13': - resolution: {integrity: sha512-PHErmuu+v6iAST48zcsB2cYwDKW45gk6qCp49t1p0NGZ4EaFPr/tA5jl0X/ekDwvWbuT0LTj++fjjdVQAbuh0Q==} + '@aws-sdk/util-user-agent-node@3.973.15': + resolution: {integrity: sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1148,12 +1148,12 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.7': - resolution: {integrity: sha512-9GF86s6mHuc1TYCbuKatMDWl2PyK3KIkpRaI7ul2/gYZPfaLzKZ+ISHhxzVb9KVeakf75tUQe6CXW2gugSCXNw==} + '@aws-sdk/xml-builder@3.972.17': + resolution: {integrity: sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg==} engines: {node: '>=20.0.0'} - '@aws/lambda-invoke-store@0.2.3': - resolution: {integrity: sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==} + '@aws/lambda-invoke-store@0.2.4': + resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} engines: {node: '>=18.0.0'} '@babel/code-frame@7.29.0': @@ -1206,12 +1206,12 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.6': - resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true @@ -1337,15 +1337,15 @@ packages: resolution: {integrity: sha512-JsOVaz7jBUMeul04DZagSlS74tsIyz/f0NmsHPsr9WV+u3fRO90ilRUG1SKrreUGa7x31gIU0CB5riQeu+TXYg==} engines: {node: '>=14.0.0'} - '@contentstack/cli-config@1.20.0': - resolution: {integrity: sha512-WURtexv9+lQWNPriWvaakHS+9SmGoO3Aq/zLu5SNt2k2Mj+awJwUehYcuZIVflTVzXlUQvxtU0Bn/mCpX2jkmQ==} + '@contentstack/cli-config@1.20.1': + resolution: {integrity: sha512-V7t2Nk5BaP1RnTn9gcd3sOAG/r0dagRD1mEIUd9qgxzQuA2f7Uwap09C4sKLP7IKLtAx8tBlFfrzuOoqr7u8sg==} engines: {node: '>=14.0.0'} '@contentstack/cli-dev-dependencies@1.3.1': resolution: {integrity: sha512-RQuCGQxBdZ+aNhOMwt/VMpz/9AL2PwIFz7H9rUS6BzPOe6G4RjmzFLXi/gnyECbyLoIgyGGXTjlz8NQ0oapp7Q==} - '@contentstack/cli-utilities@1.18.0': - resolution: {integrity: sha512-JEm6ElIegkcibHUEjRF+Id9529bAXBqkf0Givs9GL5CZE7d8eiLzFCUnlb51VZynk1g5+SmjY5nSeghrmcVSPg==} + '@contentstack/cli-utilities@1.18.1': + resolution: {integrity: sha512-1ymPu5HbOXFdDJHJFiwtT1yVNpmDOgMH8qqCeP3kjS7ED1+rz7Q3cWPnJC9FlUfvFeOAyJaJPPQCiYd0lgujtw==} '@contentstack/management@1.27.6': resolution: {integrity: sha512-92h8YzKZ2EDzMogf0fmBHapCjVpzHkDBIj0Eb/MhPFIhlybDlAZhcM/di6zwgicEJj5UjTJ+ETXXQMEJZouDew==} @@ -1357,6 +1357,9 @@ packages: '@contentstack/utils@1.7.1': resolution: {integrity: sha512-b/0t1malpJeFCNd9+1uN3BuO8mRn2b5+aNtrYEZ6YlSNjYNRu9IjqSxZ5Clhs5267950UV1ayhgFE8z3qre2eQ==} + '@contentstack/utils@1.9.1': + resolution: {integrity: sha512-THZM0rNuq0uOSKkKnvzp8lsPDvvdKIvJIcMa9JBv4foL9rC8RWkWffa2yMyb+9m/5HZrdAmpEWdubkGwARa8WQ==} + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1364,171 +1367,171 @@ packages: '@dabh/diagnostics@2.0.8': resolution: {integrity: sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==} - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} '@es-joy/jsdoccomment@0.50.2': resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} engines: {node: '>=18'} - '@esbuild/aix-ppc64@0.27.3': - resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.27.3': - resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.27.3': - resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.27.3': - resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.27.3': - resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.27.3': - resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.27.3': - resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.3': - resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.27.3': - resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.27.3': - resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.27.3': - resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.27.3': - resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.27.3': - resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.27.3': - resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.27.3': - resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.27.3': - resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.27.3': - resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.27.3': - resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.3': - resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.27.3': - resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.3': - resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.3': - resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.27.3': - resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.27.3': - resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.27.3': - resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.27.3': - resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1552,8 +1555,8 @@ packages: eslint: optional: true - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/config-helpers@0.4.2': @@ -1584,16 +1587,16 @@ packages: resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/eslintrc@3.3.4': - resolution: {integrity: sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==} + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/js@8.57.1': resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@9.39.3': - resolution: {integrity: sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==} + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/json@0.13.2': @@ -1813,8 +1816,8 @@ packages: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + '@istanbuljs/schema@0.1.6': + resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} engines: {node: '>=8'} '@jest/console@29.7.0': @@ -1906,8 +1909,8 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@jsdoc/salty@0.2.10': - resolution: {integrity: sha512-VFHSsQAQp8y1NJvAJBpLs9I2shHE6hz9TwukocDObuUgGVAq62yZGbTgJg04Z3Fj0XSMWe0sJqGg5dhKGTV92A==} + '@jsdoc/salty@0.2.12': + resolution: {integrity: sha512-TuB0x50EoAvEX/UEWITd8Mkn3WhiTjSvbTMCLj0BhsQEl5iUzjXdA0bETEVpTk+5TGTLR6QktI9H4hLviVeaAQ==} engines: {node: '>=v12.0.0'} '@napi-rs/wasm-runtime@0.2.12': @@ -1929,32 +1932,32 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} - '@oclif/core@4.10.3': - resolution: {integrity: sha512-0mD8vcrrX5uRsxzvI8tbWmSVGngvZA/Qo6O0ZGvLPAWEauSf5GFniwgirhY0SkszuHwu0S1J1ivj/jHmqtIDuA==} + '@oclif/core@4.10.5': + resolution: {integrity: sha512-qcdCF7NrdWPfme6Kr34wwljRCXbCVpL1WVxiNy0Ep6vbWKjxAjFQwuhqkoyL0yjI+KdwtLcOCGn5z2yzdijc8w==} engines: {node: '>=18.0.0'} - '@oclif/core@4.8.1': - resolution: {integrity: sha512-07mq0vKCWNsB85ZHeBMlTAiO0KLFqHyAeRK3bD2K8CI1tX3tiwkWw1lZQZkiw8MUBrhxdROhMkYMY4Q0l7JHqA==} + '@oclif/core@4.9.0': + resolution: {integrity: sha512-k/ntRgDcUprTT+aaNoF+whk3cY3f9fRD2lkF6ul7JeCUg2MaMXVXZXfbRhJCfsiX51X8/5Pqo0LGdO9SLYXNHg==} engines: {node: '>=18.0.0'} - '@oclif/plugin-help@6.2.37': - resolution: {integrity: sha512-5N/X/FzlJaYfpaHwDC0YHzOzKDWa41s9t+4FpCDu4f9OMReds4JeNBaaWk9rlIzdKjh2M6AC5Q18ORfECRkHGA==} + '@oclif/plugin-help@6.2.44': + resolution: {integrity: sha512-x03Se2LtlOOlGfTuuubt5C4Z8NHeR4zKXtVnfycuLU+2VOMu2WpsGy9nbs3nYuInuvsIY1BizjVaTjUz060Sig==} engines: {node: '>=18.0.0'} - '@oclif/plugin-not-found@3.2.74': - resolution: {integrity: sha512-6RD/EuIUGxAYR45nMQg+nw+PqwCXUxkR6Eyn+1fvbVjtb9d+60OPwB77LCRUI4zKNI+n0LOFaMniEdSpb+A7kQ==} + '@oclif/plugin-not-found@3.2.80': + resolution: {integrity: sha512-yTLjWvR1r/Rd/cO2LxHdMCDoL5sQhBYRUcOMCmxZtWVWhx4rAZ8KVUPDVsb+SvjJDV5ADTDBgt1H52fFx7YWqg==} engines: {node: '>=18.0.0'} - '@oclif/plugin-plugins@5.4.56': - resolution: {integrity: sha512-mZjRudlmVSr6Stz0CVFuaIZOjwZ5DqjWepQCR/yK9nbs8YunGautpuxBx/CcqaEH29xiQfsuNOIUWa1w/+3VSA==} + '@oclif/plugin-plugins@5.4.60': + resolution: {integrity: sha512-aTunE6bxVNDGnxwK2RkTo8m5ghFEcD2M35gM/uTC35LgQ1k4PLFYZ3yWfjhrK0LmryrL921+Cr+jwH4nzmlAWg==} engines: {node: '>=18.0.0'} - '@oclif/plugin-warn-if-update-available@3.1.55': - resolution: {integrity: sha512-VIEBoaoMOCjl3y+w/kdfZMODi0mVMnDuM0vkBf3nqeidhRXVXq87hBqYDdRwN1XoD+eDfE8tBbOP7qtSOONztQ==} + '@oclif/plugin-warn-if-update-available@3.1.60': + resolution: {integrity: sha512-cRKBZm14IuA6G8W84dfd3iXj3BTAoxQ5o3pUE8DKEQ4n/tVha20t5nkVeD+ISC68e0Fuw5koTMvRwXb1lJSnzg==} engines: {node: '>=18.0.0'} - '@oclif/test@4.1.16': - resolution: {integrity: sha512-LPrF++WGGBE0pe3GUkzEteI5WrwTT7usGpIMSxkyJhYnFXKkwASyTcCmOhNH4QC65kqsLt1oBA88BMkCJqPtxg==} + '@oclif/test@4.1.18': + resolution: {integrity: sha512-SIy/8x8OHKh5Z32aS8jpzTDc+FC9531mMyypoH5HiZ0vXNjKJ9+SpbW4nYK2c/X44WcPdmjIImStZ/Wgc2zZnQ==} engines: {node: '>=18.0.0'} peerDependencies: '@oclif/core': '>= 3.0.0' @@ -2023,8 +2026,11 @@ packages: '@sinonjs/fake-timers@13.0.5': resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} - '@sinonjs/fake-timers@15.1.0': - resolution: {integrity: sha512-cqfapCxwTGsrR80FEgOoPsTonoefMBY7dnUEbQ+GRcved0jvkJLzvX6F4WtN+HBqbPX/SiFsIRUp+IrCW/2I2w==} + '@sinonjs/fake-timers@15.3.2': + resolution: {integrity: sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==} + + '@sinonjs/samsam@10.0.2': + resolution: {integrity: sha512-8lVwD1Df1BmzoaOLhMcGGcz/Jyr5QY2KSB75/YK1QgKzoabTeLdIVyhXNZK9ojfSKSdirbXqdbsXXqP9/Ve8+A==} '@sinonjs/samsam@8.0.3': resolution: {integrity: sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==} @@ -2035,220 +2041,216 @@ packages: Deprecated: no longer maintained and no longer used by Sinon packages. See https://github.com/sinonjs/nise/issues/243 for replacement details. - '@smithy/abort-controller@4.2.10': - resolution: {integrity: sha512-qocxM/X4XGATqQtUkbE9SPUB6wekBi+FyJOMbPj0AhvyvFGYEmOlz6VB22iMePCQsFmMIvFSeViDvA7mZJG47g==} - engines: {node: '>=18.0.0'} - - '@smithy/chunked-blob-reader-native@4.2.2': - resolution: {integrity: sha512-QzzYIlf4yg0w5TQaC9VId3B3ugSk1MI/wb7tgcHtd7CBV9gNRKZrhc2EPSxSZuDy10zUZ0lomNMgkc6/VVe8xg==} + '@smithy/chunked-blob-reader-native@4.2.3': + resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader@5.2.1': - resolution: {integrity: sha512-y5d4xRiD6TzeP5BWlb+Ig/VFqF+t9oANNhGeMqyzU7obw7FYgTgVi50i5JqBTeKp+TABeDIeeXFZdz65RipNtA==} + '@smithy/chunked-blob-reader@5.2.2': + resolution: {integrity: sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.9': - resolution: {integrity: sha512-ejQvXqlcU30h7liR9fXtj7PIAau1t/sFbJpgWPfiYDs7zd16jpH0IsSXKcba2jF6ChTXvIjACs27kNMc5xxE2Q==} + '@smithy/config-resolver@4.4.15': + resolution: {integrity: sha512-BJdMBY5YO9iHh+lPLYdHv6LbX+J8IcPCYMl1IJdBt2KDWNHwONHrPVHk3ttYBqJd9wxv84wlbN0f7GlQzcQtNQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.6': - resolution: {integrity: sha512-4xE+0L2NrsFKpEVFlFELkIHQddBvMbQ41LRIP74dGCXnY1zQ9DgksrBcRBDJT+iOzGy4VEJIeU3hkUK5mn06kg==} + '@smithy/core@3.23.14': + resolution: {integrity: sha512-vJ0IhpZxZAkFYOegMKSrxw7ujhhT2pass/1UEcZ4kfl5srTAqtPU5I7MdYQoreVas3204ykCiNhY1o7Xlz6Yyg==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.10': - resolution: {integrity: sha512-3bsMLJJLTZGZqVGGeBVFfLzuRulVsGTj12BzRKODTHqUABpIr0jMN1vN3+u6r2OfyhAQ2pXaMZWX/swBK5I6PQ==} + '@smithy/credential-provider-imds@4.2.13': + resolution: {integrity: sha512-wboCPijzf6RJKLOvnjDAiBxGSmSnGXj35o5ZAWKDaHa/cvQ5U3ZJ13D4tMCE8JG4dxVAZFy/P0x/V9CwwdfULQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.2.10': - resolution: {integrity: sha512-A4ynrsFFfSXUHicfTcRehytppFBcY3HQxEGYiyGktPIOye3Ot7fxpiy4VR42WmtGI4Wfo6OXt/c1Ky1nUFxYYQ==} + '@smithy/eventstream-codec@4.2.13': + resolution: {integrity: sha512-vYahwBAtRaAcFbOmE9aLr12z7RiHYDSLcnogSdxfm7kKfsNa3wH+NU5r7vTeB5rKvLsWyPjVX8iH94brP7umiQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.2.10': - resolution: {integrity: sha512-0xupsu9yj9oDVuQ50YCTS9nuSYhGlrwqdaKQel9y2Fz7LU9fNErVlw9N0o4pm4qqvWEGbSTI4HKc6XJfB30MVw==} + '@smithy/eventstream-serde-browser@4.2.13': + resolution: {integrity: sha512-wwybfcOX0tLqCcBP378TIU9IqrDuZq/tDV48LlZNydMpCnqnYr+hWBAYbRE+rFFf/p7IkDJySM3bgiMKP2ihPg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.3.10': - resolution: {integrity: sha512-8kn6sinrduk0yaYHMJDsNuiFpXwQwibR7n/4CDUqn4UgaG+SeBHu5jHGFdU9BLFAM7Q4/gvr9RYxBHz9/jKrhA==} + '@smithy/eventstream-serde-config-resolver@4.3.13': + resolution: {integrity: sha512-ied1lO559PtAsMJzg2TKRlctLnEi1PfkNeMMpdwXDImk1zV9uvS/Oxoy/vcy9uv1GKZAjDAB5xT6ziE9fzm5wA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.2.10': - resolution: {integrity: sha512-uUrxPGgIffnYfvIOUmBM5i+USdEBRTdh7mLPttjphgtooxQ8CtdO1p6K5+Q4BBAZvKlvtJ9jWyrWpBJYzBKsyQ==} + '@smithy/eventstream-serde-node@4.2.13': + resolution: {integrity: sha512-hFyK+ORJrxAN3RYoaD6+gsGDQjeix8HOEkosoajvXYZ4VeqonM3G4jd9IIRm/sWGXUKmudkY9KdYjzosUqdM8A==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.2.10': - resolution: {integrity: sha512-aArqzOEvcs2dK+xQVCgLbpJQGfZihw8SD4ymhkwNTtwKbnrzdhJsFDKuMQnam2kF69WzgJYOU5eJlCx+CA32bw==} + '@smithy/eventstream-serde-universal@4.2.13': + resolution: {integrity: sha512-kRrq4EKLGeOxhC2CBEhRNcu1KSzNJzYY7RK3S7CxMPgB5dRrv55WqQOtRwQxQLC04xqORFLUgnDlc6xrNUULaA==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.11': - resolution: {integrity: sha512-wbTRjOxdFuyEg0CpumjZO0hkUl+fetJFqxNROepuLIoijQh51aMBmzFLfoQdwRjxsuuS2jizzIUTjPWgd8pd7g==} + '@smithy/fetch-http-handler@5.3.16': + resolution: {integrity: sha512-nYDRUIvNd4mFmuXraRWt6w5UsZTNqtj4hXJA/iiOD4tuseIdLP9Lq38teH/SZTcIFCa2f+27o7hYpIsWktJKEQ==} engines: {node: '>=18.0.0'} - '@smithy/hash-blob-browser@4.2.11': - resolution: {integrity: sha512-DrcAx3PM6AEbWZxsKl6CWAGnVwiz28Wp1ZhNu+Hi4uI/6C1PIZBIaPM2VoqBDAsOWbM6ZVzOEQMxFLLdmb4eBQ==} + '@smithy/hash-blob-browser@4.2.14': + resolution: {integrity: sha512-rtQ5es8r/5v4rav7q5QTsfx9CtCyzrz/g7ZZZBH2xtMmd6G/KQrLOWfSHTvFOUPlVy59RQvxeBYJaLRoybMEyA==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.10': - resolution: {integrity: sha512-1VzIOI5CcsvMDvP3iv1vG/RfLJVVVc67dCRyLSB2Hn9SWCZrDO3zvcIzj3BfEtqRW5kcMg5KAeVf1K3dR6nD3w==} + '@smithy/hash-node@4.2.13': + resolution: {integrity: sha512-4/oy9h0jjmY80a2gOIo75iLl8TOPhmtx4E2Hz+PfMjvx/vLtGY4TMU/35WRyH2JHPfT5CVB38u4JRow7gnmzJA==} engines: {node: '>=18.0.0'} - '@smithy/hash-stream-node@4.2.10': - resolution: {integrity: sha512-w78xsYrOlwXKwN5tv1GnKIRbHb1HygSpeZMP6xDxCPGf1U/xDHjCpJu64c5T35UKyEPwa0bPeIcvU69VY3khUA==} + '@smithy/hash-stream-node@4.2.13': + resolution: {integrity: sha512-WdQ7HwUjINXETeh6dqUeob1UHIYx8kAn9PSp1HhM2WWegiZBYVy2WXIs1lB07SZLan/udys9SBnQGt9MQbDpdg==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.10': - resolution: {integrity: sha512-vy9KPNSFUU0ajFYk0sDZIYiUlAWGEAhRfehIr5ZkdFrRFTAuXEPUd41USuqHU6vvLX4r6Q9X7MKBco5+Il0Org==} + '@smithy/invalid-dependency@4.2.13': + resolution: {integrity: sha512-jvC0RB/8BLj2SMIkY0Npl425IdnxZJxInpZJbu563zIRnVjpDMXevU3VMCRSabaLB0kf/eFIOusdGstrLJ8IDg==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/is-array-buffer@4.2.1': - resolution: {integrity: sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==} + '@smithy/is-array-buffer@4.2.2': + resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.2.10': - resolution: {integrity: sha512-Op+Dh6dPLWTjWITChFayDllIaCXRofOed8ecpggTC5fkh8yXes0vAEX7gRUfjGK+TlyxoCAA05gHbZW/zB9JwQ==} + '@smithy/md5-js@4.2.13': + resolution: {integrity: sha512-cNm7I9NXolFxtS20ojROddOEpSAeI1Obq6pd1Kj5HtHws3s9Fkk8DdHDfQSs5KuxCewZuVK6UqrJnfJmiMzDuQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.10': - resolution: {integrity: sha512-TQZ9kX5c6XbjhaEBpvhSvMEZ0klBs1CFtOdPFwATZSbC9UeQfKHPLPN9Y+I6wZGMOavlYTOlHEPDrt42PMSH9w==} + '@smithy/middleware-content-length@4.2.13': + resolution: {integrity: sha512-IPMLm/LE4AZwu6qiE8Rr8vJsWhs9AtOdySRXrOM7xnvclp77Tyh7hMs/FRrMf26kgIe67vFJXXOSmVxS7oKeig==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.20': - resolution: {integrity: sha512-9W6Np4ceBP3XCYAGLoMCmn8t2RRVzuD1ndWPLBbv7H9CrwM9Bprf6Up6BM9ZA/3alodg0b7Kf6ftBK9R1N04vw==} + '@smithy/middleware-endpoint@4.4.29': + resolution: {integrity: sha512-R9Q/58U+qBiSARGWbAbFLczECg/RmysRksX6Q8BaQEpt75I7LI6WGDZnjuC9GXSGKljEbA7N118LhGaMbfrTXw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.37': - resolution: {integrity: sha512-/1psZZllBBSQ7+qo5+hhLz7AEPGLx3Z0+e3ramMBEuPK2PfvLK4SrncDB9VegX5mBn+oP/UTDrM6IHrFjvX1ZA==} + '@smithy/middleware-retry@4.5.1': + resolution: {integrity: sha512-/zY+Gp7Qj2D2hVm3irkCyONER7E9MiX3cUUm/k2ZmhkzZkrPgwVS4aJ5NriZUEN/M0D1hhjrgjUmX04HhRwdWA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.11': - resolution: {integrity: sha512-STQdONGPwbbC7cusL60s7vOa6He6A9w2jWhoapL0mgVjmR19pr26slV+yoSP76SIssMTX/95e5nOZ6UQv6jolg==} + '@smithy/middleware-serde@4.2.17': + resolution: {integrity: sha512-0T2mcaM6v9W1xku86Dk0bEW7aEseG6KenFkPK98XNw0ZhOqOiD1MrMsdnQw9QsL3/Oa85T53iSMlm0SZdSuIEQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.10': - resolution: {integrity: sha512-pmts/WovNcE/tlyHa8z/groPeOtqtEpp61q3W0nW1nDJuMq/x+hWa/OVQBtgU0tBqupeXq0VBOLA4UZwE8I0YA==} + '@smithy/middleware-stack@4.2.13': + resolution: {integrity: sha512-g72jN/sGDLyTanrCLH9fhg3oysO3f7tQa6eWWsMyn2BiYNCgjF24n4/I9wff/5XidFvjj9ilipAoQrurTUrLvw==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.10': - resolution: {integrity: sha512-UALRbJtVX34AdP2VECKVlnNgidLHA2A7YgcJzwSBg1hzmnO/bZBHl/LDQQyYifzUwp1UOODnl9JJ3KNawpUJ9w==} + '@smithy/node-config-provider@4.3.13': + resolution: {integrity: sha512-iGxQ04DsKXLckbgnX4ipElrOTk+IHgTyu0q0WssZfYhDm9CQWHmu6cOeI5wmWRxpXbBDhIIfXMWz5tPEtcVqbw==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.4.12': - resolution: {integrity: sha512-zo1+WKJkR9x7ZtMeMDAAsq2PufwiLDmkhcjpWPRRkmeIuOm6nq1qjFICSZbnjBvD09ei8KMo26BWxsu2BUU+5w==} + '@smithy/node-http-handler@4.5.2': + resolution: {integrity: sha512-/oD7u8M0oj2ZTFw7GkuuHWpIxtWdLlnyNkbrWcyVYhd5RJNDuczdkb0wfnQICyNFrVPlr8YHOhamjNy3zidhmA==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.2.10': - resolution: {integrity: sha512-5jm60P0CU7tom0eNrZ7YrkgBaoLFXzmqB0wVS+4uK8PPGmosSrLNf6rRd50UBvukztawZ7zyA8TxlrKpF5z9jw==} + '@smithy/property-provider@4.2.13': + resolution: {integrity: sha512-bGzUCthxRmezuxkbu9wD33wWg9KX3hJpCXpQ93vVkPrHn9ZW6KNNdY5xAUWNuRCwQ+VyboFuWirG1lZhhkcyRQ==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.10': - resolution: {integrity: sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==} + '@smithy/protocol-http@5.3.13': + resolution: {integrity: sha512-+HsmuJUF4u8POo6s8/a2Yb/AQ5t/YgLovCuHF9oxbocqv+SZ6gd8lC2duBFiCA/vFHoHQhoq7QjqJqZC6xOxxg==} engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.2.10': - resolution: {integrity: sha512-HeN7kEvuzO2DmAzLukE9UryiUvejD3tMp9a1D1NJETerIfKobBUCLfviP6QEk500166eD2IATaXM59qgUI+YDA==} + '@smithy/querystring-builder@4.2.13': + resolution: {integrity: sha512-tG4aOYFCZdPMjbgfhnIQ322H//ojujldp1SrHPHpBSb3NqgUp3dwiUGRJzie87hS1DYwWGqDuPaowoDF+rYCbQ==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.10': - resolution: {integrity: sha512-4Mh18J26+ao1oX5wXJfWlTT+Q1OpDR8ssiC9PDOuEgVBGloqg18Fw7h5Ct8DyT9NBYwJgtJ2nLjKKFU6RP1G1Q==} + '@smithy/querystring-parser@4.2.13': + resolution: {integrity: sha512-hqW3Q4P+CDzUyQ87GrboGMeD7XYNMOF+CuTwu936UQRB/zeYn3jys8C3w+wMkDfY7CyyyVwZQ5cNFoG0x1pYmA==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.2.10': - resolution: {integrity: sha512-0R/+/Il5y8nB/By90o8hy/bWVYptbIfvoTYad0igYQO5RefhNCDmNzqxaMx7K1t/QWo0d6UynqpqN5cCQt1MCg==} + '@smithy/service-error-classification@4.2.13': + resolution: {integrity: sha512-a0s8XZMfOC/qpqq7RCPvJlk93rWFrElH6O++8WJKz0FqnA4Y7fkNi/0mnGgSH1C4x6MFsuBA8VKu4zxFrMe5Vw==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.4.5': - resolution: {integrity: sha512-pHgASxl50rrtOztgQCPmOXFjRW+mCd7ALr/3uXNzRrRoGV5G2+78GOsQ3HlQuBVHCh9o6xqMNvlIKZjWn4Euug==} + '@smithy/shared-ini-file-loader@4.4.8': + resolution: {integrity: sha512-VZCZx2bZasxdqxVgEAhREvDSlkatTPnkdWy1+Kiy8w7kYPBosW0V5IeDwzDUMvWBt56zpK658rx1cOBFOYaPaw==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.10': - resolution: {integrity: sha512-Wab3wW8468WqTKIxI+aZe3JYO52/RYT/8sDOdzkUhjnLakLe9qoQqIcfih/qxcF4qWEFoWBszY0mj5uxffaVXA==} + '@smithy/signature-v4@5.3.13': + resolution: {integrity: sha512-YpYSyM0vMDwKbHD/JA7bVOF6kToVRpa+FM5ateEVRpsTNu564g1muBlkTubXhSKKYXInhpADF46FPyrZcTLpXg==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.12.0': - resolution: {integrity: sha512-R8bQ9K3lCcXyZmBnQqUZJF4ChZmtWT5NLi6x5kgWx5D+/j0KorXcA0YcFg/X5TOgnTCy1tbKc6z2g2y4amFupQ==} + '@smithy/smithy-client@4.12.9': + resolution: {integrity: sha512-ovaLEcTU5olSeHcRXcxV6viaKtpkHZumn6Ps0yn7dRf2rRSfy794vpjOtrWDO0d1auDSvAqxO+lyhERSXQ03EQ==} engines: {node: '>=18.0.0'} - '@smithy/types@4.13.0': - resolution: {integrity: sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==} + '@smithy/types@4.14.0': + resolution: {integrity: sha512-OWgntFLW88kx2qvf/c/67Vno1yuXm/f9M7QFAtVkkO29IJXGBIg0ycEaBTH0kvCtwmvZxRujrgP5a86RvsXJAQ==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.10': - resolution: {integrity: sha512-uypjF7fCDsRk26u3qHmFI/ePL7bxxB9vKkE+2WKEciHhz+4QtbzWiHRVNRJwU3cKhrYDYQE3b0MRFtqfLYdA4A==} + '@smithy/url-parser@4.2.13': + resolution: {integrity: sha512-2G03yoboIRZlZze2+PT4GZEjgwQsJjUgn6iTsvxA02bVceHR6vp4Cuk7TUnPFWKF+ffNUk3kj4COwkENS2K3vw==} engines: {node: '>=18.0.0'} - '@smithy/util-base64@4.3.1': - resolution: {integrity: sha512-BKGuawX4Doq/bI/uEmg+Zyc36rJKWuin3py89PquXBIBqmbnJwBBsmKhdHfNEp0+A4TDgLmT/3MSKZ1SxHcR6w==} + '@smithy/util-base64@4.3.2': + resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-browser@4.2.1': - resolution: {integrity: sha512-SiJeLiozrAoCrgDBUgsVbmqHmMgg/2bA15AzcbcW+zan7SuyAVHN4xTSbq0GlebAIwlcaX32xacnrG488/J/6g==} + '@smithy/util-body-length-browser@4.2.2': + resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-node@4.2.2': - resolution: {integrity: sha512-4rHqBvxtJEBvsZcFQSPQqXP2b/yy/YlB66KlcEgcH2WNoOKCKB03DSLzXmOsXjbl8dJ4OEYTn31knhdznwk7zw==} + '@smithy/util-body-length-node@4.2.3': + resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} - '@smithy/util-buffer-from@4.2.1': - resolution: {integrity: sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==} + '@smithy/util-buffer-from@4.2.2': + resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} engines: {node: '>=18.0.0'} - '@smithy/util-config-provider@4.2.1': - resolution: {integrity: sha512-462id/00U8JWFw6qBuTSWfN5TxOHvDu4WliI97qOIOnuC/g+NDAknTU8eoGXEPlLkRVgWEr03jJBLV4o2FL8+A==} + '@smithy/util-config-provider@4.2.2': + resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.36': - resolution: {integrity: sha512-R0smq7EHQXRVMxkAxtH5akJ/FvgAmNF6bUy/GwY/N20T4GrwjT633NFm0VuRpC+8Bbv8R9A0DoJ9OiZL/M3xew==} + '@smithy/util-defaults-mode-browser@4.3.45': + resolution: {integrity: sha512-ag9sWc6/nWZAuK3Wm9KlFJUnRkXLrXn33RFjIAmCTFThqLHY+7wCst10BGq56FxslsDrjhSie46c8OULS+BiIw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.39': - resolution: {integrity: sha512-otWuoDm35btJV1L8MyHrPl462B07QCdMTktKc7/yM+Psv6KbED/ziXiHnmr7yPHUjfIwE9S8Max0LO24Mo3ZVg==} + '@smithy/util-defaults-mode-node@4.2.50': + resolution: {integrity: sha512-xpjncL5XozFA3No7WypTsPU1du0fFS8flIyO+Wh2nhCy7bpEapvU7BR55Bg+wrfw+1cRA+8G8UsTjaxgzrMzXg==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.3.1': - resolution: {integrity: sha512-xyctc4klmjmieQiF9I1wssBWleRV0RhJ2DpO8+8yzi2LO1Z+4IWOZNGZGNj4+hq9kdo+nyfrRLmQTzc16Op2Vg==} + '@smithy/util-endpoints@3.4.0': + resolution: {integrity: sha512-QQHGPKkw6NPcU6TJ1rNEEa201srPtZiX4k61xL163vvs9sTqW/XKz+UEuJ00uvPqoN+5Rs4Ka1UJ7+Mp03IXJw==} engines: {node: '>=18.0.0'} - '@smithy/util-hex-encoding@4.2.1': - resolution: {integrity: sha512-c1hHtkgAWmE35/50gmdKajgGAKV3ePJ7t6UtEmpfCWJmQE9BQAQPz0URUVI89eSkcDqCtzqllxzG28IQoZPvwA==} + '@smithy/util-hex-encoding@4.2.2': + resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.2.10': - resolution: {integrity: sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==} + '@smithy/util-middleware@4.2.13': + resolution: {integrity: sha512-GTooyrlmRTqvUen4eK7/K1p6kryF7bnDfq6XsAbIsf2mo51B/utaH+XThY6dKgNCWzMAaH/+OLmqaBuLhLWRow==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.2.10': - resolution: {integrity: sha512-HrBzistfpyE5uqTwiyLsFHscgnwB0kgv8vySp7q5kZ0Eltn/tjosaSGGDj/jJ9ys7pWzIP/icE2d+7vMKXLv7A==} + '@smithy/util-retry@4.3.1': + resolution: {integrity: sha512-FwmicpgWOkP5kZUjN3y+3JIom8NLGqSAJBeoIgK0rIToI817TEBHCrd0A2qGeKQlgDeP+Jzn4i0H/NLAXGy9uQ==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.15': - resolution: {integrity: sha512-OlOKnaqnkU9X+6wEkd7mN+WB7orPbCVDauXOj22Q7VtiTkvy7ZdSsOg4QiNAZMgI4OkvNf+/VLUC3VXkxuWJZw==} + '@smithy/util-stream@4.5.22': + resolution: {integrity: sha512-3H8iq/0BfQjUs2/4fbHZ9aG9yNzcuZs24LPkcX1Q7Z+qpqaGM8+qbGmE8zo9m2nCRgamyvS98cHdcWvR6YUsew==} engines: {node: '>=18.0.0'} - '@smithy/util-uri-escape@4.2.1': - resolution: {integrity: sha512-YmiUDn2eo2IOiWYYvGQkgX5ZkBSiTQu4FlDo5jNPpAxng2t6Sjb6WutnZV9l6VR4eJul1ABmCrnWBC9hKHQa6Q==} + '@smithy/util-uri-escape@4.2.2': + resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} engines: {node: '>=18.0.0'} '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@smithy/util-utf8@4.2.1': - resolution: {integrity: sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==} + '@smithy/util-utf8@4.2.2': + resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.2.10': - resolution: {integrity: sha512-4eTWph/Lkg1wZEDAyObwme0kmhEb7J/JjibY2znJdrYRgKbKqB7YoEhhJVJ4R1g/SYih4zuwX7LpJaM8RsnTVg==} + '@smithy/util-waiter@4.2.15': + resolution: {integrity: sha512-oUt9o7n8hBv3BL56sLSneL0XeigZSuem0Hr78JaoK33D9oKieyCvVP8eTSe3j7g2mm/S1DvzxKieG7JEWNJUNg==} engines: {node: '>=18.0.0'} - '@smithy/uuid@1.1.1': - resolution: {integrity: sha512-dSfDCeihDmZlV2oyr0yWPTUfh07suS+R5OB+FZGiv/hHyK3hrFBW5rR1UYjfa57vBsrP9lciFkRPzebaV1Qujw==} + '@smithy/uuid@1.1.2': + resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} engines: {node: '>=18.0.0'} '@so-ric/colorspace@1.1.6': @@ -2260,8 +2262,8 @@ packages: peerDependencies: eslint: '>=8.40.0' - '@stylistic/eslint-plugin@5.9.0': - resolution: {integrity: sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==} + '@stylistic/eslint-plugin@5.10.0': + resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^9.0.0 || ^10.0.0 @@ -2372,11 +2374,11 @@ packages: '@types/node@14.18.63': resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} - '@types/node@20.19.34': - resolution: {integrity: sha512-by3/Z0Qp+L9cAySEsSNNwZ6WWw8ywgGLPQGgbQDhNRSitqYgkgp4pErd23ZSCavbtUA2CN4jQtoB3T8nk4j3Rg==} + '@types/node@20.19.39': + resolution: {integrity: sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==} - '@types/node@22.19.12': - resolution: {integrity: sha512-0QEp0aPJYSyf6RrTjDB7HlKgNMTY+V2C7ESTaVt6G9gQ0rPLzTGz7OF2NXTLR5vcy7HJEtIUsyWLsfX0kTqJBA==} + '@types/node@22.19.17': + resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2451,13 +2453,13 @@ packages: typescript: optional: true - '@typescript-eslint/eslint-plugin@8.56.1': - resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} + '@typescript-eslint/eslint-plugin@8.58.2': + resolution: {integrity: sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.56.1 + '@typescript-eslint/parser': ^8.58.2 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/parser@6.21.0': resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} @@ -2469,18 +2471,18 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.56.1': - resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} + '@typescript-eslint/parser@8.58.2': + resolution: {integrity: sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.56.1': - resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} + '@typescript-eslint/project-service@8.58.2': + resolution: {integrity: sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/scope-manager@5.62.0': resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} @@ -2494,15 +2496,15 @@ packages: resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.56.1': - resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} + '@typescript-eslint/scope-manager@8.58.2': + resolution: {integrity: sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.56.1': - resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} + '@typescript-eslint/tsconfig-utils@8.58.2': + resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/type-utils@5.62.0': resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} @@ -2524,12 +2526,12 @@ packages: typescript: optional: true - '@typescript-eslint/type-utils@8.56.1': - resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} + '@typescript-eslint/type-utils@8.58.2': + resolution: {integrity: sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/types@5.62.0': resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} @@ -2543,8 +2545,8 @@ packages: resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.56.1': - resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} + '@typescript-eslint/types@8.58.2': + resolution: {integrity: sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@5.62.0': @@ -2574,11 +2576,11 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.56.1': - resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} + '@typescript-eslint/typescript-estree@8.58.2': + resolution: {integrity: sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/utils@5.62.0': resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} @@ -2598,12 +2600,12 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@8.56.1': - resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} + '@typescript-eslint/utils@8.58.2': + resolution: {integrity: sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/visitor-keys@5.62.0': resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} @@ -2617,8 +2619,8 @@ packages: resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.56.1': - resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} + '@typescript-eslint/visitor-keys@8.58.2': + resolution: {integrity: sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -2862,8 +2864,8 @@ packages: resolution: {integrity: sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==} engines: {node: '>=10'} - array-back@6.2.2: - resolution: {integrity: sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==} + array-back@6.2.3: + resolution: {integrity: sha512-SGDvmg6QTYiTxCBkYVmThcoa67uLl35pyzRHdpCGBOcqFy6BtwnphoFPk7LhJshD+Yk1Kt35WGWeZPTgwR4Fhw==} engines: {node: '>=12.17'} array-buffer-byte-length@1.0.2: @@ -2931,8 +2933,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.13.5: - resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==} + axios@1.15.0: + resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -2966,8 +2968,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.0: - resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} + baseline-browser-mapping@2.10.18: + resolution: {integrity: sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==} engines: {node: '>=6.0.0'} hasBin: true @@ -3001,8 +3003,8 @@ packages: browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3049,8 +3051,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -3072,8 +3074,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001774: - resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} + caniuse-lite@1.0.30001788: + resolution: {integrity: sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==} capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -3297,8 +3299,8 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - contentstack@3.26.4: - resolution: {integrity: sha512-NUe1Yz+NwmNJHTbSMr0tJ4YrerhHSaHPgptXFGxhTQkHG1d/2JDmjGeKocpA5ffO/x9JhgJmzrki+V4BsyQN4A==} + contentstack@3.27.0: + resolution: {integrity: sha512-2ZzVk1dO4AhgaiuPjLIzeDnQky/ElI02E4+tntX7xXQXgPEDWgogghoRMT0y0dFBcZthrZe1QChwYA9aCRSGpA==} engines: {node: '>= 10.14.2'} convert-source-map@1.9.0: @@ -3307,8 +3309,8 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - core-js-compat@3.48.0: - resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3398,8 +3400,8 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - dedent@1.7.1: - resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -3480,8 +3482,8 @@ packages: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} engines: {node: '>=0.3.1'} - diff@8.0.3: - resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} dir-glob@3.0.1: @@ -3524,8 +3526,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.302: - resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} + electron-to-chromium@1.5.336: + resolution: {integrity: sha512-AbH9q9J455r/nLmdNZes0G0ZKcRX73FicwowalLs6ijwOmCJSRRrLX63lcAlzy9ux3dWK1w1+1nsBJEWN11hcQ==} elegant-spinner@1.0.1: resolution: {integrity: sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==} @@ -3544,8 +3546,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.19.0: - resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -3559,8 +3561,8 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract@1.24.1: - resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} engines: {node: '>= 0.4'} es-define-property@1.0.1: @@ -3593,8 +3595,8 @@ packages: es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - esbuild@0.27.3: - resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} hasBin: true @@ -3629,8 +3631,8 @@ packages: resolution: {integrity: sha512-NNTyyolSmKJicgxtoWZ/hoy2Rw56WIoWCFxgnBkXqDgi9qPKMwZs2Nx2b6SHLJvCiWWhZhWr5V46CFPo3PSPag==} engines: {node: '>=18.0.0'} - eslint-config-oclif@6.0.144: - resolution: {integrity: sha512-87Zn12V0wnkxPSsm9TdIyZ4v5uNceqjMilyyR8Snk/oxCtOaawy/6mU1DwzS1zv4tnspZgeLJn+Y1ZI8Mf7BQw==} + eslint-config-oclif@6.0.157: + resolution: {integrity: sha512-Kt4MBzjWY4FLJgVeMsG4oZwmWbkQuqQioKtnXp9RDb6LR472Isr9yAfuLEsNTZMXfYEv5lsTv2zyg619HkL19Q==} engines: {node: '>=18.18.0'} eslint-config-xo-space@0.35.0: @@ -3651,8 +3653,8 @@ packages: peerDependencies: eslint: '>=9.33.0' - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} eslint-import-resolver-typescript@3.10.1: resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} @@ -3818,8 +3820,8 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - eslint@9.39.3: - resolution: {integrity: sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==} + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -3913,8 +3915,11 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fast-xml-parser@5.3.6: - resolution: {integrity: sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==} + fast-xml-builder@1.1.4: + resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} + + fast-xml-parser@5.5.8: + resolution: {integrity: sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==} hasBin: true fastest-levenshtein@1.0.16: @@ -4014,14 +4019,14 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} fn.name@1.1.0: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -4051,8 +4056,8 @@ packages: fromentries@1.3.2: resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} - fs-extra@11.3.3: - resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} fs-extra@8.1.0: @@ -4129,8 +4134,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.6: - resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + get-tsconfig@4.13.7: + resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} git-hooks-list@3.2.0: resolution: {integrity: sha512-ZHG9a1gEhUMX1TvGrLdyWb9kDopCBbTnI8z4JgRMYxsijWipgjSEYoPWqBuIB0DnRnvqlQSEeVmzpeuPm7NdFQ==} @@ -4206,8 +4211,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -5000,8 +5005,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.6: - resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} + lru-cache@11.3.5: + resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -5092,8 +5097,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimatch@10.2.4: - resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} minimatch@3.1.5: @@ -5107,8 +5112,8 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.8: - resolution: {integrity: sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -5192,8 +5197,8 @@ packages: nise@5.1.9: resolution: {integrity: sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==} - nise@6.1.1: - resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} + nise@6.1.5: + resolution: {integrity: sha512-SnRDPDBjxZZoU2n0+gzzLtSvo1OZo7j6jnbXsoh3AFxEGhaFU7ZF0TmefuKERq79wxR2U+MPn7ArW+Tl+clC3A==} no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -5202,6 +5207,10 @@ packages: resolution: {integrity: sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==} engines: {node: '>= 10.13'} + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -5209,8 +5218,8 @@ packages: resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} engines: {node: '>=8'} - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -5243,8 +5252,8 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - npm@10.9.4: - resolution: {integrity: sha512-OnUG836FwboQIbqtefDNlyR0gTHzIfwRfE3DuiNewBvnMnWEpB0VEXwBlFVgqpNzIgYo/MHh3d2Hel/pszapAA==} + npm@10.9.8: + resolution: {integrity: sha512-fYwb6ODSmHkqrJQQaCxY3M2lPf/mpgC7ik0HSzzIwG5CGtabRp4bNqikatvCoT42b5INQSqudVH0R7yVmC9hVg==} engines: {node: ^18.17.0 || >=20.5.0} hasBin: true bundledDependencies: @@ -5357,6 +5366,10 @@ packages: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + object.fromentries@2.0.8: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} @@ -5369,8 +5382,8 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - oclif@4.22.81: - resolution: {integrity: sha512-MO2bupt/3wWYqt05F8ZLwMYKN58YqDfRVdJxAvCdg/wZJg6/sDXVKoMSTSzwqsnIaJGjru2LBNvk8lH+p+1uMQ==} + oclif@4.23.0: + resolution: {integrity: sha512-0Rz8YsJx6NQORMgyDeDr6i0OlJa6h4oLXBht9iRZhn/YI/by/ONKgcJIPXyTgeLK21JmhbFqJn6Y1AME0EH1Dw==} engines: {node: '>=18.0.0'} hasBin: true @@ -5500,6 +5513,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} + engines: {node: '>=14.0.0'} + path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -5526,8 +5543,8 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -5559,8 +5576,8 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - pnpm@10.30.3: - resolution: {integrity: sha512-yWHR4KLY41TsqlFmuCJRZmi39Ey1vZUSLVkN2Bki9gb1RzttI+xKW+Bef80Y6EiNR9l4u+mBhy8RRdBumnQAFw==} + pnpm@10.33.0: + resolution: {integrity: sha512-EFaLtKavtYyes2MNqQzJUWQXq+vT+rvmc58K55VyjaFJHp21pUTHatjrdXD1xLs9bGN7LLQb/c20f6gjyGSTGQ==} engines: {node: '>=18.12'} hasBin: true @@ -5612,11 +5629,12 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} @@ -5629,8 +5647,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.15.0: - resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -5784,8 +5802,13 @@ packages: resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} engines: {node: '>=10'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} engines: {node: '>= 0.4'} hasBin: true @@ -5931,8 +5954,8 @@ packages: engines: {node: '>=18'} hasBin: true - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} engines: {node: '>= 0.4'} side-channel-map@1.0.1: @@ -5961,8 +5984,8 @@ packages: sinon@19.0.5: resolution: {integrity: sha512-r15s9/s+ub/d4bxNXqIUmwp6imVSdTorIRaxoecYjqTVLZ8RuoXr/4EDGwIBo6Waxn7f2gnURX9zuhAfCwaF6Q==} - sinon@21.0.1: - resolution: {integrity: sha512-Z0NVCW45W8Mg5oC/27/+fCqIHFnW8kpkFOq0j9XJIev4Ld0mKmERaZv5DMLAb9fGCevjKwaEeIQz5+MBXfZcDw==} + sinon@21.1.2: + resolution: {integrity: sha512-FS6mN+/bx7e2ajpXkEmOcWB6xBzWiuNoAQT18/+a20SS4U7FSYl8Ms7N6VTUxN/1JAjkx7aXp+THMC8xdpp0gA==} sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -6141,8 +6164,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strnum@2.1.2: - resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + strnum@2.2.3: + resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} @@ -6172,12 +6195,12 @@ packages: resolution: {integrity: sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==} engines: {node: '>=4.0.0'} - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} engines: {node: '>=6'} - tar@7.5.11: - resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==} + tar@7.5.13: + resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} engines: {node: '>=18'} temp-path@1.0.0: @@ -6219,8 +6242,8 @@ packages: tiny-jsonc@1.0.2: resolution: {integrity: sha512-f5QDAfLq6zIVSyCZQZhhyl0QS6MvAyTxgz4X4x3+EoCktNWEYJ6PeoEA97fyb98njpBNNi88ybpD7m+BDFXaCw==} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} tmp@0.0.33: @@ -6252,8 +6275,8 @@ packages: peerDependencies: typescript: '>=4.2.0' - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -6263,8 +6286,8 @@ packages: peerDependencies: typescript: '>=4.0.0' - ts-jest@29.4.6: - resolution: {integrity: sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==} + ts-jest@29.4.9: + resolution: {integrity: sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -6275,7 +6298,7 @@ packages: esbuild: '*' jest: ^29.0.0 || ^30.0.0 jest-util: ^29.0.0 || ^30.0.0 - typescript: '>=4.3 <6' + typescript: '>=4.3 <7' peerDependenciesMeta: '@babel/core': optional: true @@ -6397,12 +6420,12 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.56.1: - resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==} + typescript-eslint@8.58.2: + resolution: {integrity: sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' typescript@4.9.5: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} @@ -6505,9 +6528,14 @@ packages: resolution: {integrity: sha512-Nb6GvBR8UWX1D+Le+xUq0+Q1kFmRBIWVrfLnQAOmcpEzA9oAxwJ9gIr36t9TWYfzvWRvuMtjHiVsJYEkXWaTAQ==} engines: {node: '>=0.10.0'} - walk-back@5.1.1: - resolution: {integrity: sha512-e/FRLDVdZQWFrAzU6Hdvpm7D7m2ina833gIKLptQykRK49mmCYHLHq7UqjPDbxbKLZkTkW1rFqbengdE3sLfdw==} + walk-back@5.1.2: + resolution: {integrity: sha512-uCgzIY1U7fyXvJm+mesY0xjf2HXu7mtTnptONwVQ11ur1JhMrUyQJn2fDje1CGFQDnTFTo1Slr1vRuvUS9PYoQ==} engines: {node: '>=12.17'} + peerDependencies: + '@75lb/nature': latest + peerDependenciesMeta: + '@75lb/nature': + optional: true walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -6675,21 +6703,21 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 + '@aws-sdk/types': 3.973.7 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 + '@aws-sdk/types': 3.973.7 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-locate-window': 3.965.4 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-locate-window': 3.965.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -6698,15 +6726,15 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-locate-window': 3.965.4 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-locate-window': 3.965.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.3 + '@aws-sdk/types': 3.973.7 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -6715,450 +6743,452 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.973.3 + '@aws-sdk/types': 3.973.7 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-cloudfront@3.998.0': + '@aws-sdk/client-cloudfront@3.1009.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/credential-provider-node': 3.972.13 - '@aws-sdk/middleware-host-header': 3.972.5 - '@aws-sdk/middleware-logger': 3.972.5 - '@aws-sdk/middleware-recursion-detection': 3.972.5 - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/region-config-resolver': 3.972.5 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@aws-sdk/util-user-agent-browser': 3.972.5 - '@aws-sdk/util-user-agent-node': 3.972.13 - '@smithy/config-resolver': 4.4.9 - '@smithy/core': 3.23.6 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/hash-node': 4.2.10 - '@smithy/invalid-dependency': 4.2.10 - '@smithy/middleware-content-length': 4.2.10 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-retry': 4.4.37 - '@smithy/middleware-serde': 4.2.11 - '@smithy/middleware-stack': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/node-http-handler': 4.4.12 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-body-length-node': 4.2.2 - '@smithy/util-defaults-mode-browser': 4.3.36 - '@smithy/util-defaults-mode-node': 4.2.39 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - '@smithy/util-waiter': 4.2.10 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/credential-provider-node': 3.972.30 + '@aws-sdk/middleware-host-header': 3.972.9 + '@aws-sdk/middleware-logger': 3.972.9 + '@aws-sdk/middleware-recursion-detection': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.29 + '@aws-sdk/region-config-resolver': 3.972.11 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-endpoints': 3.996.6 + '@aws-sdk/util-user-agent-browser': 3.972.9 + '@aws-sdk/util-user-agent-node': 3.973.15 + '@smithy/config-resolver': 4.4.15 + '@smithy/core': 3.23.14 + '@smithy/fetch-http-handler': 5.3.16 + '@smithy/hash-node': 4.2.13 + '@smithy/invalid-dependency': 4.2.13 + '@smithy/middleware-content-length': 4.2.13 + '@smithy/middleware-endpoint': 4.4.29 + '@smithy/middleware-retry': 4.5.1 + '@smithy/middleware-serde': 4.2.17 + '@smithy/middleware-stack': 4.2.13 + '@smithy/node-config-provider': 4.3.13 + '@smithy/node-http-handler': 4.5.2 + '@smithy/protocol-http': 5.3.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.45 + '@smithy/util-defaults-mode-node': 4.2.50 + '@smithy/util-endpoints': 3.4.0 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-retry': 4.3.1 + '@smithy/util-stream': 4.5.22 + '@smithy/util-utf8': 4.2.2 + '@smithy/util-waiter': 4.2.15 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-s3@3.998.0': + '@aws-sdk/client-s3@3.1014.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/credential-provider-node': 3.972.13 - '@aws-sdk/middleware-bucket-endpoint': 3.972.5 - '@aws-sdk/middleware-expect-continue': 3.972.5 - '@aws-sdk/middleware-flexible-checksums': 3.973.0 - '@aws-sdk/middleware-host-header': 3.972.5 - '@aws-sdk/middleware-location-constraint': 3.972.5 - '@aws-sdk/middleware-logger': 3.972.5 - '@aws-sdk/middleware-recursion-detection': 3.972.5 - '@aws-sdk/middleware-sdk-s3': 3.972.14 - '@aws-sdk/middleware-ssec': 3.972.5 - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/region-config-resolver': 3.972.5 - '@aws-sdk/signature-v4-multi-region': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@aws-sdk/util-user-agent-browser': 3.972.5 - '@aws-sdk/util-user-agent-node': 3.972.13 - '@smithy/config-resolver': 4.4.9 - '@smithy/core': 3.23.6 - '@smithy/eventstream-serde-browser': 4.2.10 - '@smithy/eventstream-serde-config-resolver': 4.3.10 - '@smithy/eventstream-serde-node': 4.2.10 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/hash-blob-browser': 4.2.11 - '@smithy/hash-node': 4.2.10 - '@smithy/hash-stream-node': 4.2.10 - '@smithy/invalid-dependency': 4.2.10 - '@smithy/md5-js': 4.2.10 - '@smithy/middleware-content-length': 4.2.10 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-retry': 4.4.37 - '@smithy/middleware-serde': 4.2.11 - '@smithy/middleware-stack': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/node-http-handler': 4.4.12 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-body-length-node': 4.2.2 - '@smithy/util-defaults-mode-browser': 4.3.36 - '@smithy/util-defaults-mode-node': 4.2.39 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - '@smithy/util-waiter': 4.2.10 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/credential-provider-node': 3.972.30 + '@aws-sdk/middleware-bucket-endpoint': 3.972.9 + '@aws-sdk/middleware-expect-continue': 3.972.9 + '@aws-sdk/middleware-flexible-checksums': 3.974.7 + '@aws-sdk/middleware-host-header': 3.972.9 + '@aws-sdk/middleware-location-constraint': 3.972.9 + '@aws-sdk/middleware-logger': 3.972.9 + '@aws-sdk/middleware-recursion-detection': 3.972.10 + '@aws-sdk/middleware-sdk-s3': 3.972.28 + '@aws-sdk/middleware-ssec': 3.972.9 + '@aws-sdk/middleware-user-agent': 3.972.29 + '@aws-sdk/region-config-resolver': 3.972.11 + '@aws-sdk/signature-v4-multi-region': 3.996.16 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-endpoints': 3.996.6 + '@aws-sdk/util-user-agent-browser': 3.972.9 + '@aws-sdk/util-user-agent-node': 3.973.15 + '@smithy/config-resolver': 4.4.15 + '@smithy/core': 3.23.14 + '@smithy/eventstream-serde-browser': 4.2.13 + '@smithy/eventstream-serde-config-resolver': 4.3.13 + '@smithy/eventstream-serde-node': 4.2.13 + '@smithy/fetch-http-handler': 5.3.16 + '@smithy/hash-blob-browser': 4.2.14 + '@smithy/hash-node': 4.2.13 + '@smithy/hash-stream-node': 4.2.13 + '@smithy/invalid-dependency': 4.2.13 + '@smithy/md5-js': 4.2.13 + '@smithy/middleware-content-length': 4.2.13 + '@smithy/middleware-endpoint': 4.4.29 + '@smithy/middleware-retry': 4.5.1 + '@smithy/middleware-serde': 4.2.17 + '@smithy/middleware-stack': 4.2.13 + '@smithy/node-config-provider': 4.3.13 + '@smithy/node-http-handler': 4.5.2 + '@smithy/protocol-http': 5.3.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.45 + '@smithy/util-defaults-mode-node': 4.2.50 + '@smithy/util-endpoints': 3.4.0 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-retry': 4.3.1 + '@smithy/util-stream': 4.5.22 + '@smithy/util-utf8': 4.2.2 + '@smithy/util-waiter': 4.2.15 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.973.14': - dependencies: - '@aws-sdk/types': 3.973.3 - '@aws-sdk/xml-builder': 3.972.7 - '@smithy/core': 3.23.6 - '@smithy/node-config-provider': 4.3.10 - '@smithy/property-provider': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/signature-v4': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-utf8': 4.2.1 + '@aws-sdk/core@3.973.27': + dependencies: + '@aws-sdk/types': 3.973.7 + '@aws-sdk/xml-builder': 3.972.17 + '@smithy/core': 3.23.14 + '@smithy/node-config-provider': 4.3.13 + '@smithy/property-provider': 4.2.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/signature-v4': 5.3.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/crc64-nvme@3.972.2': + '@aws-sdk/crc64-nvme@3.972.6': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.12': + '@aws-sdk/credential-provider-env@3.972.25': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/types': 3.973.7 + '@smithy/property-provider': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.14': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/node-http-handler': 4.4.12 - '@smithy/property-provider': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-stream': 4.5.15 + '@aws-sdk/credential-provider-http@3.972.27': + dependencies: + '@aws-sdk/core': 3.973.27 + '@aws-sdk/types': 3.973.7 + '@smithy/fetch-http-handler': 5.3.16 + '@smithy/node-http-handler': 4.5.2 + '@smithy/property-provider': 4.2.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/util-stream': 4.5.22 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.12': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/credential-provider-env': 3.972.12 - '@aws-sdk/credential-provider-http': 3.972.14 - '@aws-sdk/credential-provider-login': 3.972.12 - '@aws-sdk/credential-provider-process': 3.972.12 - '@aws-sdk/credential-provider-sso': 3.972.12 - '@aws-sdk/credential-provider-web-identity': 3.972.12 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/credential-provider-imds': 4.2.10 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/credential-provider-ini@3.972.29': + dependencies: + '@aws-sdk/core': 3.973.27 + '@aws-sdk/credential-provider-env': 3.972.25 + '@aws-sdk/credential-provider-http': 3.972.27 + '@aws-sdk/credential-provider-login': 3.972.29 + '@aws-sdk/credential-provider-process': 3.972.25 + '@aws-sdk/credential-provider-sso': 3.972.29 + '@aws-sdk/credential-provider-web-identity': 3.972.29 + '@aws-sdk/nested-clients': 3.996.19 + '@aws-sdk/types': 3.973.7 + '@smithy/credential-provider-imds': 4.2.13 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.12': + '@aws-sdk/credential-provider-login@3.972.29': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/nested-clients': 3.996.19 + '@aws-sdk/types': 3.973.7 + '@smithy/property-provider': 4.2.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.13': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.12 - '@aws-sdk/credential-provider-http': 3.972.14 - '@aws-sdk/credential-provider-ini': 3.972.12 - '@aws-sdk/credential-provider-process': 3.972.12 - '@aws-sdk/credential-provider-sso': 3.972.12 - '@aws-sdk/credential-provider-web-identity': 3.972.12 - '@aws-sdk/types': 3.973.3 - '@smithy/credential-provider-imds': 4.2.10 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/credential-provider-node@3.972.30': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.25 + '@aws-sdk/credential-provider-http': 3.972.27 + '@aws-sdk/credential-provider-ini': 3.972.29 + '@aws-sdk/credential-provider-process': 3.972.25 + '@aws-sdk/credential-provider-sso': 3.972.29 + '@aws-sdk/credential-provider-web-identity': 3.972.29 + '@aws-sdk/types': 3.973.7 + '@smithy/credential-provider-imds': 4.2.13 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.12': + '@aws-sdk/credential-provider-process@3.972.25': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/types': 3.973.7 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.12': + '@aws-sdk/credential-provider-sso@3.972.29': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/token-providers': 3.998.0 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/nested-clients': 3.996.19 + '@aws-sdk/token-providers': 3.1026.0 + '@aws-sdk/types': 3.973.7 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.12': + '@aws-sdk/credential-provider-web-identity@3.972.29': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/nested-clients': 3.996.19 + '@aws-sdk/types': 3.973.7 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/middleware-bucket-endpoint@3.972.5': + '@aws-sdk/middleware-bucket-endpoint@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-config-provider': 4.2.1 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-arn-parser': 3.972.3 + '@smithy/node-config-provider': 4.3.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.972.5': + '@aws-sdk/middleware-expect-continue@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.973.0': + '@aws-sdk/middleware-flexible-checksums@3.974.7': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/crc64-nvme': 3.972.2 - '@aws-sdk/types': 3.973.3 - '@smithy/is-array-buffer': 4.2.1 - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/crc64-nvme': 3.972.6 + '@aws-sdk/types': 3.973.7 + '@smithy/is-array-buffer': 4.2.2 + '@smithy/node-config-provider': 4.3.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-stream': 4.5.22 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.972.5': + '@aws-sdk/middleware-host-header@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/middleware-location-constraint@3.972.5': + '@aws-sdk/middleware-location-constraint@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.972.5': + '@aws-sdk/middleware-logger@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.972.5': + '@aws-sdk/middleware-recursion-detection@3.972.10': dependencies: - '@aws-sdk/types': 3.973.3 - '@aws/lambda-invoke-store': 0.2.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.14': - dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/core': 3.23.6 - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/signature-v4': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-config-provider': 4.2.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 + '@aws-sdk/middleware-sdk-s3@3.972.28': + dependencies: + '@aws-sdk/core': 3.973.27 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-arn-parser': 3.972.3 + '@smithy/core': 3.23.14 + '@smithy/node-config-provider': 4.3.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/signature-v4': 5.3.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-stream': 4.5.22 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-ssec@3.972.5': + '@aws-sdk/middleware-ssec@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.14': + '@aws-sdk/middleware-user-agent@3.972.29': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@smithy/core': 3.23.6 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-endpoints': 3.996.6 + '@smithy/core': 3.23.14 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-retry': 4.3.1 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.996.2': + '@aws-sdk/nested-clients@3.996.19': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.14 - '@aws-sdk/middleware-host-header': 3.972.5 - '@aws-sdk/middleware-logger': 3.972.5 - '@aws-sdk/middleware-recursion-detection': 3.972.5 - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/region-config-resolver': 3.972.5 - '@aws-sdk/types': 3.973.3 - '@aws-sdk/util-endpoints': 3.996.2 - '@aws-sdk/util-user-agent-browser': 3.972.5 - '@aws-sdk/util-user-agent-node': 3.972.13 - '@smithy/config-resolver': 4.4.9 - '@smithy/core': 3.23.6 - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/hash-node': 4.2.10 - '@smithy/invalid-dependency': 4.2.10 - '@smithy/middleware-content-length': 4.2.10 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-retry': 4.4.37 - '@smithy/middleware-serde': 4.2.11 - '@smithy/middleware-stack': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/node-http-handler': 4.4.12 - '@smithy/protocol-http': 5.3.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-body-length-node': 4.2.2 - '@smithy/util-defaults-mode-browser': 4.3.36 - '@smithy/util-defaults-mode-node': 4.2.39 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/util-utf8': 4.2.1 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/middleware-host-header': 3.972.9 + '@aws-sdk/middleware-logger': 3.972.9 + '@aws-sdk/middleware-recursion-detection': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.29 + '@aws-sdk/region-config-resolver': 3.972.11 + '@aws-sdk/types': 3.973.7 + '@aws-sdk/util-endpoints': 3.996.6 + '@aws-sdk/util-user-agent-browser': 3.972.9 + '@aws-sdk/util-user-agent-node': 3.973.15 + '@smithy/config-resolver': 4.4.15 + '@smithy/core': 3.23.14 + '@smithy/fetch-http-handler': 5.3.16 + '@smithy/hash-node': 4.2.13 + '@smithy/invalid-dependency': 4.2.13 + '@smithy/middleware-content-length': 4.2.13 + '@smithy/middleware-endpoint': 4.4.29 + '@smithy/middleware-retry': 4.5.1 + '@smithy/middleware-serde': 4.2.17 + '@smithy/middleware-stack': 4.2.13 + '@smithy/node-config-provider': 4.3.13 + '@smithy/node-http-handler': 4.5.2 + '@smithy/protocol-http': 5.3.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.45 + '@smithy/util-defaults-mode-node': 4.2.50 + '@smithy/util-endpoints': 3.4.0 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-retry': 4.3.1 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.972.5': + '@aws-sdk/region-config-resolver@3.972.11': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/config-resolver': 4.4.9 - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/config-resolver': 4.4.15 + '@smithy/node-config-provider': 4.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.2': + '@aws-sdk/signature-v4-multi-region@3.996.16': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.14 - '@aws-sdk/types': 3.973.3 - '@smithy/protocol-http': 5.3.10 - '@smithy/signature-v4': 5.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/middleware-sdk-s3': 3.972.28 + '@aws-sdk/types': 3.973.7 + '@smithy/protocol-http': 5.3.13 + '@smithy/signature-v4': 5.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.998.0': + '@aws-sdk/token-providers@3.1026.0': dependencies: - '@aws-sdk/core': 3.973.14 - '@aws-sdk/nested-clients': 3.996.2 - '@aws-sdk/types': 3.973.3 - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@aws-sdk/core': 3.973.27 + '@aws-sdk/nested-clients': 3.996.19 + '@aws-sdk/types': 3.973.7 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.973.3': + '@aws-sdk/types@3.973.7': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@aws-sdk/util-arn-parser@3.972.2': + '@aws-sdk/util-arn-parser@3.972.3': dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.996.2': + '@aws-sdk/util-endpoints@3.996.6': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-endpoints': 3.3.1 + '@aws-sdk/types': 3.973.7 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 + '@smithy/util-endpoints': 3.4.0 tslib: 2.8.1 - '@aws-sdk/util-locate-window@3.965.4': + '@aws-sdk/util-locate-window@3.965.5': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.972.5': + '@aws-sdk/util-user-agent-browser@3.972.9': dependencies: - '@aws-sdk/types': 3.973.3 - '@smithy/types': 4.13.0 + '@aws-sdk/types': 3.973.7 + '@smithy/types': 4.14.0 bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.972.13': + '@aws-sdk/util-user-agent-node@3.973.15': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.14 - '@aws-sdk/types': 3.973.3 - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 + '@aws-sdk/middleware-user-agent': 3.972.29 + '@aws-sdk/types': 3.973.7 + '@smithy/node-config-provider': 4.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.7': + '@aws-sdk/xml-builder@3.972.17': dependencies: - '@smithy/types': 4.13.0 - fast-xml-parser: 5.3.6 + '@smithy/types': 4.14.0 + fast-xml-parser: 5.5.8 tslib: 2.8.1 - '@aws/lambda-invoke-store@0.2.3': {} + '@aws/lambda-invoke-store@0.2.4': {} '@babel/code-frame@7.29.0': dependencies: @@ -7174,8 +7204,8 @@ snapshots: '@babel/generator': 7.29.1 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.29.0 + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 @@ -7190,7 +7220,7 @@ snapshots: '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -7200,7 +7230,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.0 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 + browserslist: 4.28.2 lru-cache: 5.1.1 semver: 6.3.1 @@ -7230,12 +7260,12 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.28.6': + '@babel/helpers@7.29.2': dependencies: '@babel/template': 7.28.6 '@babel/types': 7.29.0 - '@babel/parser@7.29.0': + '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -7327,7 +7357,7 @@ snapshots: '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@babel/traverse@7.29.0': @@ -7335,7 +7365,7 @@ snapshots: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/types': 7.29.0 debug: 4.4.3(supports-color@8.1.1) @@ -7353,12 +7383,12 @@ snapshots: '@colors/colors@1.6.0': {} - '@contentstack/cli-auth@1.8.0(@types/node@22.19.12)': + '@contentstack/cli-auth@1.8.0(@types/node@22.19.17)': dependencies: - '@contentstack/cli-command': 1.8.0(@types/node@22.19.12) - '@contentstack/cli-utilities': 1.18.0(@types/node@22.19.12) - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 + '@contentstack/cli-command': 1.8.0(@types/node@22.19.17) + '@contentstack/cli-utilities': 1.18.1(@types/node@22.19.17) + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 otplib: 12.0.1 transitivePeerDependencies: - '@types/node' @@ -7366,63 +7396,63 @@ snapshots: '@contentstack/cli-command@1.8.0(@types/node@14.18.63)': dependencies: - '@contentstack/cli-utilities': 1.18.0(@types/node@14.18.63) - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 - contentstack: 3.26.4 + '@contentstack/cli-utilities': 1.18.1(@types/node@14.18.63) + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 + contentstack: 3.27.0 transitivePeerDependencies: - '@types/node' - debug '@contentstack/cli-command@1.8.0(@types/node@14.18.63)(debug@4.4.3)': dependencies: - '@contentstack/cli-utilities': 1.18.0(@types/node@14.18.63)(debug@4.4.3) - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 - contentstack: 3.26.4 + '@contentstack/cli-utilities': 1.18.1(@types/node@14.18.63)(debug@4.4.3) + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 + contentstack: 3.27.0 transitivePeerDependencies: - '@types/node' - debug - '@contentstack/cli-command@1.8.0(@types/node@20.19.34)': + '@contentstack/cli-command@1.8.0(@types/node@20.19.39)': dependencies: - '@contentstack/cli-utilities': 1.18.0(@types/node@20.19.34) - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 - contentstack: 3.26.4 + '@contentstack/cli-utilities': 1.18.1(@types/node@20.19.39) + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 + contentstack: 3.27.0 transitivePeerDependencies: - '@types/node' - debug - '@contentstack/cli-command@1.8.0(@types/node@22.19.12)': + '@contentstack/cli-command@1.8.0(@types/node@22.19.17)': dependencies: - '@contentstack/cli-utilities': 1.18.0(@types/node@22.19.12) - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 - contentstack: 3.26.4 + '@contentstack/cli-utilities': 1.18.1(@types/node@22.19.17) + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 + contentstack: 3.27.0 transitivePeerDependencies: - '@types/node' - debug - '@contentstack/cli-config@1.20.0(@types/node@14.18.63)': + '@contentstack/cli-config@1.20.1(@types/node@14.18.63)': dependencies: '@contentstack/cli-command': 1.8.0(@types/node@14.18.63) - '@contentstack/cli-utilities': 1.18.0(@types/node@14.18.63) + '@contentstack/cli-utilities': 1.18.1(@types/node@14.18.63) '@contentstack/utils': 1.7.1 - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 lodash: 4.18.1 transitivePeerDependencies: - '@types/node' - debug - '@contentstack/cli-config@1.20.0(@types/node@22.19.12)': + '@contentstack/cli-config@1.20.1(@types/node@22.19.17)': dependencies: - '@contentstack/cli-command': 1.8.0(@types/node@22.19.12) - '@contentstack/cli-utilities': 1.18.0(@types/node@22.19.12) + '@contentstack/cli-command': 1.8.0(@types/node@22.19.17) + '@contentstack/cli-utilities': 1.18.1(@types/node@22.19.17) '@contentstack/utils': 1.7.1 - '@oclif/core': 4.10.3 - '@oclif/plugin-help': 6.2.37 + '@oclif/core': 4.10.5 + '@oclif/plugin-help': 6.2.44 lodash: 4.18.1 transitivePeerDependencies: - '@types/node' @@ -7430,19 +7460,19 @@ snapshots: '@contentstack/cli-dev-dependencies@1.3.1': dependencies: - '@oclif/core': 4.8.1 - '@oclif/test': 4.1.16(@oclif/core@4.8.1) + '@oclif/core': 4.10.5 + '@oclif/test': 4.1.18(@oclif/core@4.10.5) fancy-test: 2.0.42 lodash: 4.18.1 transitivePeerDependencies: - supports-color - '@contentstack/cli-utilities@1.18.0(@types/node@14.18.63)': + '@contentstack/cli-utilities@1.18.1(@types/node@14.18.63)': dependencies: '@contentstack/management': 1.27.6(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.0(debug@4.4.3) - '@oclif/core': 4.10.3 - axios: 1.13.5(debug@4.4.3) + '@oclif/core': 4.10.5 + axios: 1.15.0(debug@4.4.3) chalk: 4.1.2 cli-cursor: 3.1.0 cli-progress: 3.12.0 @@ -7472,12 +7502,12 @@ snapshots: - '@types/node' - debug - '@contentstack/cli-utilities@1.18.0(@types/node@14.18.63)(debug@4.4.3)': + '@contentstack/cli-utilities@1.18.1(@types/node@14.18.63)(debug@4.4.3)': dependencies: '@contentstack/management': 1.27.6(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.0(debug@4.4.3) - '@oclif/core': 4.10.3 - axios: 1.13.5(debug@4.4.3) + '@oclif/core': 4.10.5 + axios: 1.15.0(debug@4.4.3) chalk: 4.1.2 cli-cursor: 3.1.0 cli-progress: 3.12.0 @@ -7507,12 +7537,12 @@ snapshots: - '@types/node' - debug - '@contentstack/cli-utilities@1.18.0(@types/node@20.19.34)': + '@contentstack/cli-utilities@1.18.1(@types/node@20.19.39)': dependencies: '@contentstack/management': 1.27.6(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.0(debug@4.4.3) - '@oclif/core': 4.10.3 - axios: 1.13.5(debug@4.4.3) + '@oclif/core': 4.10.5 + axios: 1.15.0(debug@4.4.3) chalk: 4.1.2 cli-cursor: 3.1.0 cli-progress: 3.12.0 @@ -7520,7 +7550,7 @@ snapshots: conf: 10.2.0 dotenv: 16.6.1 figures: 3.2.0 - inquirer: 8.2.7(@types/node@20.19.34) + inquirer: 8.2.7(@types/node@20.19.39) inquirer-search-checkbox: 1.0.0 inquirer-search-list: 1.2.6 js-yaml: 4.1.1 @@ -7542,12 +7572,12 @@ snapshots: - '@types/node' - debug - '@contentstack/cli-utilities@1.18.0(@types/node@22.19.12)': + '@contentstack/cli-utilities@1.18.1(@types/node@22.19.17)': dependencies: '@contentstack/management': 1.27.6(debug@4.4.3) '@contentstack/marketplace-sdk': 1.5.0(debug@4.4.3) - '@oclif/core': 4.10.3 - axios: 1.13.5(debug@4.4.3) + '@oclif/core': 4.10.5 + axios: 1.15.0(debug@4.4.3) chalk: 4.1.2 cli-cursor: 3.1.0 cli-progress: 3.12.0 @@ -7555,7 +7585,7 @@ snapshots: conf: 10.2.0 dotenv: 16.6.1 figures: 3.2.0 - inquirer: 8.2.7(@types/node@22.19.12) + inquirer: 8.2.7(@types/node@22.19.17) inquirer-search-checkbox: 1.0.0 inquirer-search-list: 1.2.6 js-yaml: 4.1.1 @@ -7579,28 +7609,30 @@ snapshots: '@contentstack/management@1.27.6(debug@4.4.3)': dependencies: - '@contentstack/utils': 1.7.1 + '@contentstack/utils': 1.9.1 assert: 2.1.0 - axios: 1.13.5(debug@4.4.3) + axios: 1.15.0(debug@4.4.3) buffer: 6.0.3 form-data: 4.0.5 husky: 9.1.7 lodash: 4.18.1 otplib: 12.0.1 - qs: 6.15.0 + qs: 6.15.1 stream-browserify: 3.0.0 transitivePeerDependencies: - debug '@contentstack/marketplace-sdk@1.5.0(debug@4.4.3)': dependencies: - '@contentstack/utils': 1.7.1 - axios: 1.13.5(debug@4.4.3) + '@contentstack/utils': 1.9.1 + axios: 1.15.0(debug@4.4.3) transitivePeerDependencies: - debug '@contentstack/utils@1.7.1': {} + '@contentstack/utils@1.9.1': {} + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -7611,18 +7643,18 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@emnapi/core@1.8.1': + '@emnapi/core@1.9.2': dependencies: - '@emnapi/wasi-threads': 1.1.0 + '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.8.1': + '@emnapi/runtime@1.9.2': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.1.0': + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true @@ -7630,87 +7662,87 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/types': 8.58.2 comment-parser: 1.4.1 esquery: 1.7.0 jsdoc-type-pratt-parser: 4.1.0 - '@esbuild/aix-ppc64@0.27.3': + '@esbuild/aix-ppc64@0.27.7': optional: true - '@esbuild/android-arm64@0.27.3': + '@esbuild/android-arm64@0.27.7': optional: true - '@esbuild/android-arm@0.27.3': + '@esbuild/android-arm@0.27.7': optional: true - '@esbuild/android-x64@0.27.3': + '@esbuild/android-x64@0.27.7': optional: true - '@esbuild/darwin-arm64@0.27.3': + '@esbuild/darwin-arm64@0.27.7': optional: true - '@esbuild/darwin-x64@0.27.3': + '@esbuild/darwin-x64@0.27.7': optional: true - '@esbuild/freebsd-arm64@0.27.3': + '@esbuild/freebsd-arm64@0.27.7': optional: true - '@esbuild/freebsd-x64@0.27.3': + '@esbuild/freebsd-x64@0.27.7': optional: true - '@esbuild/linux-arm64@0.27.3': + '@esbuild/linux-arm64@0.27.7': optional: true - '@esbuild/linux-arm@0.27.3': + '@esbuild/linux-arm@0.27.7': optional: true - '@esbuild/linux-ia32@0.27.3': + '@esbuild/linux-ia32@0.27.7': optional: true - '@esbuild/linux-loong64@0.27.3': + '@esbuild/linux-loong64@0.27.7': optional: true - '@esbuild/linux-mips64el@0.27.3': + '@esbuild/linux-mips64el@0.27.7': optional: true - '@esbuild/linux-ppc64@0.27.3': + '@esbuild/linux-ppc64@0.27.7': optional: true - '@esbuild/linux-riscv64@0.27.3': + '@esbuild/linux-riscv64@0.27.7': optional: true - '@esbuild/linux-s390x@0.27.3': + '@esbuild/linux-s390x@0.27.7': optional: true - '@esbuild/linux-x64@0.27.3': + '@esbuild/linux-x64@0.27.7': optional: true - '@esbuild/netbsd-arm64@0.27.3': + '@esbuild/netbsd-arm64@0.27.7': optional: true - '@esbuild/netbsd-x64@0.27.3': + '@esbuild/netbsd-x64@0.27.7': optional: true - '@esbuild/openbsd-arm64@0.27.3': + '@esbuild/openbsd-arm64@0.27.7': optional: true - '@esbuild/openbsd-x64@0.27.3': + '@esbuild/openbsd-x64@0.27.7': optional: true - '@esbuild/openharmony-arm64@0.27.3': + '@esbuild/openharmony-arm64@0.27.7': optional: true - '@esbuild/sunos-x64@0.27.3': + '@esbuild/sunos-x64@0.27.7': optional: true - '@esbuild/win32-arm64@0.27.3': + '@esbuild/win32-arm64@0.27.7': optional: true - '@esbuild/win32-ia32@0.27.3': + '@esbuild/win32-ia32@0.27.7': optional: true - '@esbuild/win32-x64@0.27.3': + '@esbuild/win32-x64@0.27.7': optional: true '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': @@ -7718,9 +7750,9 @@ snapshots: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': dependencies: - eslint: 9.39.3 + eslint: 9.39.4 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -7731,7 +7763,7 @@ snapshots: optionalDependencies: eslint: 8.57.1 - '@eslint/config-array@0.21.1': + '@eslint/config-array@0.21.2': dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3(supports-color@8.1.1) @@ -7780,7 +7812,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/eslintrc@3.3.4': + '@eslint/eslintrc@3.3.5': dependencies: ajv: 6.14.0 debug: 4.4.3(supports-color@8.1.1) @@ -7796,7 +7828,7 @@ snapshots: '@eslint/js@8.57.1': {} - '@eslint/js@9.39.3': {} + '@eslint/js@9.39.4': {} '@eslint/json@0.13.2': dependencies: @@ -7871,25 +7903,25 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/checkbox@4.3.2(@types/node@20.19.34)': + '@inquirer/checkbox@4.3.2(@types/node@20.19.39)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/type': 3.0.10(@types/node@20.19.39) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/checkbox@4.3.2(@types/node@22.19.12)': + '@inquirer/checkbox@4.3.2(@types/node@22.19.17)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/type': 3.0.10(@types/node@22.19.17) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/confirm@3.2.0': dependencies: @@ -7903,19 +7935,19 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/confirm@5.1.21(@types/node@20.19.34)': + '@inquirer/confirm@5.1.21(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/confirm@5.1.21(@types/node@22.19.12)': + '@inquirer/confirm@5.1.21(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/core@10.3.2(@types/node@14.18.63)': dependencies: @@ -7930,38 +7962,38 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/core@10.3.2(@types/node@20.19.34)': + '@inquirer/core@10.3.2(@types/node@20.19.39)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/type': 3.0.10(@types/node@20.19.39) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/core@10.3.2(@types/node@22.19.12)': + '@inquirer/core@10.3.2(@types/node@22.19.17)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/type': 3.0.10(@types/node@22.19.17) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/core@9.2.1': dependencies: '@inquirer/figures': 1.0.15 '@inquirer/type': 2.0.0 '@types/mute-stream': 0.0.4 - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@types/wrap-ansi': 3.0.0 ansi-escapes: 4.3.2 cli-width: 4.1.0 @@ -7979,21 +8011,21 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/editor@4.2.23(@types/node@20.19.34)': + '@inquirer/editor@4.2.23(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/external-editor': 1.0.3(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/external-editor': 1.0.3(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/editor@4.2.23(@types/node@22.19.12)': + '@inquirer/editor@4.2.23(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/external-editor': 1.0.3(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/external-editor': 1.0.3(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/expand@4.0.23(@types/node@14.18.63)': dependencies: @@ -8003,21 +8035,21 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/expand@4.0.23(@types/node@20.19.34)': + '@inquirer/expand@4.0.23(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/expand@4.0.23(@types/node@22.19.12)': + '@inquirer/expand@4.0.23(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/external-editor@1.0.3(@types/node@14.18.63)': dependencies: @@ -8026,19 +8058,19 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/external-editor@1.0.3(@types/node@20.19.34)': + '@inquirer/external-editor@1.0.3(@types/node@20.19.39)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/external-editor@1.0.3(@types/node@22.19.12)': + '@inquirer/external-editor@1.0.3(@types/node@22.19.17)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/figures@1.0.15': {} @@ -8054,19 +8086,19 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/input@4.3.1(@types/node@20.19.34)': + '@inquirer/input@4.3.1(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/input@4.3.1(@types/node@22.19.12)': + '@inquirer/input@4.3.1(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/number@3.0.23(@types/node@14.18.63)': dependencies: @@ -8075,19 +8107,19 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/number@3.0.23(@types/node@20.19.34)': + '@inquirer/number@3.0.23(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/number@3.0.23(@types/node@22.19.12)': + '@inquirer/number@3.0.23(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/password@4.0.23(@types/node@14.18.63)': dependencies: @@ -8097,21 +8129,21 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/password@4.0.23(@types/node@20.19.34)': + '@inquirer/password@4.0.23(@types/node@20.19.39)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/password@4.0.23(@types/node@22.19.12)': + '@inquirer/password@4.0.23(@types/node@22.19.17)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/prompts@7.10.1(@types/node@14.18.63)': dependencies: @@ -8128,35 +8160,35 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/prompts@7.10.1(@types/node@20.19.34)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@20.19.34) - '@inquirer/confirm': 5.1.21(@types/node@20.19.34) - '@inquirer/editor': 4.2.23(@types/node@20.19.34) - '@inquirer/expand': 4.0.23(@types/node@20.19.34) - '@inquirer/input': 4.3.1(@types/node@20.19.34) - '@inquirer/number': 3.0.23(@types/node@20.19.34) - '@inquirer/password': 4.0.23(@types/node@20.19.34) - '@inquirer/rawlist': 4.1.11(@types/node@20.19.34) - '@inquirer/search': 3.2.2(@types/node@20.19.34) - '@inquirer/select': 4.4.2(@types/node@20.19.34) + '@inquirer/prompts@7.10.1(@types/node@20.19.39)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@20.19.39) + '@inquirer/confirm': 5.1.21(@types/node@20.19.39) + '@inquirer/editor': 4.2.23(@types/node@20.19.39) + '@inquirer/expand': 4.0.23(@types/node@20.19.39) + '@inquirer/input': 4.3.1(@types/node@20.19.39) + '@inquirer/number': 3.0.23(@types/node@20.19.39) + '@inquirer/password': 4.0.23(@types/node@20.19.39) + '@inquirer/rawlist': 4.1.11(@types/node@20.19.39) + '@inquirer/search': 3.2.2(@types/node@20.19.39) + '@inquirer/select': 4.4.2(@types/node@20.19.39) optionalDependencies: - '@types/node': 20.19.34 - - '@inquirer/prompts@7.10.1(@types/node@22.19.12)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@22.19.12) - '@inquirer/confirm': 5.1.21(@types/node@22.19.12) - '@inquirer/editor': 4.2.23(@types/node@22.19.12) - '@inquirer/expand': 4.0.23(@types/node@22.19.12) - '@inquirer/input': 4.3.1(@types/node@22.19.12) - '@inquirer/number': 3.0.23(@types/node@22.19.12) - '@inquirer/password': 4.0.23(@types/node@22.19.12) - '@inquirer/rawlist': 4.1.11(@types/node@22.19.12) - '@inquirer/search': 3.2.2(@types/node@22.19.12) - '@inquirer/select': 4.4.2(@types/node@22.19.12) + '@types/node': 20.19.39 + + '@inquirer/prompts@7.10.1(@types/node@22.19.17)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@22.19.17) + '@inquirer/confirm': 5.1.21(@types/node@22.19.17) + '@inquirer/editor': 4.2.23(@types/node@22.19.17) + '@inquirer/expand': 4.0.23(@types/node@22.19.17) + '@inquirer/input': 4.3.1(@types/node@22.19.17) + '@inquirer/number': 3.0.23(@types/node@22.19.17) + '@inquirer/password': 4.0.23(@types/node@22.19.17) + '@inquirer/rawlist': 4.1.11(@types/node@22.19.17) + '@inquirer/search': 3.2.2(@types/node@22.19.17) + '@inquirer/select': 4.4.2(@types/node@22.19.17) optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/rawlist@4.1.11(@types/node@14.18.63)': dependencies: @@ -8166,21 +8198,21 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/rawlist@4.1.11(@types/node@20.19.34)': + '@inquirer/rawlist@4.1.11(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) + '@inquirer/type': 3.0.10(@types/node@20.19.39) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/rawlist@4.1.11(@types/node@22.19.12)': + '@inquirer/rawlist@4.1.11(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) + '@inquirer/type': 3.0.10(@types/node@22.19.17) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/search@3.2.2(@types/node@14.18.63)': dependencies: @@ -8191,23 +8223,23 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/search@3.2.2(@types/node@20.19.34)': + '@inquirer/search@3.2.2(@types/node@20.19.39)': dependencies: - '@inquirer/core': 10.3.2(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/type': 3.0.10(@types/node@20.19.39) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/search@3.2.2(@types/node@22.19.12)': + '@inquirer/search@3.2.2(@types/node@22.19.17)': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/type': 3.0.10(@types/node@22.19.17) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/select@2.5.0': dependencies: @@ -8227,25 +8259,25 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/select@4.4.2(@types/node@20.19.34)': + '@inquirer/select@4.4.2(@types/node@20.19.39)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@20.19.34) + '@inquirer/core': 10.3.2(@types/node@20.19.39) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@20.19.34) + '@inquirer/type': 3.0.10(@types/node@20.19.39) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/select@4.4.2(@types/node@22.19.12)': + '@inquirer/select@4.4.2(@types/node@22.19.17)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@22.19.12) + '@inquirer/core': 10.3.2(@types/node@22.19.17) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.12) + '@inquirer/type': 3.0.10(@types/node@22.19.17) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@inquirer/type@1.5.5': dependencies: @@ -8259,13 +8291,13 @@ snapshots: optionalDependencies: '@types/node': 14.18.63 - '@inquirer/type@3.0.10(@types/node@20.19.34)': + '@inquirer/type@3.0.10(@types/node@20.19.39)': optionalDependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 - '@inquirer/type@3.0.10(@types/node@22.19.12)': + '@inquirer/type@3.0.10(@types/node@22.19.17)': optionalDependencies: - '@types/node': 22.19.12 + '@types/node': 22.19.17 '@isaacs/fs-minipass@4.0.1': dependencies: @@ -8279,7 +8311,7 @@ snapshots: js-yaml: 3.14.2 resolve-from: 5.0.0 - '@istanbuljs/schema@0.1.3': {} + '@istanbuljs/schema@0.1.6': {} '@jest/console@29.7.0': dependencies: @@ -8347,7 +8379,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.19.34 + '@types/node': 14.18.63 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -8475,14 +8507,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jsdoc/salty@0.2.10': + '@jsdoc/salty@0.2.12': dependencies: lodash: 4.18.1 '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 '@tybys/wasm-util': 0.10.1 optional: true @@ -8500,7 +8532,7 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} - '@oclif/core@4.10.3': + '@oclif/core@4.10.5': dependencies: ansi-escapes: 4.3.2 ansis: 3.17.0 @@ -8512,16 +8544,16 @@ snapshots: indent-string: 4.0.0 is-wsl: 2.2.0 lilconfig: 3.1.3 - minimatch: 10.2.4 + minimatch: 10.2.5 semver: 7.7.4 string-width: 4.2.3 supports-color: 8.1.1 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 widest-line: 3.1.0 wordwrap: 1.0.0 wrap-ansi: 7.0.0 - '@oclif/core@4.8.1': + '@oclif/core@4.9.0': dependencies: ansi-escapes: 4.3.2 ansis: 3.17.0 @@ -8533,52 +8565,52 @@ snapshots: indent-string: 4.0.0 is-wsl: 2.2.0 lilconfig: 3.1.3 - minimatch: 10.2.4 + minimatch: 10.2.5 semver: 7.7.4 string-width: 4.2.3 supports-color: 8.1.1 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 widest-line: 3.1.0 wordwrap: 1.0.0 wrap-ansi: 7.0.0 - '@oclif/plugin-help@6.2.37': + '@oclif/plugin-help@6.2.44': dependencies: - '@oclif/core': 4.8.1 + '@oclif/core': 4.10.5 - '@oclif/plugin-not-found@3.2.74(@types/node@14.18.63)': + '@oclif/plugin-not-found@3.2.80(@types/node@14.18.63)': dependencies: '@inquirer/prompts': 7.10.1(@types/node@14.18.63) - '@oclif/core': 4.8.1 + '@oclif/core': 4.10.5 ansis: 3.17.0 fast-levenshtein: 3.0.0 transitivePeerDependencies: - '@types/node' - '@oclif/plugin-not-found@3.2.74(@types/node@20.19.34)': + '@oclif/plugin-not-found@3.2.80(@types/node@20.19.39)': dependencies: - '@inquirer/prompts': 7.10.1(@types/node@20.19.34) - '@oclif/core': 4.8.1 + '@inquirer/prompts': 7.10.1(@types/node@20.19.39) + '@oclif/core': 4.10.5 ansis: 3.17.0 fast-levenshtein: 3.0.0 transitivePeerDependencies: - '@types/node' - '@oclif/plugin-not-found@3.2.74(@types/node@22.19.12)': + '@oclif/plugin-not-found@3.2.80(@types/node@22.19.17)': dependencies: - '@inquirer/prompts': 7.10.1(@types/node@22.19.12) - '@oclif/core': 4.8.1 + '@inquirer/prompts': 7.10.1(@types/node@22.19.17) + '@oclif/core': 4.10.5 ansis: 3.17.0 fast-levenshtein: 3.0.0 transitivePeerDependencies: - '@types/node' - '@oclif/plugin-plugins@5.4.56': + '@oclif/plugin-plugins@5.4.60': dependencies: - '@oclif/core': 4.8.1 + '@oclif/core': 4.10.5 ansis: 3.17.0 debug: 4.4.3(supports-color@8.1.1) - npm: 10.9.4 + npm: 10.9.8 npm-package-arg: 11.0.3 npm-run-path: 5.3.0 object-treeify: 4.0.1 @@ -8589,9 +8621,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@oclif/plugin-warn-if-update-available@3.1.55': + '@oclif/plugin-warn-if-update-available@3.1.60': dependencies: - '@oclif/core': 4.8.1 + '@oclif/core': 4.10.5 ansis: 3.17.0 debug: 4.4.3(supports-color@8.1.1) http-call: 5.3.0 @@ -8600,9 +8632,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@oclif/test@4.1.16(@oclif/core@4.8.1)': + '@oclif/test@4.1.18(@oclif/core@4.10.5)': dependencies: - '@oclif/core': 4.8.1 + '@oclif/core': 4.10.5 ansis: 3.17.0 debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: @@ -8673,10 +8705,15 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers@15.1.0': + '@sinonjs/fake-timers@15.3.2': dependencies: '@sinonjs/commons': 3.0.1 + '@sinonjs/samsam@10.0.2': + dependencies: + '@sinonjs/commons': 3.0.1 + type-detect: 4.1.0 + '@sinonjs/samsam@8.0.3': dependencies: '@sinonjs/commons': 3.0.1 @@ -8684,254 +8721,250 @@ snapshots: '@sinonjs/text-encoding@0.7.3': {} - '@smithy/abort-controller@4.2.10': + '@smithy/chunked-blob-reader-native@4.2.3': dependencies: - '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 tslib: 2.8.1 - '@smithy/chunked-blob-reader-native@4.2.2': + '@smithy/chunked-blob-reader@5.2.2': dependencies: - '@smithy/util-base64': 4.3.1 tslib: 2.8.1 - '@smithy/chunked-blob-reader@5.2.1': + '@smithy/config-resolver@4.4.15': dependencies: + '@smithy/node-config-provider': 4.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-endpoints': 3.4.0 + '@smithy/util-middleware': 4.2.13 tslib: 2.8.1 - '@smithy/config-resolver@4.4.9': - dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-config-provider': 4.2.1 - '@smithy/util-endpoints': 3.3.1 - '@smithy/util-middleware': 4.2.10 - tslib: 2.8.1 - - '@smithy/core@3.23.6': - dependencies: - '@smithy/middleware-serde': 4.2.11 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - '@smithy/util-body-length-browser': 4.2.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-stream': 4.5.15 - '@smithy/util-utf8': 4.2.1 - '@smithy/uuid': 1.1.1 + '@smithy/core@3.23.14': + dependencies: + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-stream': 4.5.22 + '@smithy/util-utf8': 4.2.2 + '@smithy/uuid': 1.1.2 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.2.10': + '@smithy/credential-provider-imds@4.2.13': dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/property-provider': 4.2.10 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 + '@smithy/node-config-provider': 4.3.13 + '@smithy/property-provider': 4.2.13 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 tslib: 2.8.1 - '@smithy/eventstream-codec@4.2.10': + '@smithy/eventstream-codec@4.2.13': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.13.0 - '@smithy/util-hex-encoding': 4.2.1 + '@smithy/types': 4.14.0 + '@smithy/util-hex-encoding': 4.2.2 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.2.10': + '@smithy/eventstream-serde-browser@4.2.13': dependencies: - '@smithy/eventstream-serde-universal': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/eventstream-serde-universal': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.3.10': + '@smithy/eventstream-serde-config-resolver@4.3.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.2.10': + '@smithy/eventstream-serde-node@4.2.13': dependencies: - '@smithy/eventstream-serde-universal': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/eventstream-serde-universal': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.2.10': + '@smithy/eventstream-serde-universal@4.2.13': dependencies: - '@smithy/eventstream-codec': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/eventstream-codec': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.11': + '@smithy/fetch-http-handler@5.3.16': dependencies: - '@smithy/protocol-http': 5.3.10 - '@smithy/querystring-builder': 4.2.10 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 + '@smithy/protocol-http': 5.3.13 + '@smithy/querystring-builder': 4.2.13 + '@smithy/types': 4.14.0 + '@smithy/util-base64': 4.3.2 tslib: 2.8.1 - '@smithy/hash-blob-browser@4.2.11': + '@smithy/hash-blob-browser@4.2.14': dependencies: - '@smithy/chunked-blob-reader': 5.2.1 - '@smithy/chunked-blob-reader-native': 4.2.2 - '@smithy/types': 4.13.0 + '@smithy/chunked-blob-reader': 5.2.2 + '@smithy/chunked-blob-reader-native': 4.2.3 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/hash-node@4.2.10': + '@smithy/hash-node@4.2.13': dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-buffer-from': 4.2.1 - '@smithy/util-utf8': 4.2.1 + '@smithy/types': 4.14.0 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/hash-stream-node@4.2.10': + '@smithy/hash-stream-node@4.2.13': dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-utf8': 4.2.1 + '@smithy/types': 4.14.0 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.10': + '@smithy/invalid-dependency@4.2.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/is-array-buffer@4.2.1': + '@smithy/is-array-buffer@4.2.2': dependencies: tslib: 2.8.1 - '@smithy/md5-js@4.2.10': + '@smithy/md5-js@4.2.13': dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-utf8': 4.2.1 + '@smithy/types': 4.14.0 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.10': + '@smithy/middleware-content-length@4.2.13': dependencies: - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.20': + '@smithy/middleware-endpoint@4.4.29': dependencies: - '@smithy/core': 3.23.6 - '@smithy/middleware-serde': 4.2.11 - '@smithy/node-config-provider': 4.3.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 - '@smithy/url-parser': 4.2.10 - '@smithy/util-middleware': 4.2.10 + '@smithy/core': 3.23.14 + '@smithy/middleware-serde': 4.2.17 + '@smithy/node-config-provider': 4.3.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 + '@smithy/url-parser': 4.2.13 + '@smithy/util-middleware': 4.2.13 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.37': - dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/service-error-classification': 4.2.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-retry': 4.2.10 - '@smithy/uuid': 1.1.1 + '@smithy/middleware-retry@4.5.1': + dependencies: + '@smithy/core': 3.23.14 + '@smithy/node-config-provider': 4.3.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/service-error-classification': 4.2.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-retry': 4.3.1 + '@smithy/uuid': 1.1.2 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.11': + '@smithy/middleware-serde@4.2.17': dependencies: - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 + '@smithy/core': 3.23.14 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/middleware-stack@4.2.10': + '@smithy/middleware-stack@4.2.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/node-config-provider@4.3.10': + '@smithy/node-config-provider@4.3.13': dependencies: - '@smithy/property-provider': 4.2.10 - '@smithy/shared-ini-file-loader': 4.4.5 - '@smithy/types': 4.13.0 + '@smithy/property-provider': 4.2.13 + '@smithy/shared-ini-file-loader': 4.4.8 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.4.12': + '@smithy/node-http-handler@4.5.2': dependencies: - '@smithy/abort-controller': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/querystring-builder': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/protocol-http': 5.3.13 + '@smithy/querystring-builder': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/property-provider@4.2.10': + '@smithy/property-provider@4.2.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/protocol-http@5.3.10': + '@smithy/protocol-http@5.3.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.2.10': + '@smithy/querystring-builder@4.2.13': dependencies: - '@smithy/types': 4.13.0 - '@smithy/util-uri-escape': 4.2.1 + '@smithy/types': 4.14.0 + '@smithy/util-uri-escape': 4.2.2 tslib: 2.8.1 - '@smithy/querystring-parser@4.2.10': + '@smithy/querystring-parser@4.2.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/service-error-classification@4.2.10': + '@smithy/service-error-classification@4.2.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 - '@smithy/shared-ini-file-loader@4.4.5': + '@smithy/shared-ini-file-loader@4.4.8': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/signature-v4@5.3.10': + '@smithy/signature-v4@5.3.13': dependencies: - '@smithy/is-array-buffer': 4.2.1 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-hex-encoding': 4.2.1 - '@smithy/util-middleware': 4.2.10 - '@smithy/util-uri-escape': 4.2.1 - '@smithy/util-utf8': 4.2.1 + '@smithy/is-array-buffer': 4.2.2 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-middleware': 4.2.13 + '@smithy/util-uri-escape': 4.2.2 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/smithy-client@4.12.0': + '@smithy/smithy-client@4.12.9': dependencies: - '@smithy/core': 3.23.6 - '@smithy/middleware-endpoint': 4.4.20 - '@smithy/middleware-stack': 4.2.10 - '@smithy/protocol-http': 5.3.10 - '@smithy/types': 4.13.0 - '@smithy/util-stream': 4.5.15 + '@smithy/core': 3.23.14 + '@smithy/middleware-endpoint': 4.4.29 + '@smithy/middleware-stack': 4.2.13 + '@smithy/protocol-http': 5.3.13 + '@smithy/types': 4.14.0 + '@smithy/util-stream': 4.5.22 tslib: 2.8.1 - '@smithy/types@4.13.0': + '@smithy/types@4.14.0': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.2.10': + '@smithy/url-parser@4.2.13': dependencies: - '@smithy/querystring-parser': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/querystring-parser': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/util-base64@4.3.1': + '@smithy/util-base64@4.3.2': dependencies: - '@smithy/util-buffer-from': 4.2.1 - '@smithy/util-utf8': 4.2.1 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/util-body-length-browser@4.2.1': + '@smithy/util-body-length-browser@4.2.2': dependencies: tslib: 2.8.1 - '@smithy/util-body-length-node@4.2.2': + '@smithy/util-body-length-node@4.2.3': dependencies: tslib: 2.8.1 @@ -8940,65 +8973,65 @@ snapshots: '@smithy/is-array-buffer': 2.2.0 tslib: 2.8.1 - '@smithy/util-buffer-from@4.2.1': + '@smithy/util-buffer-from@4.2.2': dependencies: - '@smithy/is-array-buffer': 4.2.1 + '@smithy/is-array-buffer': 4.2.2 tslib: 2.8.1 - '@smithy/util-config-provider@4.2.1': + '@smithy/util-config-provider@4.2.2': dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.36': + '@smithy/util-defaults-mode-browser@4.3.45': dependencies: - '@smithy/property-provider': 4.2.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 + '@smithy/property-provider': 4.2.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.39': + '@smithy/util-defaults-mode-node@4.2.50': dependencies: - '@smithy/config-resolver': 4.4.9 - '@smithy/credential-provider-imds': 4.2.10 - '@smithy/node-config-provider': 4.3.10 - '@smithy/property-provider': 4.2.10 - '@smithy/smithy-client': 4.12.0 - '@smithy/types': 4.13.0 + '@smithy/config-resolver': 4.4.15 + '@smithy/credential-provider-imds': 4.2.13 + '@smithy/node-config-provider': 4.3.13 + '@smithy/property-provider': 4.2.13 + '@smithy/smithy-client': 4.12.9 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/util-endpoints@3.3.1': + '@smithy/util-endpoints@3.4.0': dependencies: - '@smithy/node-config-provider': 4.3.10 - '@smithy/types': 4.13.0 + '@smithy/node-config-provider': 4.3.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/util-hex-encoding@4.2.1': + '@smithy/util-hex-encoding@4.2.2': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.2.10': + '@smithy/util-middleware@4.2.13': dependencies: - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/util-retry@4.2.10': + '@smithy/util-retry@4.3.1': dependencies: - '@smithy/service-error-classification': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/service-error-classification': 4.2.13 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/util-stream@4.5.15': + '@smithy/util-stream@4.5.22': dependencies: - '@smithy/fetch-http-handler': 5.3.11 - '@smithy/node-http-handler': 4.4.12 - '@smithy/types': 4.13.0 - '@smithy/util-base64': 4.3.1 - '@smithy/util-buffer-from': 4.2.1 - '@smithy/util-hex-encoding': 4.2.1 - '@smithy/util-utf8': 4.2.1 + '@smithy/fetch-http-handler': 5.3.16 + '@smithy/node-http-handler': 4.5.2 + '@smithy/types': 4.14.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/util-uri-escape@4.2.1': + '@smithy/util-uri-escape@4.2.2': dependencies: tslib: 2.8.1 @@ -9007,18 +9040,17 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@4.2.1': + '@smithy/util-utf8@4.2.2': dependencies: - '@smithy/util-buffer-from': 4.2.1 + '@smithy/util-buffer-from': 4.2.2 tslib: 2.8.1 - '@smithy/util-waiter@4.2.10': + '@smithy/util-waiter@4.2.15': dependencies: - '@smithy/abort-controller': 4.2.10 - '@smithy/types': 4.13.0 + '@smithy/types': 4.14.0 tslib: 2.8.1 - '@smithy/uuid@1.1.1': + '@smithy/uuid@1.1.2': dependencies: tslib: 2.8.1 @@ -9029,7 +9061,7 @@ snapshots: '@stylistic/eslint-plugin@3.1.0(eslint@8.57.1)(typescript@4.9.5)': dependencies: - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -9041,7 +9073,7 @@ snapshots: '@stylistic/eslint-plugin@3.1.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -9051,10 +9083,10 @@ snapshots: - supports-color - typescript - '@stylistic/eslint-plugin@5.9.0(eslint@8.57.1)': + '@stylistic/eslint-plugin@5.10.0(eslint@8.57.1)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/types': 8.58.2 eslint: 8.57.1 eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -9080,7 +9112,7 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 @@ -9092,7 +9124,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@types/babel__traverse@7.28.0': @@ -9101,7 +9133,7 @@ snapshots: '@types/big-json@3.2.5': dependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 '@types/bluebird@3.5.42': {} @@ -9114,7 +9146,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.19.34 + '@types/node': 20.19.39 '@types/graceful-fs@4.1.9': dependencies: @@ -9148,7 +9180,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 '@types/linkify-it@5.0.0': {} @@ -9171,15 +9203,15 @@ snapshots: '@types/mute-stream@0.0.4': dependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 '@types/node@14.18.63': {} - '@types/node@20.19.34': + '@types/node@20.19.39': dependencies: undici-types: 6.21.0 - '@types/node@22.19.12': + '@types/node@22.19.17': dependencies: undici-types: 6.21.0 @@ -9187,7 +9219,7 @@ snapshots: '@types/progress-stream@2.0.5': dependencies: - '@types/node': 20.19.34 + '@types/node': 20.19.39 '@types/rewire@2.5.30': {} @@ -9232,10 +9264,10 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) @@ -9291,34 +9323,34 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/type-utils': 8.58.2(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 8.58.2 eslint: 8.57.1 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@4.9.5) + ts-api-utils: 2.5.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/type-utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/type-utils': 8.58.2(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.58.2 eslint: 8.57.1 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -9349,43 +9381,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5)': dependencies: - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@4.9.5) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 8.58.2 debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.58.2 debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@4.9.5)': + '@typescript-eslint/project-service@8.58.2(typescript@4.9.5)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@4.9.5) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@4.9.5) + '@typescript-eslint/types': 8.58.2 debug: 4.4.3(supports-color@8.1.1) typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.58.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) + '@typescript-eslint/types': 8.58.2 debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.3 transitivePeerDependencies: @@ -9406,16 +9438,16 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/scope-manager@8.56.1': + '@typescript-eslint/scope-manager@8.58.2': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/visitor-keys': 8.58.2 - '@typescript-eslint/tsconfig-utils@8.56.1(typescript@4.9.5)': + '@typescript-eslint/tsconfig-utils@8.58.2(typescript@4.9.5)': dependencies: typescript: 4.9.5 - '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.58.2(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -9455,26 +9487,26 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.56.1(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/type-utils@8.58.2(eslint@8.57.1)(typescript@4.9.5)': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@4.9.5) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@4.9.5) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@4.9.5) debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 - ts-api-utils: 2.4.0(typescript@4.9.5) + ts-api-utils: 2.5.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.56.1(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.58.2(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@5.9.3) debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -9485,7 +9517,7 @@ snapshots: '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/types@8.56.1': {} + '@typescript-eslint/types@8.58.2': {} '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': dependencies: @@ -9538,7 +9570,7 @@ snapshots: debug: 4.4.3(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.8 + minimatch: 9.0.9 semver: 7.7.4 ts-api-utils: 1.4.3(typescript@4.9.5) optionalDependencies: @@ -9553,7 +9585,7 @@ snapshots: debug: 4.4.3(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.8 + minimatch: 9.0.9 semver: 7.7.4 ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: @@ -9561,32 +9593,32 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.56.1(typescript@4.9.5)': + '@typescript-eslint/typescript-estree@8.58.2(typescript@4.9.5)': dependencies: - '@typescript-eslint/project-service': 8.56.1(typescript@4.9.5) - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@4.9.5) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/project-service': 8.58.2(typescript@4.9.5) + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@4.9.5) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/visitor-keys': 8.58.2 debug: 4.4.3(supports-color@8.1.1) - minimatch: 10.2.4 + minimatch: 10.2.5 semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@4.9.5) + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.58.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/visitor-keys': 8.56.1 + '@typescript-eslint/project-service': 8.58.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/visitor-keys': 8.58.2 debug: 4.4.3(supports-color@8.1.1) - minimatch: 10.2.4 + minimatch: 10.2.5 semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -9656,23 +9688,23 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.56.1(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/utils@8.58.2(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@4.9.5) eslint: 8.57.1 typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.1(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/utils@8.58.2(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.56.1 - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) eslint: 8.57.1 typescript: 5.9.3 transitivePeerDependencies: @@ -9693,9 +9725,9 @@ snapshots: '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.56.1': + '@typescript-eslint/visitor-keys@8.58.2': dependencies: - '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/types': 8.58.2 eslint-visitor-keys: 5.0.1 '@ungap/structured-clone@1.3.0': {} @@ -9870,7 +9902,7 @@ snapshots: array-back@5.0.0: {} - array-back@6.2.2: {} + array-back@6.2.3: {} array-buffer-byte-length@1.0.2: dependencies: @@ -9879,10 +9911,10 @@ snapshots: array-includes@3.1.9: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 is-string: 1.1.1 @@ -9892,34 +9924,34 @@ snapshots: array.prototype.findlastindex@1.2.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 array.prototype.flat@1.3.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-shim-unscopables: 1.1.0 array.prototype.flatmap@1.3.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-shim-unscopables: 1.1.0 arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-errors: 1.3.0 get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 @@ -9928,7 +9960,7 @@ snapshots: assert@2.1.0: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 is-nan: 1.3.2 object-is: 1.1.6 object.assign: 4.1.7 @@ -9958,11 +9990,11 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axios@1.13.5(debug@4.4.3): + axios@1.15.0(debug@4.4.3): dependencies: - follow-redirects: 1.15.11(debug@4.4.3) + follow-redirects: 1.16.0(debug@4.4.3) form-data: 4.0.5 - proxy-from-env: 1.1.0 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug @@ -9983,7 +10015,7 @@ snapshots: dependencies: '@babel/helper-plugin-utils': 7.28.6 '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 + '@istanbuljs/schema': 0.1.6 istanbul-lib-instrument: 5.2.1 test-exclude: 6.0.0 transitivePeerDependencies: @@ -10025,7 +10057,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.0: {} + baseline-browser-mapping@2.10.18: {} big-json@3.2.0: dependencies: @@ -10062,13 +10094,13 @@ snapshots: browser-stdout@1.3.1: {} - browserslist@4.28.1: + browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.0 - caniuse-lite: 1.0.30001774 - electron-to-chromium: 1.5.302 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) + baseline-browser-mapping: 2.10.18 + caniuse-lite: 1.0.30001788 + electron-to-chromium: 1.5.336 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) bs-logger@0.2.6: dependencies: @@ -10126,7 +10158,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.8: + call-bind@1.0.9: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -10149,7 +10181,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001774: {} + caniuse-lite@1.0.30001788: {} capital-case@1.0.4: dependencies: @@ -10410,9 +10442,9 @@ snapshots: content-type@1.0.5: {} - contentstack@3.26.4: + contentstack@3.27.0: dependencies: - '@contentstack/utils': 1.7.1 + '@contentstack/utils': 1.9.1 es6-promise: 4.2.8 husky: 9.1.7 localStorage: 1.0.4 @@ -10421,9 +10453,9 @@ snapshots: convert-source-map@2.0.0: {} - core-js-compat@3.48.0: + core-js-compat@3.49.0: dependencies: - browserslist: 4.28.1 + browserslist: 4.28.2 core-util-is@1.0.3: {} @@ -10517,7 +10549,7 @@ snapshots: dependencies: mimic-response: 3.1.0 - dedent@1.7.1: {} + dedent@1.7.2: {} deep-eql@4.1.4: dependencies: @@ -10571,7 +10603,7 @@ snapshots: diff@7.0.0: {} - diff@8.0.3: {} + diff@8.0.4: {} dir-glob@3.0.1: dependencies: @@ -10579,18 +10611,20 @@ snapshots: dmd@6.2.3: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 cache-point: 2.0.0 common-sequence: 2.0.2 file-set: 4.0.2 - handlebars: 4.7.8 + handlebars: 4.7.9 marked: 4.3.0 object-get: 2.1.1 reduce-flatten: 3.0.1 reduce-unique: 2.0.1 reduce-without: 1.0.1 test-value: 3.0.0 - walk-back: 5.1.1 + walk-back: 5.1.2 + transitivePeerDependencies: + - '@75lb/nature' doctrine@2.1.0: dependencies: @@ -10623,7 +10657,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.302: {} + electron-to-chromium@1.5.336: {} elegant-spinner@1.0.1: {} @@ -10637,10 +10671,10 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.19.0: + enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.0 + tapable: 2.3.2 entities@4.5.0: {} @@ -10650,12 +10684,12 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.24.1: + es-abstract@1.24.2: dependencies: array-buffer-byte-length: 1.0.2 arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 data-view-buffer: 1.0.2 data-view-byte-length: 1.0.2 @@ -10736,34 +10770,34 @@ snapshots: es6-promise@4.2.8: {} - esbuild@0.27.3: + esbuild@0.27.7: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.3 - '@esbuild/android-arm': 0.27.3 - '@esbuild/android-arm64': 0.27.3 - '@esbuild/android-x64': 0.27.3 - '@esbuild/darwin-arm64': 0.27.3 - '@esbuild/darwin-x64': 0.27.3 - '@esbuild/freebsd-arm64': 0.27.3 - '@esbuild/freebsd-x64': 0.27.3 - '@esbuild/linux-arm': 0.27.3 - '@esbuild/linux-arm64': 0.27.3 - '@esbuild/linux-ia32': 0.27.3 - '@esbuild/linux-loong64': 0.27.3 - '@esbuild/linux-mips64el': 0.27.3 - '@esbuild/linux-ppc64': 0.27.3 - '@esbuild/linux-riscv64': 0.27.3 - '@esbuild/linux-s390x': 0.27.3 - '@esbuild/linux-x64': 0.27.3 - '@esbuild/netbsd-arm64': 0.27.3 - '@esbuild/netbsd-x64': 0.27.3 - '@esbuild/openbsd-arm64': 0.27.3 - '@esbuild/openbsd-x64': 0.27.3 - '@esbuild/openharmony-arm64': 0.27.3 - '@esbuild/sunos-x64': 0.27.3 - '@esbuild/win32-arm64': 0.27.3 - '@esbuild/win32-ia32': 0.27.3 - '@esbuild/win32-x64': 0.27.3 + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 escalade@3.2.0: {} @@ -10829,25 +10863,25 @@ snapshots: transitivePeerDependencies: - eslint - eslint-config-oclif@6.0.144(eslint@8.57.1)(typescript@4.9.5): + eslint-config-oclif@6.0.157(eslint@8.57.1)(typescript@4.9.5): dependencies: '@eslint/compat': 1.4.1(eslint@8.57.1) - '@eslint/eslintrc': 3.3.4 - '@eslint/js': 9.39.3 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 '@stylistic/eslint-plugin': 3.1.0(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@4.9.5) eslint-config-oclif: 5.2.2(eslint@8.57.1) eslint-config-xo: 0.49.0(eslint@8.57.1) eslint-config-xo-space: 0.35.0(eslint@8.57.1) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsdoc: 50.8.0(eslint@8.57.1) eslint-plugin-mocha: 10.5.0(eslint@8.57.1) eslint-plugin-n: 17.24.0(eslint@8.57.1)(typescript@4.9.5) eslint-plugin-perfectionist: 4.15.1(eslint@8.57.1)(typescript@4.9.5) eslint-plugin-unicorn: 56.0.1(eslint@8.57.1) - typescript-eslint: 8.56.1(eslint@8.57.1)(typescript@4.9.5) + typescript-eslint: 8.58.2(eslint@8.57.1)(typescript@4.9.5) transitivePeerDependencies: - eslint - eslint-import-resolver-webpack @@ -10855,25 +10889,25 @@ snapshots: - supports-color - typescript - eslint-config-oclif@6.0.144(eslint@8.57.1)(typescript@5.9.3): + eslint-config-oclif@6.0.157(eslint@8.57.1)(typescript@5.9.3): dependencies: '@eslint/compat': 1.4.1(eslint@8.57.1) - '@eslint/eslintrc': 3.3.4 - '@eslint/js': 9.39.3 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 '@stylistic/eslint-plugin': 3.1.0(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@5.9.3) eslint-config-oclif: 5.2.2(eslint@8.57.1) eslint-config-xo: 0.49.0(eslint@8.57.1) eslint-config-xo-space: 0.35.0(eslint@8.57.1) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsdoc: 50.8.0(eslint@8.57.1) eslint-plugin-mocha: 10.5.0(eslint@8.57.1) eslint-plugin-n: 17.24.0(eslint@8.57.1)(typescript@5.9.3) eslint-plugin-perfectionist: 4.15.1(eslint@8.57.1)(typescript@5.9.3) eslint-plugin-unicorn: 56.0.1(eslint@8.57.1) - typescript-eslint: 8.56.1(eslint@8.57.1)(typescript@5.9.3) + typescript-eslint: 8.58.2(eslint@8.57.1)(typescript@5.9.3) transitivePeerDependencies: - eslint - eslint-import-resolver-webpack @@ -10895,16 +10929,16 @@ snapshots: dependencies: '@eslint/css': 0.10.0 '@eslint/json': 0.13.2 - '@stylistic/eslint-plugin': 5.9.0(eslint@8.57.1) + '@stylistic/eslint-plugin': 5.10.0(eslint@8.57.1) confusing-browser-globals: 1.0.11 eslint: 8.57.1 globals: 16.5.0 - eslint-import-resolver-node@0.3.9: + eslint-import-resolver-node@0.3.10: dependencies: debug: 3.2.7 is-core-module: 2.16.1 - resolve: 1.22.11 + resolve: 2.0.0-next.6 transitivePeerDependencies: - supports-color @@ -10913,10 +10947,10 @@ snapshots: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 - get-tsconfig: 4.13.6 + get-tsconfig: 4.13.7 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) @@ -10928,56 +10962,56 @@ snapshots: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 - get-tsconfig: 4.13.6 + get-tsconfig: 4.13.7 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-node: 0.3.10 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(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@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 + 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@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-node: 0.3.10 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(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@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 + 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@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -11005,8 +11039,8 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11034,8 +11068,8 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(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@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11053,7 +11087,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11063,8 +11097,8 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11076,13 +11110,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@4.9.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11092,8 +11126,8 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(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@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11105,7 +11139,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -11143,16 +11177,16 @@ snapshots: ignore: 5.3.2 is-core-module: 2.16.1 minimatch: 3.1.5 - resolve: 1.22.11 + resolve: 1.22.12 semver: 7.7.4 eslint-plugin-n@17.24.0(eslint@8.57.1)(typescript@4.9.5): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - enhanced-resolve: 5.19.0 + enhanced-resolve: 5.20.1 eslint: 8.57.1 eslint-plugin-es-x: 7.8.0(eslint@8.57.1) - get-tsconfig: 4.13.6 + get-tsconfig: 4.13.7 globals: 15.15.0 globrex: 0.1.2 ignore: 5.3.2 @@ -11164,10 +11198,10 @@ snapshots: eslint-plugin-n@17.24.0(eslint@8.57.1)(typescript@5.9.3): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - enhanced-resolve: 5.19.0 + enhanced-resolve: 5.20.1 eslint: 8.57.1 eslint-plugin-es-x: 7.8.0(eslint@8.57.1) - get-tsconfig: 4.13.6 + get-tsconfig: 4.13.7 globals: 15.15.0 globrex: 0.1.2 ignore: 5.3.2 @@ -11180,7 +11214,7 @@ snapshots: dependencies: '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 - minimatch: 9.0.8 + minimatch: 9.0.9 natural-compare-lite: 1.4.0 transitivePeerDependencies: - supports-color @@ -11190,7 +11224,7 @@ snapshots: dependencies: '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 - minimatch: 9.0.8 + minimatch: 9.0.9 natural-compare-lite: 1.4.0 transitivePeerDependencies: - supports-color @@ -11198,8 +11232,8 @@ snapshots: eslint-plugin-perfectionist@4.15.1(eslint@8.57.1)(typescript@4.9.5): dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 natural-orderby: 5.0.0 transitivePeerDependencies: @@ -11208,8 +11242,8 @@ snapshots: eslint-plugin-perfectionist@4.15.1(eslint@8.57.1)(typescript@5.9.3): dependencies: - '@typescript-eslint/types': 8.56.1 - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 natural-orderby: 5.0.0 transitivePeerDependencies: @@ -11241,7 +11275,7 @@ snapshots: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) ci-info: 4.4.0 clean-regexp: 1.0.0 - core-js-compat: 3.48.0 + core-js-compat: 3.49.0 eslint: 8.57.1 esquery: 1.7.0 globals: 15.15.0 @@ -11332,15 +11366,15 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.39.3: + eslint@9.39.4: dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 + '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.4 - '@eslint/js': 9.39.3 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 @@ -11443,7 +11477,7 @@ snapshots: dependencies: '@types/chai': 4.3.20 '@types/lodash': 4.17.24 - '@types/node': 20.19.34 + '@types/node': 20.19.39 '@types/sinon': 17.0.4 lodash: 4.18.1 mock-stdin: 1.0.0 @@ -11477,9 +11511,15 @@ snapshots: fast-uri@3.1.0: {} - fast-xml-parser@5.3.6: + fast-xml-builder@1.1.4: + dependencies: + path-expression-matcher: 1.5.0 + + fast-xml-parser@5.5.8: dependencies: - strnum: 2.1.2 + fast-xml-builder: 1.1.4 + path-expression-matcher: 1.5.0 + strnum: 2.2.3 fastest-levenshtein@1.0.16: {} @@ -11563,22 +11603,22 @@ snapshots: flat-cache@3.2.0: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 rimraf: 3.0.2 flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 flat@5.0.2: {} - flatted@3.3.3: {} + flatted@3.4.2: {} fn.name@1.1.0: {} - follow-redirects@1.15.11(debug@4.4.3): + follow-redirects@1.16.0(debug@4.4.3): optionalDependencies: debug: 4.4.3(supports-color@8.1.1) @@ -11608,7 +11648,7 @@ snapshots: fromentries@1.3.2: {} - fs-extra@11.3.3: + fs-extra@11.3.4: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.0 @@ -11631,7 +11671,7 @@ snapshots: function.prototype.name@1.1.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 @@ -11674,7 +11714,7 @@ snapshots: get-stream@4.1.0: dependencies: - pump: 3.0.3 + pump: 3.0.4 get-stream@6.0.1: {} @@ -11684,7 +11724,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.13.6: + get-tsconfig@4.13.7: dependencies: resolve-pkg-maps: 1.0.0 @@ -11702,7 +11742,7 @@ snapshots: glob@13.0.6: dependencies: - minimatch: 10.2.4 + minimatch: 10.2.5 minipass: 7.1.3 path-scurry: 2.0.2 @@ -11773,7 +11813,7 @@ snapshots: graphemer@1.4.0: {} - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -11891,12 +11931,12 @@ snapshots: ini@1.3.8: {} - inquirer-checkbox-plus-prompt@1.4.2(inquirer@8.2.7(@types/node@20.19.34)): + inquirer-checkbox-plus-prompt@1.4.2(inquirer@8.2.7(@types/node@20.19.39)): dependencies: chalk: 4.1.2 cli-cursor: 3.1.0 figures: 3.2.0 - inquirer: 8.2.7(@types/node@20.19.34) + inquirer: 8.2.7(@types/node@20.19.39) lodash: 4.18.1 rxjs: 6.6.7 @@ -11951,9 +11991,9 @@ snapshots: transitivePeerDependencies: - '@types/node' - inquirer@8.2.7(@types/node@20.19.34): + inquirer@8.2.7(@types/node@20.19.39): dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@20.19.34) + '@inquirer/external-editor': 1.0.3(@types/node@20.19.39) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -11971,9 +12011,9 @@ snapshots: transitivePeerDependencies: - '@types/node' - inquirer@8.2.7(@types/node@22.19.12): + inquirer@8.2.7(@types/node@22.19.17): dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@22.19.12) + '@inquirer/external-editor': 1.0.3(@types/node@22.19.17) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -12011,7 +12051,7 @@ snapshots: is-array-buffer@3.0.5: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 get-intrinsic: 1.3.0 @@ -12099,7 +12139,7 @@ snapshots: is-nan@1.3.2: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 is-negative-zero@2.0.3: {} @@ -12199,7 +12239,7 @@ snapshots: istanbul-lib-instrument@4.0.3: dependencies: '@babel/core': 7.29.0 - '@istanbuljs/schema': 0.1.3 + '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: @@ -12208,8 +12248,8 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.29.0 - '@istanbuljs/schema': 0.1.3 + '@babel/parser': 7.29.2 + '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: @@ -12218,8 +12258,8 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.29.0 - '@istanbuljs/schema': 0.1.3 + '@babel/parser': 7.29.2 + '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 7.7.4 transitivePeerDependencies: @@ -12274,7 +12314,7 @@ snapshots: '@types/node': 14.18.63 chalk: 4.1.2 co: 4.6.0 - dedent: 1.7.1 + dedent: 1.7.2 is-generator-fn: 2.1.0 jest-each: 29.7.0 jest-matcher-utils: 29.7.0 @@ -12423,7 +12463,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.34 + '@types/node': 14.18.63 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -12447,7 +12487,7 @@ snapshots: jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) jest-util: 29.7.0 jest-validate: 29.7.0 - resolve: 1.22.11 + resolve: 1.22.12 resolve.exports: 2.0.3 slash: 3.0.0 @@ -12594,7 +12634,7 @@ snapshots: jsdoc-api@8.1.1: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 cache-point: 2.0.0 collect-all: 1.0.4 file-set: 4.0.2 @@ -12602,11 +12642,13 @@ snapshots: jsdoc: 4.0.5 object-to-spawn-args: 2.0.1 temp-path: 1.0.0 - walk-back: 5.1.1 + walk-back: 5.1.2 + transitivePeerDependencies: + - '@75lb/nature' jsdoc-parse@6.2.5: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 find-replace: 5.0.2 sort-array: 5.1.1 transitivePeerDependencies: @@ -12614,13 +12656,13 @@ snapshots: jsdoc-to-markdown@8.0.3: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 command-line-tool: 0.8.0 config-master: 3.1.0 dmd: 6.2.3 jsdoc-api: 8.1.1 jsdoc-parse: 6.2.5 - walk-back: 5.1.1 + walk-back: 5.1.2 transitivePeerDependencies: - '@75lb/nature' @@ -12628,8 +12670,8 @@ snapshots: jsdoc@4.0.5: dependencies: - '@babel/parser': 7.29.0 - '@jsdoc/salty': 0.2.10 + '@babel/parser': 7.29.2 + '@jsdoc/salty': 0.2.12 '@types/markdown-it': 14.1.2 bluebird: 3.7.2 catharsis: 0.9.0 @@ -12834,7 +12876,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.6: {} + lru-cache@11.3.5: {} lru-cache@5.1.1: dependencies: @@ -12905,7 +12947,7 @@ snapshots: min-indent@1.0.1: {} - minimatch@10.2.4: + minimatch@10.2.5: dependencies: brace-expansion: 5.0.5 @@ -12921,7 +12963,7 @@ snapshots: dependencies: brace-expansion: 5.0.5 - minimatch@9.0.8: + minimatch@9.0.9: dependencies: brace-expansion: 5.0.5 @@ -12998,13 +13040,12 @@ snapshots: just-extend: 6.2.0 path-to-regexp: 6.3.0 - nise@6.1.1: + nise@6.1.5: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 13.0.5 - '@sinonjs/text-encoding': 0.7.3 + '@sinonjs/fake-timers': 15.3.2 just-extend: 6.2.0 - path-to-regexp: 8.3.0 + path-to-regexp: 8.4.2 no-case@3.0.4: dependencies: @@ -13019,18 +13060,25 @@ snapshots: transitivePeerDependencies: - supports-color + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + node-int64@0.4.0: {} node-preload@0.2.1: dependencies: process-on-spawn: 1.1.0 - node-releases@2.0.27: {} + node-releases@2.0.37: {} normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.11 + resolve: 1.22.12 semver: 5.7.2 validate-npm-package-license: 3.0.4 @@ -13063,14 +13111,14 @@ snapshots: dependencies: path-key: 4.0.0 - npm@10.9.4: {} + npm@10.9.8: {} number-is-nan@1.0.1: {} nyc@15.1.0: dependencies: '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 + '@istanbuljs/schema': 0.1.6 caching-transform: 4.0.0 convert-source-map: 1.9.0 decamelize: 1.2.0 @@ -13107,7 +13155,7 @@ snapshots: object-is@1.1.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 object-keys@1.1.1: {} @@ -13118,44 +13166,51 @@ snapshots: object.assign@4.1.7: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 has-symbols: 1.1.0 object-keys: 1.1.1 + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + object.fromentries@2.0.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 object.groupby@1.0.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 object.values@1.2.1: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 - oclif@4.22.81(@types/node@14.18.63): + oclif@4.23.0(@types/node@14.18.63): dependencies: - '@aws-sdk/client-cloudfront': 3.998.0 - '@aws-sdk/client-s3': 3.998.0 + '@aws-sdk/client-cloudfront': 3.1009.0 + '@aws-sdk/client-s3': 3.1014.0 '@inquirer/confirm': 3.2.0 '@inquirer/input': 2.3.0 '@inquirer/select': 2.5.0 - '@oclif/core': 4.8.1 - '@oclif/plugin-help': 6.2.37 - '@oclif/plugin-not-found': 3.2.74(@types/node@14.18.63) - '@oclif/plugin-warn-if-update-available': 3.1.55 + '@oclif/core': 4.9.0 + '@oclif/plugin-help': 6.2.44 + '@oclif/plugin-not-found': 3.2.80(@types/node@14.18.63) + '@oclif/plugin-warn-if-update-available': 3.1.60 ansis: 3.17.0 async-retry: 1.3.3 change-case: 4.1.2 @@ -13176,17 +13231,17 @@ snapshots: - aws-crt - supports-color - oclif@4.22.81(@types/node@20.19.34): + oclif@4.23.0(@types/node@20.19.39): dependencies: - '@aws-sdk/client-cloudfront': 3.998.0 - '@aws-sdk/client-s3': 3.998.0 + '@aws-sdk/client-cloudfront': 3.1009.0 + '@aws-sdk/client-s3': 3.1014.0 '@inquirer/confirm': 3.2.0 '@inquirer/input': 2.3.0 '@inquirer/select': 2.5.0 - '@oclif/core': 4.8.1 - '@oclif/plugin-help': 6.2.37 - '@oclif/plugin-not-found': 3.2.74(@types/node@20.19.34) - '@oclif/plugin-warn-if-update-available': 3.1.55 + '@oclif/core': 4.9.0 + '@oclif/plugin-help': 6.2.44 + '@oclif/plugin-not-found': 3.2.80(@types/node@20.19.39) + '@oclif/plugin-warn-if-update-available': 3.1.60 ansis: 3.17.0 async-retry: 1.3.3 change-case: 4.1.2 @@ -13207,17 +13262,17 @@ snapshots: - aws-crt - supports-color - oclif@4.22.81(@types/node@22.19.12): + oclif@4.23.0(@types/node@22.19.17): dependencies: - '@aws-sdk/client-cloudfront': 3.998.0 - '@aws-sdk/client-s3': 3.998.0 + '@aws-sdk/client-cloudfront': 3.1009.0 + '@aws-sdk/client-s3': 3.1014.0 '@inquirer/confirm': 3.2.0 '@inquirer/input': 2.3.0 '@inquirer/select': 2.5.0 - '@oclif/core': 4.8.1 - '@oclif/plugin-help': 6.2.37 - '@oclif/plugin-not-found': 3.2.74(@types/node@22.19.12) - '@oclif/plugin-warn-if-update-available': 3.1.55 + '@oclif/core': 4.9.0 + '@oclif/plugin-help': 6.2.44 + '@oclif/plugin-not-found': 3.2.80(@types/node@22.19.17) + '@oclif/plugin-warn-if-update-available': 3.1.60 ansis: 3.17.0 async-retry: 1.3.3 change-case: 4.1.2 @@ -13381,6 +13436,8 @@ snapshots: path-exists@4.0.0: {} + path-expression-matcher@1.5.0: {} + path-is-absolute@1.0.1: {} path-key@2.0.1: {} @@ -13393,12 +13450,12 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.2.6 + lru-cache: 11.3.5 minipass: 7.1.3 path-to-regexp@6.3.0: {} - path-to-regexp@8.3.0: {} + path-to-regexp@8.4.2: {} path-type@4.0.0: {} @@ -13420,7 +13477,7 @@ snapshots: pluralize@8.0.0: {} - pnpm@10.30.3: {} + pnpm@10.33.0: {} possible-typed-array-names@1.1.0: {} @@ -13471,9 +13528,9 @@ snapshots: proto-list@1.2.4: {} - proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 @@ -13484,7 +13541,7 @@ snapshots: pure-rand@6.1.0: {} - qs@6.15.0: + qs@6.15.1: dependencies: side-channel: 1.1.0 @@ -13560,7 +13617,7 @@ snapshots: rechoir@0.6.2: dependencies: - resolve: 1.22.11 + resolve: 1.22.12 redeyed@2.1.1: dependencies: @@ -13578,9 +13635,9 @@ snapshots: reflect.getprototypeof@1.0.10: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 @@ -13591,7 +13648,7 @@ snapshots: regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 es-errors: 1.3.0 get-proto: 1.0.1 @@ -13636,12 +13693,22 @@ snapshots: resolve.exports@2.0.3: {} - resolve@1.22.11: + resolve@1.22.12: dependencies: + es-errors: 1.3.0 is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resolve@2.0.0-next.6: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + responselike@3.0.0: dependencies: lowercase-keys: 3.0.0 @@ -13664,7 +13731,7 @@ snapshots: rewire@9.0.1: dependencies: - eslint: 9.39.3 + eslint: 9.39.4 pirates: 4.0.7 transitivePeerDependencies: - jiti @@ -13701,7 +13768,7 @@ snapshots: safe-array-concat@1.1.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 get-intrinsic: 1.3.0 has-symbols: 1.1.0 @@ -13790,7 +13857,7 @@ snapshots: minimist: 1.2.8 shelljs: 0.9.2 - side-channel-list@1.0.0: + side-channel-list@1.0.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -13814,7 +13881,7 @@ snapshots: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 - side-channel-list: 1.0.0 + side-channel-list: 1.0.1 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 @@ -13837,16 +13904,15 @@ snapshots: '@sinonjs/fake-timers': 13.0.5 '@sinonjs/samsam': 8.0.3 diff: 7.0.0 - nise: 6.1.1 + nise: 6.1.5 supports-color: 7.2.0 - sinon@21.0.1: + sinon@21.1.2: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 15.1.0 - '@sinonjs/samsam': 8.0.3 - diff: 8.0.3 - supports-color: 7.2.0 + '@sinonjs/fake-timers': 15.3.2 + '@sinonjs/samsam': 10.0.2 + diff: 8.0.4 sisteransi@1.0.5: {} @@ -13870,7 +13936,7 @@ snapshots: sort-array@5.1.1: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 typical: 7.3.0 sort-object-keys@1.1.3: {} @@ -13884,7 +13950,7 @@ snapshots: is-plain-obj: 4.1.0 semver: 7.7.4 sort-object-keys: 1.1.3 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 source-map-js@1.2.1: {} @@ -13991,24 +14057,24 @@ snapshots: string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -14046,7 +14112,7 @@ snapshots: strip-json-comments@3.1.1: {} - strnum@2.1.2: {} + strnum@2.2.3: {} supports-color@2.0.0: {} @@ -14074,9 +14140,9 @@ snapshots: typical: 2.6.1 wordwrapjs: 3.0.0 - tapable@2.3.0: {} + tapable@2.3.2: {} - tar@7.5.11: + tar@7.5.13: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -14088,7 +14154,7 @@ snapshots: test-exclude@6.0.0: dependencies: - '@istanbuljs/schema': 0.1.3 + '@istanbuljs/schema': 0.1.6 glob: 7.2.3 minimatch: 3.1.5 @@ -14122,7 +14188,7 @@ snapshots: tiny-jsonc@1.0.2: {} - tinyglobby@0.2.15: + tinyglobby@0.2.16: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 @@ -14155,11 +14221,11 @@ snapshots: dependencies: typescript: 5.9.3 - ts-api-utils@2.4.0(typescript@4.9.5): + ts-api-utils@2.5.0(typescript@4.9.5): dependencies: typescript: 4.9.5 - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -14173,11 +14239,11 @@ snapshots: picomatch: 4.0.4 typescript: 5.9.3 - ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@14.18.63)(ts-node@8.10.2(typescript@4.9.5)))(typescript@4.9.5): + ts-jest@29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@14.18.63)(ts-node@8.10.2(typescript@4.9.5)))(typescript@4.9.5): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 + handlebars: 4.7.9 jest: 29.7.0(@types/node@14.18.63)(ts-node@8.10.2(typescript@4.9.5)) json5: 2.2.3 lodash.memoize: 4.1.2 @@ -14211,14 +14277,14 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-node@10.9.2(@types/node@20.19.34)(typescript@5.9.3): + ts-node@10.9.2(@types/node@20.19.39)(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': 20.19.34 + '@types/node': 20.19.39 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 @@ -14229,14 +14295,14 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-node@10.9.2(@types/node@22.19.12)(typescript@4.9.5): + ts-node@10.9.2(@types/node@22.19.17)(typescript@4.9.5): 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.19.12 + '@types/node': 22.19.17 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 @@ -14274,8 +14340,8 @@ snapshots: tsx@4.21.0: dependencies: - esbuild: 0.27.3 - get-tsconfig: 4.13.6 + esbuild: 0.27.7 + get-tsconfig: 4.13.7 optionalDependencies: fsevents: 2.3.3 @@ -14319,7 +14385,7 @@ snapshots: typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 @@ -14328,7 +14394,7 @@ snapshots: typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 @@ -14337,7 +14403,7 @@ snapshots: typed-array-length@1.0.7: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 is-typed-array: 1.1.15 @@ -14350,9 +14416,9 @@ snapshots: typedarray.prototype.slice@1.0.5: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-errors: 1.3.0 get-proto: 1.0.1 math-intrinsics: 1.1.0 @@ -14361,23 +14427,23 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.56.1(eslint@8.57.1)(typescript@4.9.5): + typescript-eslint@8.58.2(eslint@8.57.1)(typescript@4.9.5): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/typescript-estree': 8.56.1(typescript@4.9.5) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 8.58.2(typescript@4.9.5) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 typescript: 4.9.5 transitivePeerDependencies: - supports-color - typescript-eslint@8.56.1(eslint@8.57.1)(typescript@5.9.3): + typescript-eslint@8.58.2(eslint@8.57.1)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.1(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.1(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.58.2(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.58.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.58.2(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 typescript: 5.9.3 transitivePeerDependencies: @@ -14441,9 +14507,9 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - update-browserslist-db@1.2.3(browserslist@4.28.1): + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: - browserslist: 4.28.1 + browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -14490,7 +14556,7 @@ snapshots: walk-back@2.0.1: {} - walk-back@5.1.1: {} + walk-back@5.1.2: {} walker@1.0.8: dependencies: @@ -14536,7 +14602,7 @@ snapshots: which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 for-each: 0.3.5 get-proto: 1.0.1 From 8d8cc929f30c4eeb9247fe9637a6502f31335ed1 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Wed, 22 Apr 2026 12:10:28 +0530 Subject: [PATCH 6/9] chore: update lint --- .talismanrc | 14 +- .../src/commands/cm/stacks/export.ts | 121 +++++++++--------- 2 files changed, 62 insertions(+), 73 deletions(-) diff --git a/.talismanrc b/.talismanrc index 46fbd9349..9a81e2a60 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,14 +1,4 @@ fileignoreconfig: - - filename: pnpm-lock.yaml - checksum: f614edf878dd0fb734e54c5649c8fec09ce03f454f26d166d402661528e716e7 - - filename: packages/contentstack-branches/README.md - checksum: 20d649ee8af8c91a3c4ea35038f740738cdd3e2c2d7d6286d40d2ce33d4fec7d - - filename: packages/contentstack-branches/src/utils/create-branch.ts - checksum: d0613295ee26f7a77d026e40db0a4ab726fabd0a74965f729f1a66d1ef14768f - - filename: packages/contentstack-branches/src/commands/cm/branches/merge-status.ts - checksum: 6e5b959ddcc5ff68e03c066ea185fcf6c6e57b1819069730340af35aad8a93a8 - - filename: packages/contentstack-branches/src/branch/diff-handler.ts - checksum: 3cd4d26a2142cab7cbf2094c9251e028467d17d6a1ed6daf22f21975133805f1 - - filename: packages/contentstack-branches/src/branch/merge-handler.ts - checksum: 0b84508c013bfb50f99f5c96ae36969c3101017c4cc132ee61242ac45faeffc9 + - filename: packages/contentstack-export/src/commands/cm/stacks/export.ts + checksum: 6ca7ca3a1dbecba4a28d0aae13ecee7f0dba58aa100d310a5993111357eebfbf version: '1.0' diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 533147484..4bd542e6d 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -1,17 +1,19 @@ import { Command } from '@contentstack/cli-command'; import { + cliux, + messageHandler, + printFlagDeprecation, + managementSDKClient, + flags, ContentstackClient, FlagInput, - createLogContext, - flags, - getLogPath, - handleAndLogError, - log, - managementSDKClient, - messageHandler, pathValidator, - printFlagDeprecation, sanitizePath, + configHandler, + log, + handleAndLogError, + getLogPath, + createLogContext, } from '@contentstack/cli-utilities'; import { ModuleExporter } from '../../../export'; @@ -19,8 +21,6 @@ import { ExportConfig } from '../../../types'; import { setupExportConfig, writeExportMetaFile } from '../../../utils'; export default class ExportCommand extends Command { - static aliases: string[] = ['cm:export']; - static description: string = messageHandler.parse('Export content from a stack'); static examples: string[] = [ @@ -33,39 +33,23 @@ export default class ExportCommand extends Command { 'csdx cm:stacks:export --branch [optional] branch name', ]; + static usage: string = + 'cm:stacks:export [-c ] [-k ] [-d ] [-a ] [--module ] [--content-types ] [--branch ] [--secured-assets]'; + static flags: FlagInput = { - alias: flags.string({ - char: 'a', - description: 'The management token alias of the source stack from which you will export content.', - }), - 'auth-token': flags.boolean({ - char: 'A', - description: 'to use auth token', - hidden: true, - parse: printFlagDeprecation(['-A', '--auth-token']), - }), - branch: flags.string({ - char: 'B', - // default: 'main', - description: - "[optional] The name of the branch where you want to export your content. If you don't mention the branch name, then by default the content will be exported from all the branches of your stack.", - exclusive: ['branch-alias'], - parse: printFlagDeprecation(['-B'], ['--branch']), - }), - 'branch-alias': flags.string({ - description: '(Optional) The alias of the branch from which you want to export content.', - exclusive: ['branch'], - }), config: flags.string({ char: 'c', description: '[optional] Path of the config', }), - 'content-types': flags.string({ - char: 't', - description: - '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.', - multiple: true, - parse: printFlagDeprecation(['-t'], ['--content-types']), + 'stack-uid': flags.string({ + char: 's', + description: 'API key of the source stack', + hidden: true, + parse: printFlagDeprecation(['-s', '--stack-uid'], ['-k', '--stack-api-key']), + }), + 'stack-api-key': flags.string({ + char: 'k', + description: 'API Key of the source stack', }), data: flags.string({ description: 'path or location to store the data', @@ -76,57 +60,75 @@ export default class ExportCommand extends Command { char: 'd', description: 'The path or the location in your file system to store the exported content. For e.g., ./content', }), + alias: flags.string({ + char: 'a', + description: 'The management token alias of the source stack from which you will export content.', + }), 'management-token-alias': flags.string({ description: 'alias of the management token', hidden: true, parse: printFlagDeprecation(['--management-token-alias'], ['-a', '--alias']), }), + 'auth-token': flags.boolean({ + char: 'A', + description: 'to use auth token', + hidden: true, + parse: printFlagDeprecation(['-A', '--auth-token']), + }), module: flags.string({ char: 'm', description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, taxonomies, and studio.', parse: printFlagDeprecation(['-m'], ['--module']), }), - query: flags.string({ - description: '[optional] Query object (inline JSON or file path) to filter module exports.', - hidden: true, + 'content-types': flags.string({ + char: 't', + description: + '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.', + multiple: true, + parse: printFlagDeprecation(['-t'], ['--content-types']), }), - 'secured-assets': flags.boolean({ - description: '[optional] Use this flag for assets that are secured.', + branch: flags.string({ + char: 'B', + // default: 'main', + description: + "[optional] The name of the branch where you want to export your content. If you don't mention the branch name, then by default the content will be exported from all the branches of your stack.", + parse: printFlagDeprecation(['-B'], ['--branch']), + exclusive: ['branch-alias'], }), - 'stack-api-key': flags.string({ - char: 'k', - description: 'API Key of the source stack', + 'branch-alias': flags.string({ + description: '(Optional) The alias of the branch from which you want to export content.', + exclusive: ['branch'], }), - 'stack-uid': flags.string({ - char: 's', - description: 'API key of the source stack', - hidden: true, - parse: printFlagDeprecation(['-s', '--stack-uid'], ['-k', '--stack-api-key']), + 'secured-assets': flags.boolean({ + description: '[optional] Use this flag for assets that are secured.', }), yes: flags.boolean({ char: 'y', - description: '[optional] Force override all Marketplace prompts.', required: false, + description: '[optional] Force override all Marketplace prompts.', + }), + query: flags.string({ + description: '[optional] Query object (inline JSON or file path) to filter module exports.', + hidden: true, }), }; - static usage = - 'cm:stacks:export [-c ] [-k ] [-d ] [-a ] [--module ] [--content-types ] [--branch ] [--secured-assets]'; + static aliases: string[] = ['cm:export']; async run(): Promise { let exportDir: string = pathValidator('logs'); try { const { flags } = await this.parse(ExportCommand); const exportConfig = await setupExportConfig(flags); - + // Store apiKey in configHandler for session.json (return value not needed) createLogContext( this.context?.info?.command || 'cm:stacks:export', exportConfig.apiKey, - exportConfig.authenticationMethod + exportConfig.authenticationMethod, ); - + // For log entries, only pass module (other fields are in session.json) exportConfig.context = { module: '' }; //log.info(`Using Cli Version: ${this.context?.cliVersion}`, exportConfig.context); @@ -141,9 +143,7 @@ export default class ExportCommand extends Command { if (!exportConfig.branches?.length) { writeExportMetaFile(exportConfig); } - log.success( - `The content of the stack ${exportConfig.apiKey} has been exported successfully!`, - ); + log.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`); log.info(`The exported content has been stored at '${exportDir}'.`, exportConfig.context); log.success(`The log has been stored at '${getLogPath()}'.`, exportConfig.context); } catch (error) { @@ -152,7 +152,6 @@ export default class ExportCommand extends Command { } } - // Assign values to exportConfig private assignExportConfig(exportConfig: ExportConfig): void { // Note setting host to create cma client From 8c054c05148e2414c08d4d38945c6e6c86d28d9d Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Wed, 22 Apr 2026 12:22:25 +0530 Subject: [PATCH 7/9] chore: fix lint issues --- .talismanrc | 30 +- .../contentstack-export/src/config/index.ts | 840 +++++++++--------- .../src/export/module-exporter.ts | 75 +- .../src/export/modules/assets.ts | 436 ++++----- .../src/export/modules/base-class.ts | 188 ++-- .../src/export/modules/composable-studio.ts | 74 +- .../src/export/modules/content-types.ts | 74 +- .../src/export/modules/custom-roles.ts | 141 +-- .../src/export/modules/entries.ts | 329 +++---- .../src/export/modules/environments.ts | 87 +- .../src/export/modules/extensions.ts | 85 +- .../src/export/modules/global-fields.ts | 112 +-- .../src/export/modules/index.ts | 3 +- .../src/export/modules/labels.ts | 85 +- .../src/export/modules/locales.ts | 139 +-- .../src/export/modules/marketplace-apps.ts | 272 +++--- .../src/export/modules/personalize.ts | 43 +- .../src/export/modules/publishing-rules.ts | 15 +- .../src/export/modules/stack.ts | 180 ++-- .../src/export/modules/taxonomies.ts | 326 +++---- .../src/export/modules/webhooks.ts | 87 +- .../src/export/modules/workflows.ts | 133 ++- .../src/types/default-config.ts | 250 +++--- .../src/types/export-config.ts | 46 +- .../contentstack-export/src/types/index.ts | 91 +- .../src/types/marketplace-app.ts | 46 +- .../src/utils/basic-login.ts | 13 +- .../src/utils/common-helper.ts | 4 +- .../src/utils/export-config-handler.ts | 17 +- .../src/utils/file-helper.ts | 14 +- .../contentstack-export/src/utils/index.ts | 10 +- .../src/utils/interactive.ts | 16 +- .../contentstack-export/src/utils/logger.ts | 52 +- .../src/utils/marketplace-app-helper.ts | 16 +- .../src/utils/setup-branches.ts | 6 +- .../src/utils/setup-export-dir.ts | 6 +- 36 files changed, 2204 insertions(+), 2137 deletions(-) diff --git a/.talismanrc b/.talismanrc index 9a81e2a60..6199b48e8 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,30 @@ fileignoreconfig: - - filename: packages/contentstack-export/src/commands/cm/stacks/export.ts - checksum: 6ca7ca3a1dbecba4a28d0aae13ecee7f0dba58aa100d310a5993111357eebfbf + - filename: packages/contentstack-export/src/export/modules/environments.ts + checksum: 3b606a0cab740e20fbda0a9d25d76dc7971f264b447da9b135ad1e7749b314d2 + - filename: packages/contentstack-export/src/export/modules/webhooks.ts + checksum: 11ca5c4e0e1887ea1629ae4a1a762dc47a0e01f5d0f8096ee36e61183a959107 + - filename: packages/contentstack-export/src/utils/export-config-handler.ts + checksum: 94e83a42ad4150ccfb6c02f6f4fac59e9fd6f58a31988b919a6ff6e027afa805 + - filename: packages/contentstack-export/src/export/modules/workflows.ts + checksum: ef3d6e36cc07eca762f94c5f7f68c5c0d49e884b6099e81a1830249cac24a287 + - filename: packages/contentstack-export/src/types/default-config.ts + checksum: 0cc62919207384ec710ea3f8a3445d6e5bd78cc2c5306b9e74aaeec688eb028d + - filename: packages/contentstack-export/src/export/modules/custom-roles.ts + checksum: 8a0cdd00b048fb6c5c8990cc881a324229e225970ec78ce5861da63fb3a875b4 + - filename: packages/contentstack-export/src/export/modules/assets.ts + checksum: 7d64a43878f19da561da4159271873035752587a016eb7af0bb8a5592740da9d + - filename: packages/contentstack-export/src/export/modules/publishing-rules.ts + checksum: 4a4278d29878fc3627f216ee168a0896cca7644bc06f4e983f4ae0b25fefabb7 + - filename: packages/contentstack-export/src/config/index.ts + checksum: 2c811d2bd7b6657b567fd120cfaf05306ca751109c070bf7b49c18d06b211764 + - filename: packages/contentstack-export/src/export/modules/locales.ts + checksum: 7226915d3e9f69111bf6f3a669edd28f55167fdc86a3b1d7583e3986825aa0e5 + - filename: packages/contentstack-export/src/export/modules/labels.ts + checksum: 1c970c204c6ff78fe66151352263cbb24eb86d2c7cb2e0050d1734dd002425ef + - filename: packages/contentstack-export/src/export/modules/extensions.ts + checksum: a08f2f63a13e9c41bac3c84ca52ea3ca1a147ca548e4e66ed682c320b7a830a8 + - filename: packages/contentstack-export/src/export/modules/entries.ts + checksum: 691df8e31ba2a2a719ea46f1b3a0e7abe0b90355f4e91f211956189dd12aa403 + - filename: packages/contentstack-export/src/export/modules/stack.ts + checksum: 316c172556694cc5421c0aca1c9470c3aaa588a87922812322a85d11816a1c90 version: '1.0' diff --git a/packages/contentstack-export/src/config/index.ts b/packages/contentstack-export/src/config/index.ts index 06b931dc3..e3c4d12a2 100644 --- a/packages/contentstack-export/src/config/index.ts +++ b/packages/contentstack-export/src/config/index.ts @@ -1,30 +1,17 @@ import { DefaultConfig } from '../types'; const config: DefaultConfig = { - apis: { - assets: '/assets/', - content_types: '/content_types/', - entries: '/entries/', - environments: '/environments/', - extension: '/extensions', - globalfields: '/global_fields/', - labels: '/labels/', - locales: '/locales/', - stacks: '/stacks/', - userSession: '/user-session/', - users: '/stacks', - webhooks: '/webhooks/', - }, contentVersion: 2, - developerHubBaseUrl: '', + versioning: false, + host: 'https://api.contentstack.io/v3', developerHubUrls: { // NOTE CDA url used as developer-hub url mapper to avoid conflict if user used any custom name 'https://api.contentstack.io': 'https://developerhub-api.contentstack.com', - 'https://azure-eu-api.contentstack.com': 'https://azure-eu-developerhub-api.contentstack.com', - 'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com', 'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com', - 'https://gcp-eu-api.contentstack.com': 'https://gcp-eu-developerhub-api.contentstack.com', + 'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com', + 'https://azure-eu-api.contentstack.com': 'https://azure-eu-developerhub-api.contentstack.com', 'https://gcp-na-api.contentstack.com': 'https://gcp-na-developerhub-api.contentstack.com', + 'https://gcp-eu-api.contentstack.com': 'https://gcp-eu-developerhub-api.contentstack.com', }, // use below hosts for eu region // host:'https://eu-api.contentstack.com/v3', @@ -35,303 +22,119 @@ const config: DefaultConfig = { // use below hosts for gcp-na region // host: 'https://gcp-na-api.contentstack.com' // use below hosts for gcp-eu region - fetchConcurrency: 5, - host: 'https://api.contentstack.io/v3', - languagesCode: [ - 'af-za', - 'sq-al', - 'ar', - 'ar-dz', - 'ar-bh', - 'ar-eg', - 'ar-iq', - 'ar-jo', - 'ar-kw', - 'ar-lb', - 'ar-ly', - 'ar-ma', - 'ar-om', - 'ar-qa', - 'ar-sa', - 'ar-sy', - 'ar-tn', - 'ar-ae', - 'ar-ye', - 'hy-am', - 'az', - 'cy-az-az', - 'lt-az-az', - 'eu-es', - 'be-by', - 'bs', - 'bg-bg', - 'ca-es', - 'zh', - 'zh-au', - 'zh-cn', - 'zh-hk', - 'zh-mo', - 'zh-my', - 'zh-sg', - 'zh-tw', - 'zh-chs', - 'zh-cht', - 'hr-hr', - 'cs', - 'cs-cz', - 'da-dk', - 'div-mv', - 'nl', - 'nl-be', - 'nl-nl', - 'en', - 'en-au', - 'en-at', - 'en-be', - 'en-bz', - 'en-ca', - 'en-cb', - 'en-cn', - 'en-cz', - 'en-dk', - 'en-do', - 'en-ee', - 'en-fi', - 'en-fr', - 'en-de', - 'en-gr', - 'en-hk', - 'en-hu', - 'en-in', - 'en-id', - 'en-ie', - 'en-it', - 'en-jm', - 'en-jp', - 'en-kr', - 'en-lv', - 'en-lt', - 'en-lu', - 'en-my', - 'en-mx', - 'en-nz', - 'en-no', - 'en-ph', - 'en-pl', - 'en-pt', - 'en-pr', - 'en-ru', - 'en-sg', - 'en-sk', - 'en-si', - 'en-za', - 'en-es', - 'en-se', - 'en-ch', - 'en-th', - 'en-nl', - 'en-tt', - 'en-gb', - 'en-us', - 'en-zw', - 'et-ee', - 'fo-fo', - 'fa-ir', - 'fi', - 'fi-fi', - 'fr', - 'fr-be', - 'fr-ca', - 'fr-fr', - 'fr-lu', - 'fr-mc', - 'fr-ch', - 'fr-us', - 'gd', - 'gl-es', - 'ka-ge', - 'de', - 'de-at', - 'de-de', - 'de-li', - 'de-lu', - 'de-ch', - 'el-gr', - 'gu-in', - 'he-il', - 'hi-in', - 'hu-hu', - 'is-is', - 'id-id', - 'it', - 'it-it', - 'it-ch', - 'ja', - 'ja-jp', - 'kn-in', - 'kk-kz', - 'km-kh', - 'kok-in', - 'ko', - 'ko-kr', - 'ky-kz', - 'lv-lv', - 'lt-lt', - 'mk-mk', - 'ms', - 'ms-bn', - 'ms-my', - 'ms-sg', - 'mt', - 'mr-in', - 'mn-mn', - 'no', - 'no-no', - 'nb-no', - 'nn-no', - 'pl-pl', - 'pt', - 'pt-br', - 'pt-pt', - 'pa-in', - 'ro-ro', - 'ru', - 'ru-kz', - 'ru-ru', - 'ru-ua', - 'sa-in', - 'cy-sr-sp', - 'lt-sr-sp', - 'sr-me', - 'sk-sk', - 'sl-si', - 'es', - 'es-ar', - 'es-bo', - 'es-cl', - 'es-co', - 'es-cr', - 'es-do', - 'es-ec', - 'es-sv', - 'es-gt', - 'es-hn', - 'es-419', - 'es-mx', - 'es-ni', - 'es-pa', - 'es-py', - 'es-pe', - 'es-pr', - 'es-es', - 'es-us', - 'es-uy', - 'es-ve', - 'sw-ke', - 'sv', - 'sv-fi', - 'sv-se', - 'syr-sy', - 'tl', - 'ta-in', - 'tt-ru', - 'te-in', - 'th-th', - 'tr-tr', - 'uk-ua', - 'ur-pk', - 'uz', - 'cy-uz-uz', - 'lt-uz-uz', - 'vi-vn', - 'xh', - 'zu', - ], - marketplaceAppEncryptionKey: 'nF2ejRQcTv', // host: 'https://gcp-eu-api.contentstack.com' modules: { - assets: { - assetsMetaKeys: [], // Default keys ['uid', 'url', 'filename'] - // This is the total no. of asset objects fetched in each 'get assets' call - batchLimit: 20, - // no of asset version files (of a single asset) that'll be downloaded parallel - chunkFileSize: 1, // measured on Megabits (5mb) - dirName: 'assets', - displayExecutionTime: false, - downloadLimit: 5, - enableDownloadStatus: false, - fetchConcurrency: 5, - fileName: 'assets.json', - host: 'https://images.contentstack.io', - includeVersionedAssets: false, - invalidKeys: ['created_at', 'updated_at', 'created_by', 'updated_by', '_metadata', 'published'], - securedAssets: false, - }, - attributes: { - dirName: 'attributes', - fileName: 'attributes.json', - invalidKeys: [ - 'updatedAt', - 'createdBy', - 'updatedBy', - '_id', - 'createdAt', - 'createdByUserName', - 'updatedByUserName', - ], + types: [ + 'stack', + 'assets', + 'locales', + 'environments', + 'extensions', + 'webhooks', + 'taxonomies', + 'global-fields', + 'content-types', + 'custom-roles', + 'workflows', + 'publishing-rules', + 'personalize', + 'entries', + 'labels', + 'marketplace-apps', + 'composable-studio', + ], + locales: { + dirName: 'locales', + fileName: 'locales.json', + requiredKeys: ['code', 'uid', 'name', 'fallback_locale'], }, - audiences: { - dirName: 'audiences', - fileName: 'audiences.json', - invalidKeys: [ - 'updatedAt', - 'createdBy', - 'updatedBy', - '_id', - 'createdAt', - 'createdByUserName', - 'updatedByUserName', - ], + masterLocale: { + dirName: 'locales', + fileName: 'master-locale.json', + requiredKeys: ['code', 'uid', 'name'], }, - 'composable-studio': { - apiBaseUrl: 'https://composable-studio-api.contentstack.com', - apiVersion: 'v1', - dirName: 'composable_studio', - fileName: 'composable_studio.json', + customRoles: { + dirName: 'custom-roles', + fileName: 'custom-roles.json', + customRolesLocalesFileName: 'custom-roles-locales.json', + }, + 'custom-roles': { + dirName: 'custom-roles', + fileName: 'custom-roles.json', + customRolesLocalesFileName: 'custom-roles-locales.json', + }, + environments: { + dirName: 'environments', + fileName: 'environments.json', + }, + labels: { + dirName: 'labels', + fileName: 'labels.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, + webhooks: { + dirName: 'webhooks', + fileName: 'webhooks.json', + }, + releases: { + dirName: 'releases', + fileName: 'releases.json', + releasesList: 'releasesList.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, + workflows: { + dirName: 'workflows', + fileName: 'workflows.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, + 'publishing-rules': { + dirName: 'workflows', + fileName: 'publishing-rules.json', + invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + }, + globalfields: { + dirName: 'global_fields', + fileName: 'globalfields.json', + validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], + }, + 'global-fields': { + dirName: 'global_fields', + fileName: 'globalfields.json', + validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], + }, + assets: { + dirName: 'assets', + fileName: 'assets.json', + // This is the total no. of asset objects fetched in each 'get assets' call + batchLimit: 20, + host: 'https://images.contentstack.io', + invalidKeys: ['created_at', 'updated_at', 'created_by', 'updated_by', '_metadata', 'published'], + // no of asset version files (of a single asset) that'll be downloaded parallel + chunkFileSize: 1, // measured on Megabits (5mb) + downloadLimit: 5, + fetchConcurrency: 5, + assetsMetaKeys: [], // Default keys ['uid', 'url', 'filename'] + securedAssets: false, + displayExecutionTime: false, + enableDownloadStatus: false, + includeVersionedAssets: false, }, content_types: { dirName: 'content_types', fileName: 'content_types.json', + validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], // total no of content types fetched in each 'get content types' call limit: 100, - validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], }, 'content-types': { dirName: 'content_types', fileName: 'content_types.json', + validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], // total no of content types fetched in each 'get content types' call limit: 100, - validKeys: ['title', 'uid', 'field_rules', 'schema', 'options', 'singleton', 'description'], - }, - 'custom-roles': { - customRolesLocalesFileName: 'custom-roles-locales.json', - dirName: 'custom-roles', - fileName: 'custom-roles.json', - }, - customRoles: { - customRolesLocalesFileName: 'custom-roles-locales.json', - dirName: 'custom-roles', - fileName: 'custom-roles.json', - }, - dependency: { - entries: ['stack', 'locales', 'content-types'], }, entries: { - batchLimit: 20, - dependencies: ['locales', 'content-types'], dirName: 'entries', - downloadLimit: 5, - exportVersions: false, fileName: 'entries.json', invalidKeys: [ 'stackHeaders', @@ -344,64 +147,29 @@ const config: DefaultConfig = { '_metadata', 'published', ], + batchLimit: 20, + downloadLimit: 5, // total no of entries fetched in each content type in a single call limit: 100, - }, - environments: { - dirName: 'environments', - fileName: 'environments.json', - }, - events: { - dirName: 'events', - fileName: 'events.json', - invalidKeys: [ - 'updatedAt', - 'createdBy', - 'updatedBy', - '_id', - 'createdAt', - 'createdByUserName', - 'updatedByUserName', - ], - }, - extensions: { - dirName: 'extensions', - fileName: 'extensions.json', - }, - 'global-fields': { - dirName: 'global_fields', - fileName: 'globalfields.json', - validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], - }, - globalfields: { - dirName: 'global_fields', - fileName: 'globalfields.json', - validKeys: ['title', 'uid', 'schema', 'options', 'singleton', 'description'], - }, - labels: { - dirName: 'labels', - fileName: 'labels.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], - }, - locales: { - dirName: 'locales', - fileName: 'locales.json', - requiredKeys: ['code', 'uid', 'name', 'fallback_locale'], - }, - marketplace_apps: { - dirName: 'marketplace_apps', - fileName: 'marketplace_apps.json', - }, - 'marketplace-apps': { - dirName: 'marketplace_apps', - fileName: 'marketplace_apps.json', - }, - masterLocale: { - dirName: 'locales', - fileName: 'master-locale.json', - requiredKeys: ['code', 'uid', 'name'], + dependencies: ['locales', 'content-types'], + exportVersions: false, }, personalize: { + baseURL: { + 'AWS-NA': 'https://personalize-api.contentstack.com', + 'AWS-EU': 'https://eu-personalize-api.contentstack.com', + 'AWS-AU': 'https://au-personalize-api.contentstack.com', + 'AZURE-NA': 'https://azure-na-personalize-api.contentstack.com', + 'AZURE-EU': 'https://azure-eu-personalize-api.contentstack.com', + 'GCP-NA': 'https://gcp-na-personalize-api.contentstack.com', + 'GCP-EU': 'https://gcp-eu-personalize-api.contentstack.com', + }, + dirName: 'personalize', + exportOrder: ['attributes', 'audiences', 'events', 'experiences'], + projects: { + dirName: 'projects', + fileName: 'projects.json', + }, attributes: { dirName: 'attributes', fileName: 'attributes.json', @@ -410,16 +178,6 @@ const config: DefaultConfig = { dirName: 'audiences', fileName: 'audiences.json', }, - baseURL: { - 'AWS-AU': 'https://au-personalize-api.contentstack.com', - 'AWS-EU': 'https://eu-personalize-api.contentstack.com', - 'AWS-NA': 'https://personalize-api.contentstack.com', - 'AZURE-EU': 'https://azure-eu-personalize-api.contentstack.com', - 'AZURE-NA': 'https://azure-na-personalize-api.contentstack.com', - 'GCP-EU': 'https://gcp-eu-personalize-api.contentstack.com', - 'GCP-NA': 'https://gcp-na-personalize-api.contentstack.com', - }, - dirName: 'personalize', events: { dirName: 'events', fileName: 'events.json', @@ -428,81 +186,323 @@ const config: DefaultConfig = { dirName: 'experiences', fileName: 'experiences.json', }, - exportOrder: ['attributes', 'audiences', 'events', 'experiences'], - projects: { - dirName: 'projects', - fileName: 'projects.json', - }, }, - 'publishing-rules': { - dirName: 'workflows', - fileName: 'publishing-rules.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + variantEntry: { + serveMockData: false, + dirName: 'variants', + fileName: 'index.json', + chunkFileSize: 1, + query: { + skip: 0, + limit: 100, + include_variant: false, + include_count: true, + include_publish_details: true, + }, + mockDataPath: './variant-mock-data.json', }, - releases: { - dirName: 'releases', - fileName: 'releases.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], - releasesList: 'releasesList.json', + extensions: { + dirName: 'extensions', + fileName: 'extensions.json', }, stack: { dirName: 'stack', fileName: 'stack.json', }, - taxonomies: { - dirName: 'taxonomies', - fileName: 'taxonomies.json', - invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath', 'created_at'], + dependency: { + entries: ['stack', 'locales', 'content-types'], + }, + marketplace_apps: { + dirName: 'marketplace_apps', + fileName: 'marketplace_apps.json', + }, + 'marketplace-apps': { + dirName: 'marketplace_apps', + fileName: 'marketplace_apps.json', + }, + 'composable-studio': { + dirName: 'composable_studio', + fileName: 'composable_studio.json', + apiBaseUrl: 'https://composable-studio-api.contentstack.com', + apiVersion: 'v1', + }, + taxonomies: { + dirName: 'taxonomies', + fileName: 'taxonomies.json', + invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath', 'created_at'], limit: 100, }, - types: [ - 'stack', - 'assets', - 'locales', - 'environments', - 'extensions', - 'webhooks', - 'taxonomies', - 'global-fields', - 'content-types', - 'custom-roles', - 'workflows', - 'publishing-rules', - 'personalize', - 'entries', - 'labels', - 'marketplace-apps', - 'composable-studio', - ], - variantEntry: { - chunkFileSize: 1, - dirName: 'variants', - fileName: 'index.json', - mockDataPath: './variant-mock-data.json', - query: { - include_count: true, - include_publish_details: true, - include_variant: false, - limit: 100, - skip: 0, - }, - serveMockData: false, + events: { + dirName: 'events', + fileName: 'events.json', + invalidKeys: [ + 'updatedAt', + 'createdBy', + 'updatedBy', + '_id', + 'createdAt', + 'createdByUserName', + 'updatedByUserName', + ], }, - webhooks: { - dirName: 'webhooks', - fileName: 'webhooks.json', + audiences: { + dirName: 'audiences', + fileName: 'audiences.json', + invalidKeys: [ + 'updatedAt', + 'createdBy', + 'updatedBy', + '_id', + 'createdAt', + 'createdByUserName', + 'updatedByUserName', + ], }, - workflows: { - dirName: 'workflows', - fileName: 'workflows.json', - invalidKeys: ['stackHeaders', 'urlPath', 'created_at', 'updated_at', 'created_by', 'updated_by'], + attributes: { + dirName: 'attributes', + fileName: 'attributes.json', + invalidKeys: [ + 'updatedAt', + 'createdBy', + 'updatedBy', + '_id', + 'createdAt', + 'createdByUserName', + 'updatedByUserName', + ], }, }, - onlyTSModules: ['taxonomies'], - personalizationEnabled: false, + languagesCode: [ + 'af-za', + 'sq-al', + 'ar', + 'ar-dz', + 'ar-bh', + 'ar-eg', + 'ar-iq', + 'ar-jo', + 'ar-kw', + 'ar-lb', + 'ar-ly', + 'ar-ma', + 'ar-om', + 'ar-qa', + 'ar-sa', + 'ar-sy', + 'ar-tn', + 'ar-ae', + 'ar-ye', + 'hy-am', + 'az', + 'cy-az-az', + 'lt-az-az', + 'eu-es', + 'be-by', + 'bs', + 'bg-bg', + 'ca-es', + 'zh', + 'zh-au', + 'zh-cn', + 'zh-hk', + 'zh-mo', + 'zh-my', + 'zh-sg', + 'zh-tw', + 'zh-chs', + 'zh-cht', + 'hr-hr', + 'cs', + 'cs-cz', + 'da-dk', + 'div-mv', + 'nl', + 'nl-be', + 'nl-nl', + 'en', + 'en-au', + 'en-at', + 'en-be', + 'en-bz', + 'en-ca', + 'en-cb', + 'en-cn', + 'en-cz', + 'en-dk', + 'en-do', + 'en-ee', + 'en-fi', + 'en-fr', + 'en-de', + 'en-gr', + 'en-hk', + 'en-hu', + 'en-in', + 'en-id', + 'en-ie', + 'en-it', + 'en-jm', + 'en-jp', + 'en-kr', + 'en-lv', + 'en-lt', + 'en-lu', + 'en-my', + 'en-mx', + 'en-nz', + 'en-no', + 'en-ph', + 'en-pl', + 'en-pt', + 'en-pr', + 'en-ru', + 'en-sg', + 'en-sk', + 'en-si', + 'en-za', + 'en-es', + 'en-se', + 'en-ch', + 'en-th', + 'en-nl', + 'en-tt', + 'en-gb', + 'en-us', + 'en-zw', + 'et-ee', + 'fo-fo', + 'fa-ir', + 'fi', + 'fi-fi', + 'fr', + 'fr-be', + 'fr-ca', + 'fr-fr', + 'fr-lu', + 'fr-mc', + 'fr-ch', + 'fr-us', + 'gd', + 'gl-es', + 'ka-ge', + 'de', + 'de-at', + 'de-de', + 'de-li', + 'de-lu', + 'de-ch', + 'el-gr', + 'gu-in', + 'he-il', + 'hi-in', + 'hu-hu', + 'is-is', + 'id-id', + 'it', + 'it-it', + 'it-ch', + 'ja', + 'ja-jp', + 'kn-in', + 'kk-kz', + 'km-kh', + 'kok-in', + 'ko', + 'ko-kr', + 'ky-kz', + 'lv-lv', + 'lt-lt', + 'mk-mk', + 'ms', + 'ms-bn', + 'ms-my', + 'ms-sg', + 'mt', + 'mr-in', + 'mn-mn', + 'no', + 'no-no', + 'nb-no', + 'nn-no', + 'pl-pl', + 'pt', + 'pt-br', + 'pt-pt', + 'pa-in', + 'ro-ro', + 'ru', + 'ru-kz', + 'ru-ru', + 'ru-ua', + 'sa-in', + 'cy-sr-sp', + 'lt-sr-sp', + 'sr-me', + 'sk-sk', + 'sl-si', + 'es', + 'es-ar', + 'es-bo', + 'es-cl', + 'es-co', + 'es-cr', + 'es-do', + 'es-ec', + 'es-sv', + 'es-gt', + 'es-hn', + 'es-419', + 'es-mx', + 'es-ni', + 'es-pa', + 'es-py', + 'es-pe', + 'es-pr', + 'es-es', + 'es-us', + 'es-uy', + 'es-ve', + 'sw-ke', + 'sv', + 'sv-fi', + 'sv-se', + 'syr-sy', + 'tl', + 'ta-in', + 'tt-ru', + 'te-in', + 'th-th', + 'tr-tr', + 'uk-ua', + 'ur-pk', + 'uz', + 'cy-uz-uz', + 'lt-uz-uz', + 'vi-vn', + 'xh', + 'zu', + ], + apis: { + userSession: '/user-session/', + globalfields: '/global_fields/', + locales: '/locales/', + labels: '/labels/', + environments: '/environments/', + assets: '/assets/', + content_types: '/content_types/', + entries: '/entries/', + users: '/stacks', + extension: '/extensions', + webhooks: '/webhooks/', + stacks: '/stacks/', + }, preserveStackVersion: false, - versioning: false, + personalizationEnabled: false, + fetchConcurrency: 5, writeConcurrency: 5, + developerHubBaseUrl: '', + marketplaceAppEncryptionKey: 'nF2ejRQcTv', + onlyTSModules: ['taxonomies'], }; export default config; diff --git a/packages/contentstack-export/src/export/module-exporter.ts b/packages/contentstack-export/src/export/module-exporter.ts index 02077334a..0cd1a8bea 100644 --- a/packages/contentstack-export/src/export/module-exporter.ts +++ b/packages/contentstack-export/src/export/module-exporter.ts @@ -1,22 +1,19 @@ +import * as path from 'path'; import { ContentstackClient, - getBranchFromAlias, handleAndLogError, - log, messageHandler, + log, + getBranchFromAlias, } from '@contentstack/cli-utilities'; -import * as path from 'path'; - -import { ExportConfig, Modules } from '../types'; import { setupBranches, setupExportDir, writeExportMetaFile } from '../utils'; import startModuleExport from './modules'; -// CJS: modules-js/index.js uses module.exports (no ESM default) -// eslint-disable-next-line import/default -- resolved at runtime via module.exports import startJSModuleExport from './modules-js'; +import { ExportConfig, Modules } from '../types'; class ModuleExporter { - private exportConfig: ExportConfig; private managementAPIClient: ContentstackClient; + private exportConfig: ExportConfig; private stackAPIClient: ReturnType; constructor(managementAPIClient: ContentstackClient, exportConfig: ExportConfig) { @@ -28,19 +25,22 @@ class ModuleExporter { this.exportConfig = exportConfig; } - async export() { - log.info(`Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context); - // checks for single module or all modules - if (this.exportConfig.singleModuleExport) { - return this.exportSingleModule(this.exportConfig.moduleName); - } - return this.exportAllModules(); - } - - async exportAllModules(): Promise { - // use the algorithm to determine the parallel and sequential execution of modules - for (const moduleName of this.exportConfig.modules.types) { - await this.exportByModuleByName(moduleName); + async start(): Promise { + // setup the branches + try { + if (!this.exportConfig.branchName && this.exportConfig.branchAlias) { + this.exportConfig.branchName = await getBranchFromAlias(this.stackAPIClient, this.exportConfig.branchAlias); + } + await setupBranches(this.exportConfig, this.stackAPIClient); + await setupExportDir(this.exportConfig); + // if branches available run it export by branches + if (this.exportConfig.branches) { + this.exportConfig.branchEnabled = true; + return this.exportByBranches(); + } + return this.export(); + } catch (error) { + throw error; } } @@ -66,6 +66,15 @@ class ModuleExporter { } } + async export() { + log.info(`Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context); + // checks for single module or all modules + if (this.exportConfig.singleModuleExport) { + return this.exportSingleModule(this.exportConfig.moduleName); + } + return this.exportAllModules(); + } + async exportByModuleByName(moduleName: Modules) { log.info(`Exporting module: '${moduleName}'...`, this.exportConfig.context); // export the modules by name @@ -73,17 +82,17 @@ class ModuleExporter { let exportedModuleResponse; if (this.exportConfig.contentVersion === 2) { exportedModuleResponse = await startModuleExport({ + stackAPIClient: this.stackAPIClient, exportConfig: this.exportConfig, moduleName, - stackAPIClient: this.stackAPIClient, }); } else { //NOTE - new modules support only ts if (this.exportConfig.onlyTSModules.indexOf(moduleName) === -1) { exportedModuleResponse = await startJSModuleExport({ + stackAPIClient: this.stackAPIClient, exportConfig: this.exportConfig, moduleName, - stackAPIClient: this.stackAPIClient, }); } } @@ -117,22 +126,10 @@ class ModuleExporter { } } - async start(): Promise { - // setup the branches - try { - if (!this.exportConfig.branchName && this.exportConfig.branchAlias) { - this.exportConfig.branchName = await getBranchFromAlias(this.stackAPIClient, this.exportConfig.branchAlias); - } - await setupBranches(this.exportConfig, this.stackAPIClient); - await setupExportDir(this.exportConfig); - // if branches available run it export by branches - if (this.exportConfig.branches) { - this.exportConfig.branchEnabled = true; - return this.exportByBranches(); - } - return this.export(); - } catch (error) { - throw error; + async exportAllModules(): Promise { + // use the algorithm to determine the parallel and sequential execution of modules + for (const moduleName of this.exportConfig.modules.types) { + await this.exportByModuleByName(moduleName); } } } diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 35b193f0e..1a95d5f25 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -1,34 +1,34 @@ -import { - FsUtility, - configHandler, - getDirectories, - handleAndLogError, - log, - messageHandler, -} from '@contentstack/cli-utilities'; +import map from 'lodash/map'; import chunk from 'lodash/chunk'; -import entries from 'lodash/entries'; -import filter from 'lodash/filter'; import first from 'lodash/first'; -import includes from 'lodash/includes'; -import isEmpty from 'lodash/isEmpty'; -import map from 'lodash/map'; import merge from 'lodash/merge'; +import filter from 'lodash/filter'; import uniqBy from 'lodash/uniqBy'; import values from 'lodash/values'; +import entries from 'lodash/entries'; +import isEmpty from 'lodash/isEmpty'; +import includes from 'lodash/includes'; +import progress from 'progress-stream'; import { createWriteStream } from 'node:fs'; import { resolve as pResolve } from 'node:path'; -import progress from 'progress-stream'; +import { + FsUtility, + getDirectories, + configHandler, + log, + handleAndLogError, + messageHandler, +} from '@contentstack/cli-utilities'; import config from '../../config'; import { ModuleClassParams } from '../../types'; import BaseClass, { CustomPromiseHandler, CustomPromiseHandlerInput } from './base-class'; export default class ExportAssets extends BaseClass { + private assetsRootPath: string; public assetConfig = config.modules.assets; - public versionedAssets: Record[] = []; private assetsFolder: Record[] = []; - private assetsRootPath: string; + public versionedAssets: Record[] = []; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -37,120 +37,85 @@ export default class ExportAssets extends BaseClass { get commonQueryParam(): Record { return { + skip: 0, asc: 'created_at', include_count: false, - skip: 0, }; } - /** - * @method downloadAssets - * @returns Promise - */ - async downloadAssets(): Promise { - const fs: FsUtility = new FsUtility({ - basePath: this.assetsRootPath, - createDirIfNotExist: false, - fileExt: 'json', - }); + async start(): Promise { + this.assetsRootPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.assetConfig.dirName, + ); - log.debug('Reading asset metadata for download...', this.exportConfig.context); - const assetsMetaData = fs.getPlainMeta(); + log.debug(`Assets root path resolved to: ${this.assetsRootPath}`, this.exportConfig.context); + log.debug('Fetching assets and folders count...', this.exportConfig.context); + // NOTE step 1: Get assets and it's folder count in parallel + const [assetsCount, assetsFolderCount] = await Promise.all([this.getAssetsCount(), this.getAssetsCount(true)]); - let listOfAssets = values(assetsMetaData).flat(); + log.debug('Fetching assets and folders data...', this.exportConfig.context); + // NOTE step 2: Get assets and it's folder data in parallel + await Promise.all([this.getAssetsFolders(assetsFolderCount), this.getAssets(assetsCount)]); - if (this.assetConfig.includeVersionedAssets) { - const versionedAssetsMetaData = fs.getPlainMeta(pResolve(this.assetsRootPath, 'versions', 'metadata.json')); - listOfAssets.push(...values(versionedAssetsMetaData).flat()); + // NOTE step 3: Get versioned assets + if (!isEmpty(this.versionedAssets) && this.assetConfig.includeVersionedAssets) { + log.debug('Fetching versioned assets metadata...', this.exportConfig.context); + await this.getVersionedAssets(); } - listOfAssets = uniqBy(listOfAssets, 'url'); - log.debug(`Total unique assets to download: ${listOfAssets.length}`, this.exportConfig.context); - - const apiBatches: Array = chunk(listOfAssets, this.assetConfig.downloadLimit); - const downloadedAssetsDirs = await getDirectories(pResolve(this.assetsRootPath, 'files')); + log.debug('Starting download of all assets...', this.exportConfig.context); + // NOTE step 4: Download all assets + await this.downloadAssets(); - const onSuccess = ({ additionalInfo, response: { data } }: any) => { - const { asset } = additionalInfo; - const assetFolderPath = pResolve(this.assetsRootPath, 'files', asset.uid); - const assetFilePath = pResolve(assetFolderPath, asset.filename); + log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); + } - log.debug(`Saving asset to: ${assetFilePath}`, this.exportConfig.context); + /** + * @method getAssetsFolders + * @param {number} totalCount number + * @returns Promise + */ + getAssetsFolders(totalCount: number | void): Promise | void> { + if (!totalCount) return Promise.resolve(); - if (!includes(downloadedAssetsDirs, asset.uid)) { - fs.createFolderIfNotExist(assetFolderPath); - } + const queryParam = { + ...this.commonQueryParam, + query: { is_dir: true }, + }; - const assetWriterStream = createWriteStream(assetFilePath); - assetWriterStream.on('error', (error) => { - handleAndLogError( - error, - { ...this.exportConfig.context, filename: asset.fileName, uid: asset.uid }, - messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), - ); - }); - /** - * NOTE if pipe not working as expected add the following code below to fix the issue - * https://oramind.com/using-streams-efficiently-in-nodejs/ - * import * as stream from "stream"; - * import { promisify } from "util"; - * const finished = promisify(stream.finished); - * await finished(assetWriterStream); - */ - if (this.assetConfig.enableDownloadStatus) { - const str = progress({ - length: data.headers['content-length'], - time: 5000, - }); - str.on('progress', function (progressData) { - console.log(`${asset.filename}: ${Math.round(progressData.percentage)}%`); - }); - data.pipe(str).pipe(assetWriterStream); - } else { - data.pipe(assetWriterStream); - } + log.debug(`Fetching asset folders with query: ${JSON.stringify(queryParam)}`, this.exportConfig.context); - log.success(messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), this.exportConfig.context); + const onSuccess = ({ response: { items } }: any) => { + log.debug(`Fetched ${items?.length || 0} asset folders`, this.exportConfig.context); + if (!isEmpty(items)) this.assetsFolder.push(...items); }; - const onReject = ({ additionalInfo, error }: any) => { - const { asset } = additionalInfo; - handleAndLogError( - error, - { ...this.exportConfig.context, filename: asset.filename, uid: asset.uid }, - messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), - ); + const onReject = ({ error }: any) => { + handleAndLogError(error, { ...this.exportConfig.context }); }; - const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { - const { batchIndex, index } = input; - const asset: any = apiBatches[batchIndex][index]; - const url = this.assetConfig.securedAssets - ? `${asset.url}?authtoken=${configHandler.get('authtoken')}` - : asset.url; - log.debug( - `Preparing to download asset: ${asset.filename} (UID: ${asset.uid}) from URL: ${url}`, - this.exportConfig.context, - ); - return this.makeAPICall({ - additionalInfo: { asset }, - module: 'download-asset', + return this.makeConcurrentCall({ + totalCount, + apiParams: { + queryParam, + module: 'assets', reject: onReject, resolve: onSuccess, - url: encodeURI(url), - }); - }; - - return this.makeConcurrentCall( - { - apiBatches, - concurrencyLimit: this.assetConfig.downloadLimit, - module: 'assets download', - totalCount: listOfAssets.length, }, - promisifyHandler, - ).then(() => { - log.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), this.exportConfig.context); + module: 'assets folders', + concurrencyLimit: this.assetConfig.fetchConcurrency, + }).then(() => { + if (!isEmpty(this.assetsFolder)) { + const path = pResolve(this.assetsRootPath, 'folders.json'); + log.debug(`Writing asset folders to ${path}`, this.exportConfig.context); + new FsUtility({ basePath: this.assetsRootPath }).writeFile(path, this.assetsFolder); + } + log.info( + messageHandler.parse('ASSET_FOLDERS_EXPORT_COMPLETE', this.assetsFolder.length), + this.exportConfig.context, + ); }); } @@ -169,8 +134,8 @@ export default class ExportAssets extends BaseClass { const queryParam = { ...this.commonQueryParam, - except: { BASE: this.assetConfig.invalidKeys }, include_publish_details: true, + except: { BASE: this.assetConfig.invalidKeys }, }; this.applyQueryFilters(queryParam, 'assets'); @@ -180,7 +145,7 @@ export default class ExportAssets extends BaseClass { log.debug(`Found ${versionAssets.length} versioned assets`, this.exportConfig.context); if (!isEmpty(versionAssets)) { this.versionedAssets.push( - ...map(versionAssets, ({ _version, uid }: any) => ({ + ...map(versionAssets, ({ uid, _version }: any) => ({ [uid]: _version, })), ); @@ -198,12 +163,12 @@ export default class ExportAssets extends BaseClass { if (!fs && !isEmpty(items)) { log.debug('Initializing FsUtility for writing assets metadata', this.exportConfig.context); fs = new FsUtility({ + metaHandler, + moduleName: 'assets', + indexFileName: 'assets.json', basePath: this.assetsRootPath, chunkFileSize: this.assetConfig.chunkFileSize, - indexFileName: 'assets.json', - metaHandler, metaPickKeys: merge(['uid', 'url', 'filename', 'parent_uid'], this.assetConfig.assetsMetaKeys), - moduleName: 'assets', }); } if (!isEmpty(items)) { @@ -213,94 +178,20 @@ export default class ExportAssets extends BaseClass { }; return this.makeConcurrentCall({ - apiParams: { - module: 'assets', - queryParam, - reject: onReject, - resolve: onSuccess, - }, - concurrencyLimit: this.assetConfig.fetchConcurrency, module: 'assets', totalCount, - }).then(() => { - fs?.completeFile(true); - log.info(messageHandler.parse('ASSET_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); - }); - } - - getAssetsCount(isDir = false): Promise { - const queryParam: any = { - limit: 1, - ...this.commonQueryParam, - skip: 10 ** 100, - }; - - if (isDir) queryParam.query = { is_dir: true }; - - log.debug( - `Querying count of assets${isDir ? ' (folders only)' : ''} with params: ${JSON.stringify(queryParam)}`, - this.exportConfig.context, - ); - - return this.stack - .asset() - .query(queryParam) - .count() - .then(({ assets }: any) => { - log.debug(`Received asset count: ${assets}`, this.exportConfig.context); - return assets; - }) - .catch((error: Error) => { - handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_COUNT_QUERY_FAILED')); - }); - } - /** - * @method getAssetsFolders - * @param {number} totalCount number - * @returns Promise - */ - getAssetsFolders(totalCount: number | void): Promise | void> { - if (!totalCount) return Promise.resolve(); - - const queryParam = { - ...this.commonQueryParam, - query: { is_dir: true }, - }; - - log.debug(`Fetching asset folders with query: ${JSON.stringify(queryParam)}`, this.exportConfig.context); - - const onSuccess = ({ response: { items } }: any) => { - log.debug(`Fetched ${items?.length || 0} asset folders`, this.exportConfig.context); - if (!isEmpty(items)) this.assetsFolder.push(...items); - }; - - const onReject = ({ error }: any) => { - handleAndLogError(error, { ...this.exportConfig.context }); - }; - - return this.makeConcurrentCall({ apiParams: { - module: 'assets', queryParam, + module: 'assets', reject: onReject, resolve: onSuccess, }, concurrencyLimit: this.assetConfig.fetchConcurrency, - module: 'assets folders', - totalCount, }).then(() => { - if (!isEmpty(this.assetsFolder)) { - const path = pResolve(this.assetsRootPath, 'folders.json'); - log.debug(`Writing asset folders to ${path}`, this.exportConfig.context); - new FsUtility({ basePath: this.assetsRootPath }).writeFile(path, this.assetsFolder); - } - log.info( - messageHandler.parse('ASSET_FOLDERS_EXPORT_COMPLETE', this.assetsFolder.length), - this.exportConfig.context, - ); + fs?.completeFile(true); + log.info(messageHandler.parse('ASSET_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } - /** * @method getVersionedAssets * @returns Promise @@ -312,8 +203,8 @@ export default class ExportAssets extends BaseClass { const queryParam = { ...this.commonQueryParam, - except: { BASE: this.assetConfig.invalidKeys }, include_publish_details: true, + except: { BASE: this.assetConfig.invalidKeys }, }; const versionedAssets = map(this.versionedAssets, (element) => { @@ -331,7 +222,7 @@ export default class ExportAssets extends BaseClass { const apiBatches: Array = chunk(versionedAssets, this.assetConfig.fetchConcurrency); const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { - const { apiParams, batchIndex, index, isLastRequest } = input; + const { index, batchIndex, apiParams, isLastRequest } = input; const batch: Record = apiBatches[batchIndex][index]; const [uid, version]: any = first(entries(batch)); @@ -348,11 +239,11 @@ export default class ExportAssets extends BaseClass { const onSuccess = ({ response }: any) => { if (!fs && !isEmpty(response)) { fs = new FsUtility({ - basePath: pResolve(this.assetsRootPath, 'versions'), - chunkFileSize: this.assetConfig.chunkFileSize, + moduleName: 'assets', indexFileName: 'versioned-assets.json', + chunkFileSize: this.assetConfig.chunkFileSize, + basePath: pResolve(this.assetsRootPath, 'versions'), metaPickKeys: merge(['uid', 'url', 'filename', '_version', 'parent_uid'], this.assetConfig.assetsMetaKeys), - moduleName: 'assets', }); } if (!isEmpty(response)) { @@ -360,7 +251,7 @@ export default class ExportAssets extends BaseClass { `Writing versioned asset: UID=${response.uid}, Version=${response._version}`, this.exportConfig.context, ); - fs?.writeIntoFile([response], { keyName: ['uid', '_version'], mapKeyVal: true }); + fs?.writeIntoFile([response], { mapKeyVal: true, keyName: ['uid', '_version'] }); } }; @@ -372,14 +263,14 @@ export default class ExportAssets extends BaseClass { { apiBatches, apiParams: { - module: 'asset', queryParam, + module: 'asset', reject: onReject, resolve: onSuccess, }, - concurrencyLimit: this.assetConfig.fetchConcurrency, module: 'versioned assets', totalCount: versionedAssets.length, + concurrencyLimit: this.assetConfig.fetchConcurrency, }, promisifyHandler, ).then(() => { @@ -387,32 +278,141 @@ export default class ExportAssets extends BaseClass { log.info(messageHandler.parse('ASSET_VERSIONED_METADATA_EXPORT_COMPLETE'), this.exportConfig.context); }); } - async start(): Promise { - this.assetsRootPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.assetConfig.dirName, + + getAssetsCount(isDir = false): Promise { + const queryParam: any = { + limit: 1, + ...this.commonQueryParam, + skip: 10 ** 100, + }; + + if (isDir) queryParam.query = { is_dir: true }; + + log.debug( + `Querying count of assets${isDir ? ' (folders only)' : ''} with params: ${JSON.stringify(queryParam)}`, + this.exportConfig.context, ); - log.debug(`Assets root path resolved to: ${this.assetsRootPath}`, this.exportConfig.context); - log.debug('Fetching assets and folders count...', this.exportConfig.context); - // NOTE step 1: Get assets and it's folder count in parallel - const [assetsCount, assetsFolderCount] = await Promise.all([this.getAssetsCount(), this.getAssetsCount(true)]); + return this.stack + .asset() + .query(queryParam) + .count() + .then(({ assets }: any) => { + log.debug(`Received asset count: ${assets}`, this.exportConfig.context); + return assets; + }) + .catch((error: Error) => { + handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_COUNT_QUERY_FAILED')); + }); + } + /** + * @method downloadAssets + * @returns Promise + */ + async downloadAssets(): Promise { + const fs: FsUtility = new FsUtility({ + fileExt: 'json', + createDirIfNotExist: false, + basePath: this.assetsRootPath, + }); - log.debug('Fetching assets and folders data...', this.exportConfig.context); - // NOTE step 2: Get assets and it's folder data in parallel - await Promise.all([this.getAssetsFolders(assetsFolderCount), this.getAssets(assetsCount)]); + log.debug('Reading asset metadata for download...', this.exportConfig.context); + const assetsMetaData = fs.getPlainMeta(); - // NOTE step 3: Get versioned assets - if (!isEmpty(this.versionedAssets) && this.assetConfig.includeVersionedAssets) { - log.debug('Fetching versioned assets metadata...', this.exportConfig.context); - await this.getVersionedAssets(); + let listOfAssets = values(assetsMetaData).flat(); + + if (this.assetConfig.includeVersionedAssets) { + const versionedAssetsMetaData = fs.getPlainMeta(pResolve(this.assetsRootPath, 'versions', 'metadata.json')); + listOfAssets.push(...values(versionedAssetsMetaData).flat()); } - log.debug('Starting download of all assets...', this.exportConfig.context); - // NOTE step 4: Download all assets - await this.downloadAssets(); + listOfAssets = uniqBy(listOfAssets, 'url'); + log.debug(`Total unique assets to download: ${listOfAssets.length}`, this.exportConfig.context); - log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); + const apiBatches: Array = chunk(listOfAssets, this.assetConfig.downloadLimit); + const downloadedAssetsDirs = await getDirectories(pResolve(this.assetsRootPath, 'files')); + + const onSuccess = ({ response: { data }, additionalInfo }: any) => { + const { asset } = additionalInfo; + const assetFolderPath = pResolve(this.assetsRootPath, 'files', asset.uid); + const assetFilePath = pResolve(assetFolderPath, asset.filename); + + log.debug(`Saving asset to: ${assetFilePath}`, this.exportConfig.context); + + if (!includes(downloadedAssetsDirs, asset.uid)) { + fs.createFolderIfNotExist(assetFolderPath); + } + + const assetWriterStream = createWriteStream(assetFilePath); + assetWriterStream.on('error', (error) => { + handleAndLogError( + error, + { ...this.exportConfig.context, uid: asset.uid, filename: asset.fileName }, + messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), + ); + }); + /** + * NOTE if pipe not working as expected add the following code below to fix the issue + * https://oramind.com/using-streams-efficiently-in-nodejs/ + * import * as stream from "stream"; + * import { promisify } from "util"; + * const finished = promisify(stream.finished); + * await finished(assetWriterStream); + */ + if (this.assetConfig.enableDownloadStatus) { + const str = progress({ + time: 5000, + length: data.headers['content-length'], + }); + str.on('progress', function (progressData) { + console.log(`${asset.filename}: ${Math.round(progressData.percentage)}%`); + }); + data.pipe(str).pipe(assetWriterStream); + } else { + data.pipe(assetWriterStream); + } + + log.success(messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), this.exportConfig.context); + }; + + const onReject = ({ error, additionalInfo }: any) => { + const { asset } = additionalInfo; + handleAndLogError( + error, + { ...this.exportConfig.context, uid: asset.uid, filename: asset.filename }, + messageHandler.parse('ASSET_DOWNLOAD_FAILED', asset.filename, asset.uid), + ); + }; + + const promisifyHandler: CustomPromiseHandler = (input: CustomPromiseHandlerInput) => { + const { index, batchIndex } = input; + const asset: any = apiBatches[batchIndex][index]; + const url = this.assetConfig.securedAssets + ? `${asset.url}?authtoken=${configHandler.get('authtoken')}` + : asset.url; + log.debug( + `Preparing to download asset: ${asset.filename} (UID: ${asset.uid}) from URL: ${url}`, + this.exportConfig.context, + ); + return this.makeAPICall({ + reject: onReject, + resolve: onSuccess, + url: encodeURI(url), + module: 'download-asset', + additionalInfo: { asset }, + }); + }; + + return this.makeConcurrentCall( + { + apiBatches, + module: 'assets download', + totalCount: listOfAssets.length, + concurrencyLimit: this.assetConfig.downloadLimit, + }, + promisifyHandler, + ).then(() => { + log.success(messageHandler.parse('ASSET_DOWNLOAD_COMPLETE'), 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 1a2fd9dda..6379669e1 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -1,54 +1,54 @@ -import { log } from '@contentstack/cli-utilities'; -import chunk from 'lodash/chunk'; -import entries from 'lodash/entries'; +import map from 'lodash/map'; import fill from 'lodash/fill'; +import last from 'lodash/last'; +import chunk from 'lodash/chunk'; import isEmpty from 'lodash/isEmpty'; +import entries from 'lodash/entries'; import isEqual from 'lodash/isEqual'; -import last from 'lodash/last'; -import map from 'lodash/map'; +import { log } from '@contentstack/cli-utilities'; import { ExportConfig, ModuleClassParams } from '../../types'; export type ApiOptions = { - additionalInfo?: Record; + uid?: string; + url?: string; module: ApiModuleType; queryParam?: Record; - reject: (error: any) => void; resolve: (value: any) => void; - uid?: string; - url?: string; + reject: (error: any) => void; + additionalInfo?: Record; }; export type EnvType = { - apiBatches?: number[]; - apiParams?: ApiOptions; - concurrencyLimit: number; module: string; totalCount: number; + apiBatches?: number[]; + concurrencyLimit: number; + apiParams?: ApiOptions; }; export type CustomPromiseHandlerInput = { - apiParams?: ApiOptions; + index: number; batchIndex: number; element?: Record; - index: number; + apiParams?: ApiOptions; isLastRequest: boolean; }; export type CustomPromiseHandler = (input: CustomPromiseHandlerInput) => Promise; export type ApiModuleType = + | 'stack' | 'asset' | 'assets' + | 'entry' + | 'entries' | 'content-type' | 'content-types' - | 'download-asset' - | 'entries' - | 'entry' - | 'export-taxonomy' - | 'stack' | 'stacks' - | 'versioned-entries'; + | 'versioned-entries' + | 'download-asset' + | 'export-taxonomy'; export default abstract class BaseClass { readonly client: any; @@ -63,25 +63,67 @@ export default abstract class BaseClass { return this.client; } - protected applyQueryFilters(requestObject: any, moduleName: string): any { - if (this.exportConfig.query?.modules?.[moduleName]) { - const moduleQuery = this.exportConfig.query.modules[moduleName]; - // Merge the query parameters with existing requestObject - if (moduleQuery) { - if (!requestObject.query) { - requestObject.query = moduleQuery; - } - Object.assign(requestObject.query, moduleQuery); - } - } - return requestObject; - } - delay(ms: number): Promise { /* eslint-disable no-promise-executor-return */ return new Promise((resolve) => setTimeout(resolve, ms <= 0 ? 0 : ms)); } + makeConcurrentCall(env: EnvType, promisifyHandler?: CustomPromiseHandler): Promise { + const { module, apiBatches, totalCount, apiParams, concurrencyLimit } = env; + + /* eslint-disable no-async-promise-executor */ + return new Promise(async (resolve) => { + let batchNo = 0; + let isLastRequest = false; + const batch = fill(Array.from({ length: Number.parseInt(String(totalCount / 100), 10) }), 100); + + if (totalCount % 100) batch.push(100); + + const batches: Array = + apiBatches || + chunk( + map(batch, (skip: number, i: number) => skip * i), + concurrencyLimit, + ); + + /* eslint-disable no-promise-executor-return */ + if (isEmpty(batches)) return resolve(); + + for (const [batchIndex, batch] of entries(batches)) { + batchNo += 1; + const allPromise = []; + const start = Date.now(); + + for (const [index, element] of entries(batch)) { + let promise; + isLastRequest = isEqual(last(batch), element) && isEqual(last(batches), batch); + + if (promisifyHandler instanceof Function) { + promise = promisifyHandler({ + apiParams, + element, + isLastRequest, + index: Number(index), + batchIndex: Number(batchIndex), + }); + } else if (apiParams?.queryParam) { + apiParams.queryParam.skip = element; + promise = this.makeAPICall(apiParams, isLastRequest); + } + + allPromise.push(promise); + } + + /* eslint-disable no-await-in-loop */ + await Promise.allSettled(allPromise); + /* eslint-disable no-await-in-loop */ + await this.logMsgAndWaitIfRequired(module, start, batchNo); + + if (isLastRequest) resolve(); + } + }); + } + /** * @method logMsgAndWaitIfRequired * @param module string @@ -115,7 +157,7 @@ export default abstract class BaseClass { * @returns Promise */ makeAPICall( - { additionalInfo, module: moduleName, queryParam = {}, reject, resolve, uid = '', url = '' }: ApiOptions, + { module: moduleName, reject, resolve, url = '', uid = '', additionalInfo, queryParam = {} }: ApiOptions, isLastRequest = false, ): Promise { switch (moduleName) { @@ -123,21 +165,21 @@ export default abstract class BaseClass { return this.stack .asset(uid) .fetch(queryParam) - .then((response: any) => resolve({ additionalInfo, isLastRequest, response })) - .catch((error: Error) => reject({ additionalInfo, error, isLastRequest })); + .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) + .catch((error: Error) => reject({ error, isLastRequest, additionalInfo })); case 'assets': return this.stack .asset() .query(queryParam) .find() - .then((response: any) => resolve({ additionalInfo, isLastRequest, response })) - .catch((error: Error) => reject({ additionalInfo, error, isLastRequest })); + .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) + .catch((error: Error) => reject({ error, isLastRequest, additionalInfo })); case 'download-asset': return this.stack .asset() - .download({ responseType: 'stream', url }) - .then((response: any) => resolve({ additionalInfo, isLastRequest, response })) - .catch((error: any) => reject({ additionalInfo, error, isLastRequest })); + .download({ url, responseType: 'stream' }) + .then((response: any) => resolve({ response, isLastRequest, additionalInfo })) + .catch((error: any) => reject({ error, isLastRequest, additionalInfo })); case 'export-taxonomy': return this.stack .taxonomy(uid) @@ -149,59 +191,17 @@ export default abstract class BaseClass { } } - makeConcurrentCall(env: EnvType, promisifyHandler?: CustomPromiseHandler): Promise { - const { apiBatches, apiParams, concurrencyLimit, module, totalCount } = env; - - /* eslint-disable no-async-promise-executor */ - return new Promise(async (resolve) => { - let batchNo = 0; - let isLastRequest = false; - const batch = fill(Array.from({ length: Number.parseInt(String(totalCount / 100), 10) }), 100); - - if (totalCount % 100) batch.push(100); - - const batches: Array = - apiBatches || - chunk( - map(batch, (skip: number, i: number) => skip * i), - concurrencyLimit, - ); - - /* eslint-disable no-promise-executor-return */ - if (isEmpty(batches)) return resolve(); - - for (const [batchIndex, batch] of entries(batches)) { - batchNo += 1; - const allPromise = []; - const start = Date.now(); - - for (const [index, element] of entries(batch)) { - let promise; - isLastRequest = isEqual(last(batch), element) && isEqual(last(batches), batch); - - if (promisifyHandler instanceof Function) { - promise = promisifyHandler({ - apiParams, - batchIndex: Number(batchIndex), - element, - index: Number(index), - isLastRequest, - }); - } else if (apiParams?.queryParam) { - apiParams.queryParam.skip = element; - promise = this.makeAPICall(apiParams, isLastRequest); - } - - allPromise.push(promise); + protected applyQueryFilters(requestObject: any, moduleName: string): any { + if (this.exportConfig.query?.modules?.[moduleName]) { + const moduleQuery = this.exportConfig.query.modules[moduleName]; + // Merge the query parameters with existing requestObject + if (moduleQuery) { + if (!requestObject.query) { + requestObject.query = moduleQuery; } - - /* eslint-disable no-await-in-loop */ - await Promise.allSettled(allPromise); - /* eslint-disable no-await-in-loop */ - await this.logMsgAndWaitIfRequired(module, start, batchNo); - - if (isLastRequest) resolve(); + Object.assign(requestObject.query, moduleQuery); } - }); + } + return requestObject; } } diff --git a/packages/contentstack-export/src/export/modules/composable-studio.ts b/packages/contentstack-export/src/export/modules/composable-studio.ts index 143932efe..8faff8c2b 100644 --- a/packages/contentstack-export/src/export/modules/composable-studio.ts +++ b/packages/contentstack-export/src/export/modules/composable-studio.ts @@ -1,25 +1,25 @@ +import { resolve as pResolve } from 'node:path'; import { - HttpClient, - authenticationHandler, cliux, - handleAndLogError, isAuthenticated, log, messageHandler, + handleAndLogError, + HttpClient, + authenticationHandler, } from '@contentstack/cli-utilities'; -import { resolve as pResolve } from 'node:path'; -import { ComposableStudioConfig, ComposableStudioProject, ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil, getOrgUid } from '../../utils'; +import { ModuleClassParams, ComposableStudioConfig, ExportConfig, ComposableStudioProject } from '../../types'; export default class ExportComposableStudio { - protected apiClient: HttpClient; protected composableStudioConfig: ComposableStudioConfig; - public composableStudioPath: string; protected composableStudioProject: ComposableStudioProject | null = null; + protected apiClient: HttpClient; + public composableStudioPath: string; public exportConfig: ExportConfig; - constructor({ exportConfig }: Omit) { + constructor({ exportConfig }: Omit) { this.exportConfig = exportConfig; this.composableStudioConfig = exportConfig.modules['composable-studio']; this.exportConfig.context.module = 'composable-studio'; @@ -29,6 +29,34 @@ export default class ExportComposableStudio { this.apiClient.baseUrl(`${this.composableStudioConfig.apiBaseUrl}/${this.composableStudioConfig.apiVersion}`); } + async start(): Promise { + log.debug('Starting Studio project export process...', this.exportConfig.context); + + if (!isAuthenticated()) { + cliux.print( + 'WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in', + { color: 'yellow' }, + ); + return Promise.resolve(); + } + + this.composableStudioPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.composableStudioConfig.dirName, + ); + log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.composableStudioPath); + log.debug('Created Studio directory', this.exportConfig.context); + + this.exportConfig.org_uid = this.exportConfig.org_uid || (await getOrgUid(this.exportConfig)); + log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context); + + await this.exportProjects(); + log.debug('Studio project export process completed', this.exportConfig.context); + } + /** * Export Studio projects connected to the current stack */ @@ -56,8 +84,8 @@ export default class ExportComposableStudio { // Set organization_uid header this.apiClient.headers({ - Accept: 'application/json', organization_uid: this.exportConfig.org_uid, + Accept: 'application/json', }); const apiUrl = '/projects'; @@ -107,32 +135,4 @@ export default class ExportComposableStudio { }); } } - - async start(): Promise { - log.debug('Starting Studio project export process...', this.exportConfig.context); - - if (!isAuthenticated()) { - cliux.print( - 'WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in', - { color: 'yellow' }, - ); - return Promise.resolve(); - } - - this.composableStudioPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.composableStudioConfig.dirName, - ); - log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.composableStudioPath); - log.debug('Created Studio directory', this.exportConfig.context); - - this.exportConfig.org_uid = this.exportConfig.org_uid || (await getOrgUid(this.exportConfig)); - log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context); - - await this.exportProjects(); - log.debug('Studio project export process completed', this.exportConfig.context); - } } diff --git a/packages/contentstack-export/src/export/modules/content-types.ts b/packages/contentstack-export/src/export/modules/content-types.ts index 04a1731e8..7baf2b4ca 100644 --- a/packages/contentstack-export/src/export/modules/content-types.ts +++ b/packages/contentstack-export/src/export/modules/content-types.ts @@ -1,47 +1,41 @@ -import { - ContentstackClient, - handleAndLogError, - log, - messageHandler, - sanitizePath, -} from '@contentstack/cli-utilities'; import * as path from 'path'; +import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; -import { ExportConfig, ModuleClassParams } from '../../types'; -import { executeTask, fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil, executeTask } from '../../utils'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class ContentTypesExport extends BaseClass { + private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - private contentTypes: Record[]; + private qs: { + include_count: boolean; + asc: string; + skip?: number; + limit?: number; + include_global_field_schema: boolean; + uid?: Record; + }; private contentTypesConfig: { dirName?: string; - fetchConcurrency?: number; fileName?: string; - limit?: number; validKeys?: string[]; + fetchConcurrency?: number; writeConcurrency?: number; - }; - private contentTypesDirPath: string; - private qs: { - asc: string; - include_count: boolean; - include_global_field_schema: boolean; limit?: number; - skip?: number; - uid?: Record; }; - private stackAPIClient: ReturnType; + private contentTypesDirPath: string; + private contentTypes: Record[]; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.stackAPIClient = stackAPIClient; this.contentTypesConfig = exportConfig.modules['content-types']; this.qs = { - asc: 'updated_at', include_count: true, - include_global_field_schema: true, + asc: 'updated_at', limit: this.contentTypesConfig.limit, + include_global_field_schema: true, }; // If content type id is provided then use it as part of query @@ -61,6 +55,21 @@ export default class ContentTypesExport extends BaseClass { this.exportConfig.context.module = 'content-types'; } + async start() { + try { + log.debug('Starting content types export process...', this.exportConfig.context); + await fsUtil.makeDirectory(this.contentTypesDirPath); + log.debug(`Created directory at: '${this.contentTypesDirPath}'.`, this.exportConfig.context); + + await this.getContentTypes(); + await this.writeContentTypes(this.contentTypes); + + log.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + } + } + async getContentTypes(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -71,7 +80,9 @@ export default class ContentTypesExport extends BaseClass { const contentTypeSearchResponse = await this.stackAPIClient.contentType().query(this.qs).find(); log.debug( - `Fetched ${contentTypeSearchResponse.items?.length || 0} content types out of total ${contentTypeSearchResponse.count}`, + `Fetched ${contentTypeSearchResponse.items?.length || 0} content types out of total ${ + contentTypeSearchResponse.count + }`, this.exportConfig.context, ); @@ -105,21 +116,6 @@ export default class ContentTypesExport extends BaseClass { return updatedContentTypes; } - async start() { - try { - log.debug('Starting content types export process...', this.exportConfig.context); - await fsUtil.makeDirectory(this.contentTypesDirPath); - log.debug(`Created directory at: '${this.contentTypesDirPath}'.`, this.exportConfig.context); - - await this.getContentTypes(); - await this.writeContentTypes(this.contentTypes); - - log.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - } - } - async writeContentTypes(contentTypes: Record[]) { log.debug(`Writing ${contentTypes?.length} content types to disk...`, this.exportConfig.context); diff --git a/packages/contentstack-export/src/export/modules/custom-roles.ts b/packages/contentstack-export/src/export/modules/custom-roles.ts index bbbe7d8bb..6db21485a 100644 --- a/packages/contentstack-export/src/export/modules/custom-roles.ts +++ b/packages/contentstack-export/src/export/modules/custom-roles.ts @@ -1,39 +1,65 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; +import keys from 'lodash/keys'; import find from 'lodash/find'; import forEach from 'lodash/forEach'; -import keys from 'lodash/keys'; import values from 'lodash/values'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { CustomRoleConfig, ModuleClassParams } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { CustomRoleConfig, ModuleClassParams } from '../../types'; export default class ExportCustomRoles extends BaseClass { - public customRolesLocalesFilepath: string; - public rolesFolderPath: string; private customRoles: Record; - private customRolesConfig: CustomRoleConfig; private existingRoles: Record; - private localesMap: Record; + private customRolesConfig: CustomRoleConfig; private sourceLocalesMap: Record; + private localesMap: Record; + public rolesFolderPath: string; + public customRolesLocalesFilepath: string; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.customRoles = {}; this.customRolesConfig = exportConfig.modules.customRoles; - this.existingRoles = { Admin: 1, 'Content Manager': 1, Developer: 1 }; + this.existingRoles = { Admin: 1, Developer: 1, 'Content Manager': 1 }; this.localesMap = {}; this.sourceLocalesMap = {}; this.exportConfig.context.module = 'custom-roles'; } + async start(): Promise { + log.debug('Starting export process for custom roles...', this.exportConfig.context); + + this.rolesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.customRolesConfig.dirName, + ); + log.debug(`Custom roles folder path is: ${this.rolesFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.rolesFolderPath); + log.debug('Custom roles directory created.', this.exportConfig.context); + + this.customRolesLocalesFilepath = pResolve(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName); + log.debug(`Custom roles locales file path is: ${this.customRolesLocalesFilepath}`, this.exportConfig.context); + + await this.getCustomRoles(); + await this.getLocales(); + await this.getCustomRolesLocales(); + + log.debug( + `Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`, + this.exportConfig.context, + ); + } + async getCustomRoles(): Promise { log.debug('Fetching all roles from the stack...', this.exportConfig.context); - + const roles = await this.stack .role() - .fetchAll({ include_permissions: true, include_rules: true }) + .fetchAll({ include_rules: true, include_permissions: true }) .then((data: any) => { log.debug(`Fetched ${data.items?.length || 0} roles from the stack.`, this.exportConfig.context); return data; @@ -42,9 +68,12 @@ export default class ExportCustomRoles extends BaseClass { log.debug('An error occurred while fetching roles.', this.exportConfig.context); return handleAndLogError(err, { ...this.exportConfig.context }); }); - + const customRoles = roles.items.filter((role: any) => !this.existingRoles[role.name]); - log.debug(`Found ${customRoles.length} custom roles from ${roles.items?.length || 0} total roles.`, this.exportConfig.context); + log.debug( + `Found ${customRoles.length} custom roles from ${roles.items?.length || 0} total roles.`, + this.exportConfig.context, + ); if (!customRoles.length) { log.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context); @@ -56,22 +85,49 @@ export default class ExportCustomRoles extends BaseClass { log.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role?.name), this.exportConfig.context); this.customRoles[role.uid] = role; }); - + const customRolesFilePath = pResolve(this.rolesFolderPath, this.customRolesConfig.fileName); log.debug(`Writing custom roles to: ${customRolesFilePath}.`, this.exportConfig.context); fsUtil.writeFile(customRolesFilePath, this.customRoles); } + async getLocales() { + log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context); + + const locales = await this.stack + .locale() + .query({}) + .find() + .then((data: any) => { + log.debug(`Fetched ${data?.items?.length || 0} locales.`, this.exportConfig.context); + return data; + }) + .catch((err: any) => { + log.debug('An error occurred while fetching locales.', this.exportConfig.context); + return handleAndLogError(err, { ...this.exportConfig.context }); + }); + + for (const locale of locales.items) { + log.debug(`Mapping locale: ${locale?.name} (${locale?.uid})`, this.exportConfig.context); + this.sourceLocalesMap[locale.uid] = locale; + } + + log.debug(`Mapped ${Object.keys(this.sourceLocalesMap).length} source locales.`, this.exportConfig.context); + } + async getCustomRolesLocales() { log.debug('Processing custom roles locales mapping...', this.exportConfig.context); - + for (const role of values(this.customRoles)) { const customRole = role as Record; log.debug(`Processing locales for custom role: ${customRole?.name}`, this.exportConfig.context); - + const rulesLocales = find(customRole.rules, (rule: any) => rule.module === 'locale'); if (rulesLocales?.locales?.length) { - log.debug(`Found ${rulesLocales.locales.length} locales for the role: ${customRole?.name}.`, this.exportConfig.context); + log.debug( + `Found ${rulesLocales.locales.length} locales for the role: ${customRole?.name}.`, + this.exportConfig.context, + ); forEach(rulesLocales.locales, (locale: any) => { log.debug(`Adding locale ${locale} to the custom roles mapping.`, this.exportConfig.context); this.localesMap[locale] = 1; @@ -81,7 +137,7 @@ export default class ExportCustomRoles extends BaseClass { if (keys(this.localesMap)?.length) { log.debug(`Processing ${Object.keys(this.localesMap).length} mapped locales.`, this.exportConfig.context); - + for (const locale in this.localesMap) { if (this.sourceLocalesMap[locale] !== undefined) { const sourceLocale = this.sourceLocalesMap[locale] as Record; @@ -90,58 +146,11 @@ export default class ExportCustomRoles extends BaseClass { } this.localesMap[locale] = this.sourceLocalesMap[locale]; } - + log.debug(`Writing custom roles locales to: ${this.customRolesLocalesFilepath}.`, this.exportConfig.context); fsUtil.writeFile(this.customRolesLocalesFilepath, this.localesMap); } else { log.debug('No custom role locales found to process.', this.exportConfig.context); } } - - async getLocales() { - log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context); - - const locales = await this.stack - .locale() - .query({}) - .find() - .then((data: any) => { - log.debug(`Fetched ${data?.items?.length || 0} locales.`, this.exportConfig.context); - return data; - }) - .catch((err: any) => { - log.debug('An error occurred while fetching locales.', this.exportConfig.context); - return handleAndLogError(err, { ...this.exportConfig.context }); - }); - - for (const locale of locales.items) { - log.debug(`Mapping locale: ${locale?.name} (${locale?.uid})`, this.exportConfig.context); - this.sourceLocalesMap[locale.uid] = locale; - } - - log.debug(`Mapped ${Object.keys(this.sourceLocalesMap).length} source locales.`, this.exportConfig.context); - } - - async start(): Promise { - log.debug('Starting export process for custom roles...', this.exportConfig.context); - - this.rolesFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.customRolesConfig.dirName, - ); - log.debug(`Custom roles folder path is: ${this.rolesFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.rolesFolderPath); - log.debug('Custom roles directory created.', this.exportConfig.context); - - this.customRolesLocalesFilepath = pResolve(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName); - log.debug(`Custom roles locales file path is: ${this.customRolesLocalesFilepath}`, this.exportConfig.context); - - await this.getCustomRoles(); - await this.getLocales(); - await this.getCustomRolesLocales(); - - log.debug(`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`, this.exportConfig.context); - } } diff --git a/packages/contentstack-export/src/export/modules/entries.ts b/packages/contentstack-export/src/export/modules/entries.ts index 5afbb2127..743b471ea 100644 --- a/packages/contentstack-export/src/export/modules/entries.ts +++ b/packages/contentstack-export/src/export/modules/entries.ts @@ -1,32 +1,33 @@ -import { ContentstackClient, FsUtility, handleAndLogError, log, messageHandler , sanitizePath } from '@contentstack/cli-utilities'; -import { Export, ExportProjects } from '@contentstack/cli-variants'; import * as path from 'path'; +import { ContentstackClient, FsUtility, handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; +import { Export, ExportProjects } from '@contentstack/cli-variants'; +import { sanitizePath } from '@contentstack/cli-utilities'; -import { ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil } from '../../utils'; import BaseClass, { ApiOptions } from './base-class'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class EntriesExport extends BaseClass { + private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - public exportVariantEntry = false; private entriesConfig: { - batchLimit?: number; - chunkFileSize?: number; dirName?: string; - exportVersions: boolean; - fetchConcurrency?: number; fileName?: string; invalidKeys?: string[]; - limit?: number; + fetchConcurrency?: number; writeConcurrency?: number; + limit?: number; + chunkFileSize?: number; + batchLimit?: number; + exportVersions: boolean; }; + private variantEntries!: any; private entriesDirPath: string; - private entriesFileHelper: FsUtility; private localesFilePath: string; - private projectInstance: ExportProjects; private schemaFilePath: string; - private stackAPIClient: ReturnType; - private variantEntries!: any; + private entriesFileHelper: FsUtility; + private projectInstance: ExportProjects; + public exportVariantEntry: boolean = false; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -54,6 +55,66 @@ export default class EntriesExport extends BaseClass { this.exportConfig.context.module = 'entries'; } + async start() { + try { + log.debug('Starting entries export process...', this.exportConfig.context); + const locales = fsUtil.readFile(this.localesFilePath) as Array>; + if (!Array.isArray(locales) || locales?.length === 0) { + log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); + } else { + log.debug(`Loaded ${locales?.length} locales from ${this.localesFilePath}`, this.exportConfig.context); + } + + const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; + if (contentTypes?.length === 0) { + log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); + return; + } + log.debug(`Loaded ${contentTypes?.length} content types from ${this.schemaFilePath}`, this.exportConfig.context); + + // NOTE Check if variant is enabled in specific stack + if (this.exportConfig.personalizationEnabled) { + log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context); + let project_id; + try { + const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey }); + + if (project && project[0]?.uid) { + project_id = project[0].uid; + this.exportVariantEntry = true; + log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context); + } + + this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + } + } + + const entryRequestOptions = this.createRequestObjects(locales, contentTypes); + log.debug( + `Created ${entryRequestOptions.length} entry request objects for processing`, + this.exportConfig.context, + ); + + for (let entryRequestOption of entryRequestOptions) { + log.debug( + `Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, + this.exportConfig.context, + ); + await this.getEntries(entryRequestOption); + this.entriesFileHelper?.completeFile(true); + log.success( + messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), + this.exportConfig.context, + ); + } + log.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + } + } + createRequestObjects( locales: Array>, contentTypes: Array>, @@ -70,10 +131,10 @@ export default class EntriesExport extends BaseClass { log.debug(`Found ${contentTypes.length} content types for export`, this.exportConfig.context); } - const requestObjects: Array> = []; + let requestObjects: Array> = []; contentTypes.forEach((contentType) => { if (Object.keys(locales).length !== 0) { - for (const locale in locales) { + for (let locale in locales) { requestObjects.push({ contentType: contentType.uid, locale: locales[locale].code, @@ -90,96 +151,17 @@ export default class EntriesExport extends BaseClass { return requestObjects; } - async entryVersionHandler({ - apiParams, - element: entry, - }: { - apiParams: ApiOptions; - element: Record; - isLastRequest: boolean; - }) { - log.debug(`Processing versioned entry: ${entry.uid}`, this.exportConfig.context); - - return new Promise(async (resolve, reject) => { - return await this.getEntryByVersion(apiParams.queryParam, entry) - .then((response) => { - log.debug(`Successfully fetched versions for entry UID: ${entry.uid}`, this.exportConfig.context); - apiParams.resolve({ - apiData: entry, - response, - }); - resolve(true); - }) - .catch((error) => { - log.debug(`Failed to fetch versions for entry UID: ${entry.uid}`, this.exportConfig.context); - apiParams.reject({ - apiData: entry, - error, - }); - reject(true); - }); - }); - } - - async fetchEntriesVersions( - entries: any, - options: { contentType: string; locale: string; versionedEntryPath: string }, - ): Promise { - log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context); - - const onSuccess = ({ apiData: entry, response }: any) => { - const versionFilePath = path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)); - log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context); - fsUtil.writeFile(versionFilePath, response); - log.success( - messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), - this.exportConfig.context, - ); - }; - const onReject = ({ apiData: { uid } = undefined, error }: any) => { - log.debug(`Failed to fetch versioned entry for uid: ${uid}`, this.exportConfig.context); - handleAndLogError( - error, - { - ...this.exportConfig.context, - uid, - }, - messageHandler.parse('ENTRIES_EXPORT_VERSIONS_FAILED', uid), - ); - }; - - log.debug( - `Starting concurrent calls for versioned entries with batch limit: ${this.entriesConfig.batchLimit}`, - this.exportConfig.context, - ); - return await this.makeConcurrentCall( - { - apiBatches: [entries], - apiParams: { - module: 'versioned-entries', - queryParam: options, - reject: onReject, - resolve: onSuccess, - }, - concurrencyLimit: this.entriesConfig.batchLimit, - module: 'versioned-entries', - totalCount: entries.length, - }, - this.entryVersionHandler.bind(this), - ); - } - async getEntries(options: Record): Promise { options.skip = options.skip || 0; - const requestObject = { + let requestObject = { + locale: options.locale, + skip: options.skip, + limit: this.entriesConfig.limit, include_count: true, include_publish_details: true, - limit: this.entriesConfig.limit, - locale: options.locale, query: { locale: options.locale, }, - skip: options.skip, }; this.applyQueryFilters(requestObject, 'entries'); @@ -216,11 +198,11 @@ export default class EntriesExport extends BaseClass { log.debug(`Creating directory for entries at: ${entryBasePath}`, this.exportConfig.context); await fsUtil.makeDirectory(entryBasePath); this.entriesFileHelper = new FsUtility({ + moduleName: 'entries', + indexFileName: 'index.json', basePath: entryBasePath, chunkFileSize: this.entriesConfig.chunkFileSize, - indexFileName: 'index.json', keepMetadata: false, - moduleName: 'entries', omitKeys: this.entriesConfig.invalidKeys, }); log.debug('Initialized FsUtility for writing entries', this.exportConfig.context); @@ -231,7 +213,7 @@ export default class EntriesExport extends BaseClass { if (this.entriesConfig.exportVersions) { log.debug('Exporting entry versions is enabled.', this.exportConfig.context); - const versionedEntryPath = path.join( + let versionedEntryPath = path.join( sanitizePath(this.entriesDirPath), sanitizePath(options.contentType), sanitizePath(options.locale), @@ -240,8 +222,8 @@ export default class EntriesExport extends BaseClass { log.debug(`Creating versioned entries directory at: ${versionedEntryPath}.`, this.exportConfig.context); fsUtil.makeDirectory(versionedEntryPath); await this.fetchEntriesVersions(entriesSearchResponse.items, { - contentType: options.contentType, locale: options.locale, + contentType: options.contentType, versionedEntryPath, }); } @@ -250,9 +232,9 @@ export default class EntriesExport extends BaseClass { if (this.exportVariantEntry) { log.debug('Exporting variant entries for base entries', this.exportConfig.context); await this.variantEntries.exportVariantEntry({ + locale: options.locale, contentTypeUid: options.contentType, entries: entriesSearchResponse.items, - locale: options.locale, }); } @@ -269,16 +251,95 @@ export default class EntriesExport extends BaseClass { } } + async fetchEntriesVersions( + entries: any, + options: { locale: string; contentType: string; versionedEntryPath: string }, + ): Promise { + log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context); + + const onSuccess = ({ response, apiData: entry }: any) => { + const versionFilePath = path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)); + log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context); + fsUtil.writeFile(versionFilePath, response); + log.success( + messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), + this.exportConfig.context, + ); + }; + const onReject = ({ error, apiData: { uid } = undefined }: any) => { + log.debug(`Failed to fetch versioned entry for uid: ${uid}`, this.exportConfig.context); + handleAndLogError( + error, + { + ...this.exportConfig.context, + uid, + }, + messageHandler.parse('ENTRIES_EXPORT_VERSIONS_FAILED', uid), + ); + }; + + log.debug( + `Starting concurrent calls for versioned entries with batch limit: ${this.entriesConfig.batchLimit}`, + this.exportConfig.context, + ); + return await this.makeConcurrentCall( + { + apiBatches: [entries], + module: 'versioned-entries', + totalCount: entries.length, + concurrencyLimit: this.entriesConfig.batchLimit, + apiParams: { + module: 'versioned-entries', + queryParam: options, + resolve: onSuccess, + reject: onReject, + }, + }, + this.entryVersionHandler.bind(this), + ); + } + + async entryVersionHandler({ + apiParams, + element: entry, + }: { + apiParams: ApiOptions; + element: Record; + isLastRequest: boolean; + }) { + log.debug(`Processing versioned entry: ${entry.uid}`, this.exportConfig.context); + + return new Promise(async (resolve, reject) => { + return await this.getEntryByVersion(apiParams.queryParam, entry) + .then((response) => { + log.debug(`Successfully fetched versions for entry UID: ${entry.uid}`, this.exportConfig.context); + apiParams.resolve({ + response, + apiData: entry, + }); + resolve(true); + }) + .catch((error) => { + log.debug(`Failed to fetch versions for entry UID: ${entry.uid}`, this.exportConfig.context); + apiParams.reject({ + error, + apiData: entry, + }); + reject(true); + }); + }); + } + async getEntryByVersion( options: any, entry: Record, entries: Array> = [], ): Promise { const queryRequestObject = { + locale: options.locale, except: { BASE: this.entriesConfig.invalidKeys, }, - locale: options.locale, version: entry._version, }; @@ -304,64 +365,4 @@ export default class EntriesExport extends BaseClass { ); return entries; } - - async start() { - try { - log.debug('Starting entries export process...', this.exportConfig.context); - const locales = fsUtil.readFile(this.localesFilePath) as Array>; - if (!Array.isArray(locales) || locales?.length === 0) { - log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); - } else { - log.debug(`Loaded ${locales?.length} locales from ${this.localesFilePath}`, this.exportConfig.context); - } - - const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; - if (contentTypes?.length === 0) { - log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); - return; - } - log.debug(`Loaded ${contentTypes?.length} content types from ${this.schemaFilePath}`, this.exportConfig.context); - - // NOTE Check if variant is enabled in specific stack - if (this.exportConfig.personalizationEnabled) { - log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context); - let project_id; - try { - const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey }); - - if (project && project[0]?.uid) { - project_id = project[0].uid; - this.exportVariantEntry = true; - log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context); - } - - this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - } - } - - const entryRequestOptions = this.createRequestObjects(locales, contentTypes); - log.debug( - `Created ${entryRequestOptions.length} entry request objects for processing`, - this.exportConfig.context, - ); - - for (const entryRequestOption of entryRequestOptions) { - log.debug( - `Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, - this.exportConfig.context, - ); - await this.getEntries(entryRequestOption); - this.entriesFileHelper?.completeFile(true); - log.success( - messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), - this.exportConfig.context, - ); - } - log.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - } - } } diff --git a/packages/contentstack-export/src/export/modules/environments.ts b/packages/contentstack-export/src/export/modules/environments.ts index b0538c839..43c3745df 100644 --- a/packages/contentstack-export/src/export/modules/environments.ts +++ b/packages/contentstack-export/src/export/modules/environments.ts @@ -1,16 +1,16 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; -import omit from 'lodash/omit'; import { resolve as pResolve } from 'node:path'; +import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { EnvironmentConfig, ModuleClassParams } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { EnvironmentConfig, ModuleClassParams } from '../../types'; export default class ExportEnvironments extends BaseClass { - public environmentsFolderPath: string; - private environmentConfig: EnvironmentConfig; private environments: Record; + private environmentConfig: EnvironmentConfig; + public environmentsFolderPath: string; private qs: { include_count: boolean; skip?: number; @@ -24,6 +24,34 @@ export default class ExportEnvironments extends BaseClass { this.exportConfig.context.module = 'environments'; } + async start(): Promise { + log.debug('Starting environment export process...', this.exportConfig.context); + this.environmentsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.environmentConfig.dirName, + ); + log.debug(`Environments folder path is: ${this.environmentsFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.environmentsFolderPath); + log.debug('Environments directory created.', this.exportConfig.context); + + await this.getEnvironments(); + log.debug(`Retrieved ${Object.keys(this.environments).length} environments.`, this.exportConfig.context); + + if (this.environments === undefined || isEmpty(this.environments)) { + log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); + } else { + const environmentsFilePath = pResolve(this.environmentsFolderPath, this.environmentConfig.fileName); + log.debug(`Writing environments to: ${environmentsFilePath}.`, this.exportConfig.context); + fsUtil.writeFile(environmentsFilePath, this.environments); + log.success( + messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), + this.exportConfig.context, + ); + } + } + async getEnvironments(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -31,17 +59,17 @@ export default class ExportEnvironments extends BaseClass { } else { log.debug('Fetching environments with initial query...', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - + await this.stack .environment() .query(this.qs) .find() .then(async (data: any) => { - const { count, items } = data; + const { items, count } = data; log.debug(`Fetched ${items?.length || 0} environments out of ${count} total.`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} environments.`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -64,44 +92,19 @@ export default class ExportEnvironments extends BaseClass { sanitizeAttribs(environments: Record[]) { log.debug(`Sanitizing ${environments.length} environments...`, this.exportConfig.context); - + for (let index = 0; index < environments?.length; index++) { const extUid = environments[index].uid; const envName = environments[index]?.name; log.debug(`Processing environment: ${envName} (${extUid})`, this.exportConfig.context); - + this.environments[extUid] = omit(environments[index], ['ACL']); - log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName ), this.exportConfig.context); + log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`, this.exportConfig.context); - } - async start(): Promise { - log.debug('Starting environment export process...', this.exportConfig.context); - this.environmentsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.environmentConfig.dirName, + log.debug( + `Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`, + this.exportConfig.context, ); - log.debug(`Environments folder path is: ${this.environmentsFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.environmentsFolderPath); - log.debug('Environments directory created.', this.exportConfig.context); - - await this.getEnvironments(); - log.debug(`Retrieved ${Object.keys(this.environments).length} environments.`, this.exportConfig.context); - - if (this.environments === undefined || isEmpty(this.environments)) { - log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); - } else { - const environmentsFilePath = pResolve(this.environmentsFolderPath, this.environmentConfig.fileName); - log.debug(`Writing environments to: ${environmentsFilePath}.`, this.exportConfig.context); - fsUtil.writeFile(environmentsFilePath, this.environments); - log.success( - messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), - this.exportConfig.context, - ); - } } } diff --git a/packages/contentstack-export/src/export/modules/extensions.ts b/packages/contentstack-export/src/export/modules/extensions.ts index 2abfa827b..efe3e1060 100644 --- a/packages/contentstack-export/src/export/modules/extensions.ts +++ b/packages/contentstack-export/src/export/modules/extensions.ts @@ -1,16 +1,16 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { ExtensionsConfig, ModuleClassParams } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { ExtensionsConfig, ModuleClassParams } from '../../types'; export default class ExportExtensions extends BaseClass { - public extensionConfig: ExtensionsConfig; - private extensions: Record; private extensionsFolderPath: string; + private extensions: Record; + public extensionConfig: ExtensionsConfig; private qs: { include_count: boolean; skip?: number; @@ -25,6 +25,35 @@ export default class ExportExtensions extends BaseClass { this.exportConfig.context.module = 'extensions'; } + async start(): Promise { + log.debug('Starting extensions export process...', this.exportConfig.context); + + this.extensionsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.extensionConfig.dirName, + ); + log.debug(`Extensions folder path is: ${this.extensionsFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.extensionsFolderPath); + log.debug('Extensions directory created.', this.exportConfig.context); + + await this.getExtensions(); + log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions.`, this.exportConfig.context); + + if (this.extensions === undefined || isEmpty(this.extensions)) { + log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); + } else { + const extensionsFilePath = pResolve(this.extensionsFolderPath, this.extensionConfig.fileName); + log.debug(`Writing extensions to: ${extensionsFilePath}.`, this.exportConfig.context); + fsUtil.writeFile(extensionsFilePath, this.extensions); + log.success( + messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length), + this.exportConfig.context, + ); + } + } + async getExtensions(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -32,17 +61,17 @@ export default class ExportExtensions extends BaseClass { } else { log.debug('Fetching extensions with initial query...', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context); - + await this.stack .extension() .query(this.qs) .find() .then(async (data: any) => { - const { count, items } = data; + const { items, count } = data; log.debug(`Fetched ${items?.length || 0} extensions out of ${count}.`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} extensions...`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -65,45 +94,19 @@ export default class ExportExtensions extends BaseClass { sanitizeAttribs(extensions: Record[]) { log.debug(`Sanitizing ${extensions.length} extensions...`, this.exportConfig.context); - + for (let index = 0; index < extensions?.length; index++) { const extUid = extensions[index].uid; const extTitle = extensions[index]?.title; log.debug(`Processing extension: '${extTitle}' (UID: ${extUid})...`, this.exportConfig.context); - + this.extensions[extUid] = omit(extensions[index], ['SYS_ACL']); log.info(messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}.`, this.exportConfig.context); - } - async start(): Promise { - log.debug('Starting extensions export process...', this.exportConfig.context); - - this.extensionsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.extensionConfig.dirName, + log.debug( + `Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}.`, + this.exportConfig.context, ); - log.debug(`Extensions folder path is: ${this.extensionsFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.extensionsFolderPath); - log.debug('Extensions directory created.', this.exportConfig.context); - - await this.getExtensions(); - log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions.`, this.exportConfig.context); - - if (this.extensions === undefined || isEmpty(this.extensions)) { - log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); - } else { - const extensionsFilePath = pResolve(this.extensionsFolderPath, this.extensionConfig.fileName); - log.debug(`Writing extensions to: ${extensionsFilePath}.`, this.exportConfig.context); - fsUtil.writeFile(extensionsFilePath, this.extensions); - log.success( - messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ), - this.exportConfig.context, - ); - } } } diff --git a/packages/contentstack-export/src/export/modules/global-fields.ts b/packages/contentstack-export/src/export/modules/global-fields.ts index 93c4e5a45..aae016f7d 100644 --- a/packages/contentstack-export/src/export/modules/global-fields.ts +++ b/packages/contentstack-export/src/export/modules/global-fields.ts @@ -1,47 +1,41 @@ -import { - ContentstackClient, - handleAndLogError, - log, - messageHandler, - sanitizePath, -} from '@contentstack/cli-utilities'; import * as path from 'path'; +import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; -import { ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil } from '../../utils'; +import { ExportConfig, ModuleClassParams } from '../../types'; import BaseClass from './base-class'; export default class GlobalFieldsExport extends BaseClass { + private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - private globalFields: Record[]; + private qs: { + include_count: boolean; + asc: string; + skip?: number; + limit?: number; + include_global_field_schema?: boolean; + }; private globalFieldsConfig: { dirName?: string; - fetchConcurrency?: number; fileName?: string; - limit?: number; validKeys?: string[]; + fetchConcurrency?: number; writeConcurrency?: number; - }; - private globalFieldsDirPath: string; - private qs: { - asc: string; - include_count: boolean; - include_global_field_schema?: boolean; limit?: number; - skip?: number; }; - private stackAPIClient: ReturnType; + private globalFieldsDirPath: string; + private globalFields: Record[]; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.stackAPIClient = stackAPIClient; this.globalFieldsConfig = exportConfig.modules['global-fields']; this.qs = { + skip: 0, asc: 'updated_at', include_count: true, - include_global_field_schema: true, limit: this.globalFieldsConfig.limit, - skip: 0, + include_global_field_schema: true, }; this.globalFieldsDirPath = path.resolve( sanitizePath(exportConfig.data), @@ -53,17 +47,46 @@ export default class GlobalFieldsExport extends BaseClass { this.exportConfig.context.module = 'global-fields'; } - async getGlobalFields(skip = 0): Promise { + async start() { + try { + log.debug('Starting export process for global fields...', this.exportConfig.context); + log.debug(`Global fields directory path: '${this.globalFieldsDirPath}'`, this.exportConfig.context); + await fsUtil.makeDirectory(this.globalFieldsDirPath); + log.debug('Created global fields directory.', this.exportConfig.context); + + await this.getGlobalFields(); + log.debug(`Retrieved ${this.globalFields.length} global fields.`, this.exportConfig.context); + + const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName); + log.debug(`Writing global fields to: '${globalFieldsFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(globalFieldsFilePath, this.globalFields); + + log.success( + messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), + this.exportConfig.context, + ); + } catch (error) { + log.debug('An error occurred during global fields export.', this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); + } + } + + async getGlobalFields(skip: number = 0): Promise { if (skip) { this.qs.skip = skip; log.debug(`Fetching global fields with skip: ${skip}.`, this.exportConfig.context); } log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context); - - const globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find(); - - log.debug(`Fetched ${globalFieldsFetchResponse.items?.length || 0} global fields out of ${globalFieldsFetchResponse.count}.`, this.exportConfig.context); - + + let globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find(); + + log.debug( + `Fetched ${globalFieldsFetchResponse.items?.length || 0} global fields out of ${ + globalFieldsFetchResponse.count + }.`, + this.exportConfig.context, + ); + if (Array.isArray(globalFieldsFetchResponse.items) && globalFieldsFetchResponse.items.length > 0) { log.debug(`Processing ${globalFieldsFetchResponse.items.length} global fields...`, this.exportConfig.context); this.sanitizeAttribs(globalFieldsFetchResponse.items); @@ -81,42 +104,21 @@ export default class GlobalFieldsExport extends BaseClass { sanitizeAttribs(globalFields: Record[]) { log.debug(`Sanitizing ${globalFields.length} global fields...`, this.exportConfig.context); - + globalFields.forEach((globalField: Record) => { log.debug(`Processing global field: '${globalField.uid || 'unknown'}'...`, this.exportConfig.context); - - for (const key in globalField) { + + for (let key in globalField) { if (this.globalFieldsConfig.validKeys.indexOf(key) === -1) { delete globalField[key]; } } this.globalFields.push(globalField); }); - - log.debug(`Sanitization complete. Total global fields processed: ${this.globalFields.length}.`, this.exportConfig.context); - } - async start() { - try { - log.debug('Starting export process for global fields...', this.exportConfig.context); - log.debug(`Global fields directory path: '${this.globalFieldsDirPath}'`, this.exportConfig.context); - await fsUtil.makeDirectory(this.globalFieldsDirPath); - log.debug('Created global fields directory.', this.exportConfig.context); - - await this.getGlobalFields(); - log.debug(`Retrieved ${this.globalFields.length} global fields.`, this.exportConfig.context); - - const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName); - log.debug(`Writing global fields to: '${globalFieldsFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(globalFieldsFilePath, this.globalFields); - - log.success( - messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), - this.exportConfig.context, - ); - } catch (error) { - log.debug('An error occurred during global fields export.', this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context }); - } + log.debug( + `Sanitization complete. Total global fields processed: ${this.globalFields.length}.`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/index.ts b/packages/contentstack-export/src/export/modules/index.ts index e9025b1cd..ca0896b44 100644 --- a/packages/contentstack-export/src/export/modules/index.ts +++ b/packages/contentstack-export/src/export/modules/index.ts @@ -1,5 +1,4 @@ import { handleAndLogError } from '@contentstack/cli-utilities'; - import { ModuleClassParams } from '../../types'; export default async function startModuleExport(modulePayload: ModuleClassParams) { @@ -12,7 +11,7 @@ export default async function startModuleExport(modulePayload: ModuleClassParams ...modulePayload.exportConfig.context, module: modulePayload.moduleName, }); - throw error; + throw error; } } diff --git a/packages/contentstack-export/src/export/modules/labels.ts b/packages/contentstack-export/src/export/modules/labels.ts index a9c773973..c639aca60 100644 --- a/packages/contentstack-export/src/export/modules/labels.ts +++ b/packages/contentstack-export/src/export/modules/labels.ts @@ -1,16 +1,16 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { LabelConfig, ModuleClassParams } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { LabelConfig, ModuleClassParams } from '../../types'; export default class ExportLabels extends BaseClass { - public labelsFolderPath: string; - private labelConfig: LabelConfig; private labels: Record>; + private labelConfig: LabelConfig; + public labelsFolderPath: string; private qs: { include_count: boolean; skip?: number; @@ -24,6 +24,35 @@ export default class ExportLabels extends BaseClass { this.exportConfig.context.module = 'labels'; } + async start(): Promise { + log.debug('Starting export process for labels...', this.exportConfig.context); + + this.labelsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.labelConfig.dirName, + ); + log.debug(`Labels folder path: '${this.labelsFolderPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.labelsFolderPath); + log.debug('Created labels directory.', this.exportConfig.context); + + await this.getLabels(); + log.debug(`Retrieved ${Object.keys(this.labels).length} labels.`, this.exportConfig.context); + + if (this.labels === undefined || isEmpty(this.labels)) { + log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); + } else { + const labelsFilePath = pResolve(this.labelsFolderPath, this.labelConfig.fileName); + log.debug(`Writing labels to: '${labelsFilePath}'.`, this.exportConfig.context); + fsUtil.writeFile(labelsFilePath, this.labels); + log.success( + messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), + this.exportConfig.context, + ); + } + } + async getLabels(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -31,17 +60,17 @@ export default class ExportLabels extends BaseClass { } else { log.debug('Fetching labels with initial query...', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context); - + await this.stack .label() .query(this.qs) .find() .then(async (data: any) => { - const { count, items } = data; + const { items, count } = data; log.debug(`Fetched ${items?.length || 0} labels out of ${count}.`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} labels...`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -64,45 +93,19 @@ export default class ExportLabels extends BaseClass { sanitizeAttribs(labels: Record[]) { log.debug(`Sanitizing ${labels.length} labels...`, this.exportConfig.context); - + for (let index = 0; index < labels?.length; index++) { const labelUid = labels[index].uid; const labelName = labels[index]?.name; log.debug(`Processing label: '${labelName}' (UID: ${labelUid})...`, this.exportConfig.context); - + this.labels[labelUid] = omit(labels[index], this.labelConfig.invalidKeys); log.info(messageHandler.parse('LABEL_EXPORT_SUCCESS', labelName), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total labels processed: ${Object.keys(this.labels).length}.`, this.exportConfig.context); - } - async start(): Promise { - log.debug('Starting export process for labels...', this.exportConfig.context); - - this.labelsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.labelConfig.dirName, + log.debug( + `Sanitization complete. Total labels processed: ${Object.keys(this.labels).length}.`, + this.exportConfig.context, ); - log.debug(`Labels folder path: '${this.labelsFolderPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.labelsFolderPath); - log.debug('Created labels directory.', this.exportConfig.context); - - await this.getLabels(); - log.debug(`Retrieved ${Object.keys(this.labels).length} labels.`, this.exportConfig.context); - - if (this.labels === undefined || isEmpty(this.labels)) { - log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); - } else { - const labelsFilePath = pResolve(this.labelsFolderPath, this.labelConfig.fileName); - log.debug(`Writing labels to: '${labelsFilePath}'.`, this.exportConfig.context); - fsUtil.writeFile(labelsFilePath, this.labels); - log.success( - messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), - this.exportConfig.context, - ); - } } } diff --git a/packages/contentstack-export/src/export/modules/locales.ts b/packages/contentstack-export/src/export/modules/locales.ts index 9f522f6d9..4ff73240b 100644 --- a/packages/contentstack-export/src/export/modules/locales.ts +++ b/packages/contentstack-export/src/export/modules/locales.ts @@ -1,39 +1,33 @@ -import { - ContentstackClient, - handleAndLogError, - log, - messageHandler, - sanitizePath, -} from '@contentstack/cli-utilities'; import * as path from 'path'; +import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; -import { ExportConfig, ModuleClassParams } from '../../types'; import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { ExportConfig, ModuleClassParams } from '../../types'; export default class LocaleExport extends BaseClass { + private stackAPIClient: ReturnType; public exportConfig: ExportConfig; - private localeConfig: { - dirName?: string; - fetchConcurrency?: number; - fileName?: string; - limit?: number; - requiredKeys?: string[]; - writeConcurrency?: number; - }; - private locales: Record>; - private localesPath: string; - private masterLocale: Record>; private masterLocaleConfig: { dirName: string; fileName: string; requiredKeys: string[] }; private qs: { - asc: string; include_count: boolean; + asc: string; only: { BASE: string[]; }; skip?: number; }; - private stackAPIClient: ReturnType; + private localeConfig: { + dirName?: string; + fileName?: string; + requiredKeys?: string[]; + fetchConcurrency?: number; + writeConcurrency?: number; + limit?: number; + }; + private localesPath: string; + private masterLocale: Record>; + private locales: Record>; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -41,8 +35,8 @@ export default class LocaleExport extends BaseClass { this.localeConfig = exportConfig.modules.locales; this.masterLocaleConfig = exportConfig.modules.masterLocale; this.qs = { - asc: 'updated_at', include_count: true, + asc: 'updated_at', only: { BASE: this.localeConfig.requiredKeys, }, @@ -57,21 +51,63 @@ export default class LocaleExport extends BaseClass { this.exportConfig.context.module = 'locales'; } - async getLocales(skip = 0): Promise { + async start() { + try { + log.debug('Starting export process for locales...', this.exportConfig.context); + log.debug(`Locales path: '${this.localesPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.localesPath); + log.debug('Created locales directory.', this.exportConfig.context); + + await this.getLocales(); + log.debug( + `Retrieved ${Object.keys(this.locales).length} locales and ${ + Object.keys(this.masterLocale).length + } master locales.`, + this.exportConfig.context, + ); + + const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName); + const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName); + + log.debug(`Writing locales to: '${localesFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(localesFilePath, this.locales); + + log.debug(`Writing master locale to: '${masterLocaleFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(masterLocaleFilePath, this.masterLocale); + + log.success( + messageHandler.parse( + 'LOCALES_EXPORT_COMPLETE', + Object.keys(this.locales).length, + Object.keys(this.masterLocale).length, + ), + this.exportConfig.context, + ); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + throw error; + } + } + + async getLocales(skip: number = 0): Promise { if (skip) { this.qs.skip = skip; log.debug(`Fetching locales with skip: ${skip}.`, this.exportConfig.context); } log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context); - - const localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find(); - - log.debug(`Fetched ${localesFetchResponse.items?.length || 0} locales out of ${localesFetchResponse.count}.`, this.exportConfig.context); - + + let localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find(); + + log.debug( + `Fetched ${localesFetchResponse.items?.length || 0} locales out of ${localesFetchResponse.count}.`, + this.exportConfig.context, + ); + if (Array.isArray(localesFetchResponse.items) && localesFetchResponse.items.length > 0) { log.debug(`Processing ${localesFetchResponse.items.length} locales...`, this.exportConfig.context); this.sanitizeAttribs(localesFetchResponse.items); - + skip += this.localeConfig.limit || 100; if (skip > localesFetchResponse.count) { log.debug('Completed fetching all locales.', this.exportConfig.context); @@ -86,9 +122,9 @@ export default class LocaleExport extends BaseClass { sanitizeAttribs(locales: Record[]) { log.debug(`Sanitizing ${locales.length} locales...`, this.exportConfig.context); - + locales.forEach((locale: Record) => { - for (const key in locale) { + for (let key in locale) { if (this.localeConfig.requiredKeys.indexOf(key) === -1) { delete locale[key]; } @@ -102,41 +138,12 @@ export default class LocaleExport extends BaseClass { this.locales[locale.uid] = locale; } }); - - log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale).length}, Regular locales: ${Object.keys(this.locales).length}.`, this.exportConfig.context); - } - async start() { - try { - log.debug('Starting export process for locales...', this.exportConfig.context); - log.debug(`Locales path: '${this.localesPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.localesPath); - log.debug('Created locales directory.', this.exportConfig.context); - - await this.getLocales(); - log.debug(`Retrieved ${Object.keys(this.locales).length} locales and ${Object.keys(this.masterLocale).length} master locales.`, this.exportConfig.context); - - const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName); - const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName); - - log.debug(`Writing locales to: '${localesFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(localesFilePath, this.locales); - - log.debug(`Writing master locale to: '${masterLocaleFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(masterLocaleFilePath, this.masterLocale); - - log.success( - messageHandler.parse( - 'LOCALES_EXPORT_COMPLETE', - Object.keys(this.locales).length, - Object.keys(this.masterLocale).length, - ), - this.exportConfig.context, - ); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); - throw error; - } + log.debug( + `Sanitization complete. Master locales: ${Object.keys(this.masterLocale).length}, Regular locales: ${ + Object.keys(this.locales).length + }.`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/marketplace-apps.ts b/packages/contentstack-export/src/export/modules/marketplace-apps.ts index 0e08ae2e9..50cd0b761 100644 --- a/packages/contentstack-export/src/export/modules/marketplace-apps.ts +++ b/packages/contentstack-export/src/export/modules/marketplace-apps.ts @@ -1,42 +1,79 @@ +import map from 'lodash/map'; +import has from 'lodash/has'; +import find from 'lodash/find'; +import omitBy from 'lodash/omitBy'; +import entries from 'lodash/entries'; +import isEmpty from 'lodash/isEmpty'; +import { resolve as pResolve } from 'node:path'; import { Command } from '@contentstack/cli-command'; import { - ContentstackMarketplaceClient, - NodeCrypto, cliux, - handleAndLogError, + NodeCrypto, isAuthenticated, - log, marketplaceSDKClient, + ContentstackMarketplaceClient, + log, messageHandler, + handleAndLogError, } from '@contentstack/cli-utilities'; -import entries from 'lodash/entries'; -import find from 'lodash/find'; -import has from 'lodash/has'; -import isEmpty from 'lodash/isEmpty'; -import map from 'lodash/map'; -import omitBy from 'lodash/omitBy'; -import { resolve as pResolve } from 'node:path'; -import { ExportConfig, Installation, Manifest, MarketplaceAppsConfig, ModuleClassParams } from '../../types'; -import { createNodeCryptoInstance, fsUtil, getDeveloperHubUrl, getOrgUid } from '../../utils'; +import { fsUtil, getOrgUid, createNodeCryptoInstance, getDeveloperHubUrl } from '../../utils'; +import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation, Manifest } from '../../types'; export default class ExportMarketplaceApps { - public appSdk: ContentstackMarketplaceClient; - public command: Command; - public developerHubBaseUrl: string; - public exportConfig: ExportConfig; - protected installedApps: Installation[] = []; protected marketplaceAppConfig: MarketplaceAppsConfig; + protected installedApps: Installation[] = []; + public developerHubBaseUrl: string; public marketplaceAppPath: string; public nodeCrypto: NodeCrypto; + public appSdk: ContentstackMarketplaceClient; + public exportConfig: ExportConfig; + public command: Command; public query: Record; - constructor({ exportConfig }: Omit) { + constructor({ exportConfig }: Omit) { this.exportConfig = exportConfig; this.marketplaceAppConfig = exportConfig.modules.marketplace_apps; this.exportConfig.context.module = 'marketplace-apps'; } + async start(): Promise { + log.debug('Starting export process for Marketplace Apps...', this.exportConfig.context); + + if (!isAuthenticated()) { + cliux.print( + 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', + { color: 'yellow' }, + ); + return Promise.resolve(); + } + + this.marketplaceAppPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.marketplaceAppConfig.dirName, + ); + log.debug(`Marketplace apps folder path: '${this.marketplaceAppPath}'`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.marketplaceAppPath); + log.debug('Created Marketplace Apps directory.', this.exportConfig.context); + + this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await getDeveloperHubUrl(this.exportConfig)); + log.debug(`Developer Hub base URL: '${this.developerHubBaseUrl}'`, this.exportConfig.context); + + this.exportConfig.org_uid = await getOrgUid(this.exportConfig); + this.query = { target_uids: this.exportConfig.source_stack }; + log.debug(`Organization UID: '${this.exportConfig.org_uid}'.`, this.exportConfig.context); + + // NOTE init marketplace app sdk + const host = this.developerHubBaseUrl.split('://').pop(); + log.debug(`Initializing Marketplace SDK with host: '${host}'...`, this.exportConfig.context); + this.appSdk = await marketplaceSDKClient({ host }); + + await this.exportApps(); + log.debug('Marketplace apps export process completed.', this.exportConfig.context); + } + /** * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto * library if it is available. @@ -53,10 +90,10 @@ export default class ExportMarketplaceApps { this.query.installation_uids = externalQuery.installation_uid?.$in?.join(','); } } - + await this.getStackSpecificApps(); log.debug(`Retrieved ${this.installedApps.length} stack-specific apps.`, this.exportConfig.context); - + await this.getAppManifestAndAppConfig(); log.debug('Completed app manifest and configuration processing.', this.exportConfig.context); @@ -72,10 +109,88 @@ export default class ExportMarketplaceApps { } return app; }); - + log.debug(`Processed ${this.installedApps.length} Marketplace Apps.`, this.exportConfig.context); } + /** + * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed + * marketplace apps. + */ + async getAppManifestAndAppConfig(): Promise { + if (isEmpty(this.installedApps)) { + log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); + } else { + log.debug(`Processing ${this.installedApps.length} installed apps...`, this.exportConfig.context); + + for (const [index, app] of entries(this.installedApps)) { + if (app.manifest.visibility === 'private') { + log.debug(`Processing private app manifest: '${app.manifest.name}'...`, this.exportConfig.context); + await this.getPrivateAppsManifest(+index, app); + } + } + + for (const [index, app] of entries(this.installedApps)) { + log.debug( + `Processing app configurations for: '${app.manifest?.name || app.uid}'...`, + this.exportConfig.context, + ); + await this.getAppConfigurations(+index, app); + } + + const marketplaceAppsFilePath = pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName); + log.debug(`Writing Marketplace Apps to: '${marketplaceAppsFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps); + + log.success( + messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), + this.exportConfig.context, + ); + } + } + + /** + * The function `getPrivateAppsManifest` fetches the manifest of a private app and assigns it to the + * `manifest` property of the corresponding installed app. + * @param {number} index - The `index` parameter is a number that represents the position of the app + * in an array or list. It is used to identify the specific app in the `installedApps` array. + * @param {App} appInstallation - The `appInstallation` parameter is an object that represents the + * installation details of an app. It contains information such as the UID (unique identifier) of the + * app's manifest. + */ + async getPrivateAppsManifest(index: number, appInstallation: Installation) { + log.debug( + `Fetching private app manifest for: '${appInstallation.manifest.name}' (UID: ${appInstallation.manifest.uid})...`, + this.exportConfig.context, + ); + + const manifest = await this.appSdk + .marketplace(this.exportConfig.org_uid) + .app(appInstallation.manifest.uid) + .fetch({ include_oauth: true }) + .catch((error) => { + log.debug( + `Failed to fetch private app manifest for: '${appInstallation.manifest.name}'.`, + this.exportConfig.context, + ); + handleAndLogError( + error, + { + ...this.exportConfig.context, + }, + messageHandler.parse('MARKETPLACE_APP_MANIFEST_EXPORT_FAILED', appInstallation.manifest.name), + ); + }); + + if (manifest) { + log.debug( + `Successfully fetched private app manifest for: '${appInstallation.manifest.name}'.`, + this.exportConfig.context, + ); + this.installedApps[index].manifest = manifest as unknown as Manifest; + } + } + /** * The function `getAppConfigurations` exports the configuration of an app installation and encrypts * the server configuration if it exists. @@ -102,7 +217,7 @@ export default class ExportMarketplaceApps { if (has(data, 'server_configuration') || has(data, 'configuration')) { log.debug(`Found configuration data for app: '${app}'.`, this.exportConfig.context); - + if (!this.nodeCrypto && (has(data, 'server_configuration') || has(data, 'configuration'))) { log.debug(`Initializing NodeCrypto for app: '${app}'...`, this.exportConfig.context); this.nodeCrypto = await createNodeCryptoInstance(this.exportConfig); @@ -143,72 +258,6 @@ export default class ExportMarketplaceApps { }); } - /** - * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed - * marketplace apps. - */ - async getAppManifestAndAppConfig(): Promise { - if (isEmpty(this.installedApps)) { - log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); - } else { - log.debug(`Processing ${this.installedApps.length} installed apps...`, this.exportConfig.context); - - for (const [index, app] of entries(this.installedApps)) { - if (app.manifest.visibility === 'private') { - log.debug(`Processing private app manifest: '${app.manifest.name}'...`, this.exportConfig.context); - await this.getPrivateAppsManifest(+index, app); - } - } - - for (const [index, app] of entries(this.installedApps)) { - log.debug(`Processing app configurations for: '${app.manifest?.name || app.uid}'...`, this.exportConfig.context); - await this.getAppConfigurations(+index, app); - } - - const marketplaceAppsFilePath = pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName); - log.debug(`Writing Marketplace Apps to: '${marketplaceAppsFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps); - - log.success( - messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), - this.exportConfig.context, - ); - } - } - - /** - * The function `getPrivateAppsManifest` fetches the manifest of a private app and assigns it to the - * `manifest` property of the corresponding installed app. - * @param {number} index - The `index` parameter is a number that represents the position of the app - * in an array or list. It is used to identify the specific app in the `installedApps` array. - * @param {App} appInstallation - The `appInstallation` parameter is an object that represents the - * installation details of an app. It contains information such as the UID (unique identifier) of the - * app's manifest. - */ - async getPrivateAppsManifest(index: number, appInstallation: Installation) { - log.debug(`Fetching private app manifest for: '${appInstallation.manifest.name}' (UID: ${appInstallation.manifest.uid})...`, this.exportConfig.context); - - const manifest = await this.appSdk - .marketplace(this.exportConfig.org_uid) - .app(appInstallation.manifest.uid) - .fetch({ include_oauth: true }) - .catch((error) => { - log.debug(`Failed to fetch private app manifest for: '${appInstallation.manifest.name}'.`, this.exportConfig.context); - handleAndLogError( - error, - { - ...this.exportConfig.context, - }, - messageHandler.parse('MARKETPLACE_APP_MANIFEST_EXPORT_FAILED', appInstallation.manifest.name), - ); - }); - - if (manifest) { - log.debug(`Successfully fetched private app manifest for: '${appInstallation.manifest.name}'.`, this.exportConfig.context); - this.installedApps[index].manifest = manifest as unknown as Manifest; - } - } - /** * The function `getStackSpecificApps` retrieves a collection of marketplace apps specific to a stack * and stores them in the `installedApps` array. @@ -217,7 +266,7 @@ export default class ExportMarketplaceApps { * the API. In this code, it is initially set to 0, indicating that no items should be skipped in */ async getStackSpecificApps(skip = 0) { - log.debug(`Fetching stack-specific apps with skip: ${skip}`, this.exportConfig.context); + log.debug(`Fetching stack-specific apps with skip: ${skip}`, this.exportConfig.context); const collection = await this.appSdk .marketplace(this.exportConfig.org_uid) .installation() @@ -230,9 +279,9 @@ export default class ExportMarketplaceApps { }); if (collection) { - const { count, items: apps } = collection; + const { items: apps, count } = collection; log.debug(`Fetched ${apps?.length || 0} apps out of ${count}.`, this.exportConfig.context); - + // NOTE Remove all the chain functions const installation = map(apps, (app) => omitBy(app, (val, _key) => { @@ -240,7 +289,7 @@ export default class ExportMarketplaceApps { return false; }), ) as unknown as Installation[]; - + log.debug(`Processed ${installation.length} app installations.`, this.exportConfig.context); this.installedApps = this.installedApps.concat(installation); @@ -252,41 +301,4 @@ export default class ExportMarketplaceApps { } } } - - async start(): Promise { - log.debug('Starting export process for Marketplace Apps...', this.exportConfig.context); - - if (!isAuthenticated()) { - cliux.print( - 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', - { color: 'yellow' }, - ); - return Promise.resolve(); - } - - this.marketplaceAppPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.marketplaceAppConfig.dirName, - ); - log.debug(`Marketplace apps folder path: '${this.marketplaceAppPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.marketplaceAppPath); - log.debug('Created Marketplace Apps directory.', this.exportConfig.context); - - this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await getDeveloperHubUrl(this.exportConfig)); - log.debug(`Developer Hub base URL: '${this.developerHubBaseUrl}'`, this.exportConfig.context); - - this.exportConfig.org_uid = await getOrgUid(this.exportConfig); - this.query = { target_uids: this.exportConfig.source_stack }; - log.debug(`Organization UID: '${this.exportConfig.org_uid}'.`, this.exportConfig.context); - - // NOTE init marketplace app sdk - const host = this.developerHubBaseUrl.split('://').pop(); - log.debug(`Initializing Marketplace SDK with host: '${host}'...`, this.exportConfig.context); - this.appSdk = await marketplaceSDKClient({ host }); - - await this.exportApps(); - log.debug('Marketplace apps export process completed.', this.exportConfig.context); - } } diff --git a/packages/contentstack-export/src/export/modules/personalize.ts b/packages/contentstack-export/src/export/modules/personalize.ts index e154321c5..deffcd50b 100644 --- a/packages/contentstack-export/src/export/modules/personalize.ts +++ b/packages/contentstack-export/src/export/modules/personalize.ts @@ -1,18 +1,18 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; import { - AnyProperty, + ExportProjects, + ExportExperiences, + ExportEvents, ExportAttributes, ExportAudiences, - ExportEvents, - ExportExperiences, - ExportProjects, + AnyProperty, } from '@contentstack/cli-variants'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { ExportConfig, ModuleClassParams } from '../../types'; +import { ModuleClassParams, ExportConfig } from '../../types'; export default class ExportPersonalize { public exportConfig: ExportConfig; - public personalizeConfig: { baseURL: Record; dirName: string } & AnyProperty; + public personalizeConfig: { dirName: string; baseURL: Record } & AnyProperty; constructor({ exportConfig }: ModuleClassParams) { this.exportConfig = exportConfig; this.personalizeConfig = exportConfig.modules.personalize; @@ -22,31 +22,35 @@ export default class ExportPersonalize { async start(): Promise { try { log.debug('Starting export process for Personalize...', this.exportConfig.context); - + if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) { log.debug(`Personalize URL not set for region: '${this.exportConfig.region.name}'.`, this.exportConfig.context); log.info(messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } - + if (this.exportConfig.management_token) { log.debug('Management token detected, skipping personalize export.', this.exportConfig.context); log.info(messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context); this.exportConfig.personalizationEnabled = false; return; } - + log.debug('Starting export process for personalization projects...', this.exportConfig.context); await new ExportProjects(this.exportConfig).start(); - + if (this.exportConfig.personalizationEnabled) { - log.debug('Personalization is enabled, processing personalize modules... ' + this.exportConfig.modules.personalize.exportOrder.join(', '), this.exportConfig.context); - + log.debug( + 'Personalization is enabled, processing personalize modules... ' + + this.exportConfig.modules.personalize.exportOrder.join(', '), + this.exportConfig.context, + ); + const moduleMapper = { + events: new ExportEvents(this.exportConfig), attributes: new ExportAttributes(this.exportConfig), audiences: new ExportAudiences(this.exportConfig), - events: new ExportEvents(this.exportConfig), experiences: new ExportExperiences(this.exportConfig), }; @@ -54,23 +58,20 @@ export default class ExportPersonalize { .exportOrder as (keyof typeof moduleMapper)[]; log.debug(`Personalize export order: ${order.join(', ')}.`, this.exportConfig.context); - + for (const module of order) { log.debug(`Processing personalization module: '${module}'...`, this.exportConfig.context); - + if (moduleMapper[module]) { log.debug(`Starting export for module: '${module}'...`, this.exportConfig.context); await moduleMapper[module].start(); log.debug(`Completed export for module: '${module}'.`, this.exportConfig.context); } else { log.debug(`Module not implemented: '${module}'.`, this.exportConfig.context); - log.info( - messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), - this.exportConfig.context, - ); + log.info(messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context); } } - + log.debug('Completed all personalization module exports.', this.exportConfig.context); } else { log.debug('Personalization is disabled, skipping personalize module exports.', this.exportConfig.context); diff --git a/packages/contentstack-export/src/export/modules/publishing-rules.ts b/packages/contentstack-export/src/export/modules/publishing-rules.ts index fee752b10..86be31dee 100644 --- a/packages/contentstack-export/src/export/modules/publishing-rules.ts +++ b/packages/contentstack-export/src/export/modules/publishing-rules.ts @@ -1,11 +1,11 @@ -import { handleAndLogError, log } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, log } from '@contentstack/cli-utilities'; -import { ModuleClassParams, PublishingRulesConfig } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { PublishingRulesConfig, ModuleClassParams } from '../../types'; export default class ExportPublishingRules extends BaseClass { private readonly publishingRules: Record> = {}; @@ -52,7 +52,7 @@ export default class ExportPublishingRules extends BaseClass { this.qs.skip = skip; } - const data: { count?: number; items?: Record[] } = await this.stack + const data: { items?: Record[]; count?: number } = await this.stack .workflow() .publishRule() .fetchAll(this.qs); @@ -68,10 +68,7 @@ export default class ExportPublishingRules extends BaseClass { for (const rule of items) { const uid = rule.uid as string | undefined; if (uid) { - this.publishingRules[uid] = omit(rule, this.publishingRulesConfig.invalidKeys) as Record< - string, - unknown - >; + this.publishingRules[uid] = omit(rule, this.publishingRulesConfig.invalidKeys) as Record; } } diff --git a/packages/contentstack-export/src/export/modules/stack.ts b/packages/contentstack-export/src/export/modules/stack.ts index 92ee1f9b3..bfe6d7c93 100644 --- a/packages/contentstack-export/src/export/modules/stack.ts +++ b/packages/contentstack-export/src/export/modules/stack.ts @@ -1,18 +1,18 @@ -import { handleAndLogError, isAuthenticated, log, managementSDKClient } from '@contentstack/cli-utilities'; import find from 'lodash/find'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, isAuthenticated, managementSDKClient, log } from '@contentstack/cli-utilities'; -import { ModuleClassParams, StackConfig } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { StackConfig, ModuleClassParams } from '../../types'; export default class ExportStack extends BaseClass { + private stackConfig: StackConfig; + private stackFolderPath: string; private qs: { include_count: boolean; skip?: number; }; - private stackConfig: StackConfig; - private stackFolderPath: string; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -26,47 +26,70 @@ export default class ExportStack extends BaseClass { this.exportConfig.context.module = 'stack'; } - async exportStack(): Promise { - log.debug(`Starting stack export for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); + async start(): Promise { + log.debug('Starting stack export process...', this.exportConfig.context); - await fsUtil.makeDirectory(this.stackFolderPath); - log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context); + if (isAuthenticated()) { + log.debug('User authenticated.', this.exportConfig.context); + const stackData = await this.getStack(); + if (stackData?.org_uid) { + log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context); + this.exportConfig.org_uid = stackData.org_uid; + this.exportConfig.sourceStackName = stackData.name; + log.debug(`Set source stack name: '${stackData.name}'.`, this.exportConfig.context); + } else { + log.debug('No stack data found or missing organization UID.', this.exportConfig.context); + } + } else { + log.debug('User is not authenticated.', this.exportConfig.context); + } - return this.stack + if (this.exportConfig.management_token) { + log.info( + 'Skipping stack settings export: Operation is not supported when using a management token.', + this.exportConfig.context, + ); + } else { + await this.exportStackSettings(); + } + if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { + log.debug( + 'Preserve stack version is false and master locale not set, fetching locales...', + this.exportConfig.context, + ); + //fetch master locale details + return this.getLocales(); + } else if (this.exportConfig.preserveStackVersion) { + log.debug('Preserve stack version is set to true.', this.exportConfig.context); + return this.exportStack(); + } else { + log.debug('Master locale is already set.', this.exportConfig.context); + } + } + + async getStack(): Promise { + log.debug(`Fetching stack data for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); + + const tempAPIClient = await managementSDKClient({ host: this.exportConfig.host }); + log.debug(`Created Management SDK client with host: '${this.exportConfig.host}'.`, this.exportConfig.context); + + return await tempAPIClient + .stack({ api_key: this.exportConfig.source_stack }) .fetch() - .then((resp: any) => { - const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName); - log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context); - fsUtil.writeFile(stackFilePath, resp); - log.success( - `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, + .then((data: any) => { + log.debug( + `Successfully fetched stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context, ); - log.debug('Stack export completed successfully.', this.exportConfig.context); - return resp; - }) - .catch((error: any) => { - log.debug(`An error occurred while exporting stack: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context }); - }); - } - - async exportStackSettings(): Promise { - log.info('Exporting stack settings...', this.exportConfig.context); - await fsUtil.makeDirectory(this.stackFolderPath); - return this.stack - .settings() - .then((resp: any) => { - fsUtil.writeFile(pResolve(this.stackFolderPath, 'settings.json'), resp); - log.success('Exported stack settings successfully!', this.exportConfig.context); - return resp; + return data; }) .catch((error: any) => { - handleAndLogError(error, { ...this.exportConfig.context }); + log.debug(`Failed to fetch stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); + return {}; }); } - async getLocales(skip = 0) { + async getLocales(skip: number = 0) { if (skip) { this.qs.skip = skip; log.debug(`Fetching locales with skip: ${skip}.`, this.exportConfig.context); @@ -81,7 +104,7 @@ export default class ExportStack extends BaseClass { .query(this.qs) .find() .then(async (data: any) => { - const { count, items } = data; + const { items, count } = data; log.debug(`Fetched ${items?.length || 0} locales out of ${count}.`, this.exportConfig.context); if (items?.length) { @@ -128,63 +151,46 @@ export default class ExportStack extends BaseClass { }); } - async getStack(): Promise { - log.debug(`Fetching stack data for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); + async exportStack(): Promise { + log.debug(`Starting stack export for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context); - const tempAPIClient = await managementSDKClient({ host: this.exportConfig.host }); - log.debug(`Created Management SDK client with host: '${this.exportConfig.host}'.`, this.exportConfig.context); + await fsUtil.makeDirectory(this.stackFolderPath); + log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context); - return await tempAPIClient - .stack({ api_key: this.exportConfig.source_stack }) + return this.stack .fetch() - .then((data: any) => { - log.debug(`Successfully fetched stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); - return data; + .then((resp: any) => { + const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName); + log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context); + fsUtil.writeFile(stackFilePath, resp); + log.success( + `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, + this.exportConfig.context, + ); + log.debug('Stack export completed successfully.', this.exportConfig.context); + return resp; }) .catch((error: any) => { - log.debug(`Failed to fetch stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context); - return {}; + log.debug( + `An error occurred while exporting stack: '${this.exportConfig.source_stack}'.`, + this.exportConfig.context, + ); + handleAndLogError(error, { ...this.exportConfig.context }); }); } - async start(): Promise { - log.debug('Starting stack export process...', this.exportConfig.context); - - if (isAuthenticated()) { - log.debug('User authenticated.', this.exportConfig.context); - const stackData = await this.getStack(); - if (stackData?.org_uid) { - log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context); - this.exportConfig.org_uid = stackData.org_uid; - this.exportConfig.sourceStackName = stackData.name; - log.debug(`Set source stack name: '${stackData.name}'.`, this.exportConfig.context); - } else { - log.debug('No stack data found or missing organization UID.', this.exportConfig.context); - } - } else { - log.debug('User is not authenticated.', this.exportConfig.context); - } - - if (this.exportConfig.management_token) { - log.info( - 'Skipping stack settings export: Operation is not supported when using a management token.', - this.exportConfig.context, - ); - } else { - await this.exportStackSettings(); - } - if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { - log.debug( - 'Preserve stack version is false and master locale not set, fetching locales...', - this.exportConfig.context, - ); - //fetch master locale details - return this.getLocales(); - } else if (this.exportConfig.preserveStackVersion) { - log.debug('Preserve stack version is set to true.', this.exportConfig.context); - return this.exportStack(); - } else { - log.debug('Master locale is already set.', this.exportConfig.context); - } + async exportStackSettings(): Promise { + log.info('Exporting stack settings...', this.exportConfig.context); + await fsUtil.makeDirectory(this.stackFolderPath); + return this.stack + .settings() + .then((resp: any) => { + fsUtil.writeFile(pResolve(this.stackFolderPath, 'settings.json'), resp); + log.success('Exported stack settings successfully!', this.exportConfig.context); + return resp; + }) + .catch((error: any) => { + handleAndLogError(error, { ...this.exportConfig.context }); + }); } } diff --git a/packages/contentstack-export/src/export/modules/taxonomies.ts b/packages/contentstack-export/src/export/modules/taxonomies.ts index ae8cbc287..11ed9bb5c 100644 --- a/packages/contentstack-export/src/export/modules/taxonomies.ts +++ b/packages/contentstack-export/src/export/modules/taxonomies.ts @@ -1,30 +1,30 @@ -import { handleAndLogError, log, messageHandler, sanitizePath } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; -import keys from 'lodash/keys'; import omit from 'lodash/omit'; +import keys from 'lodash/keys'; +import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; -import { ExportConfig, ModuleClassParams } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { ModuleClassParams, ExportConfig } from '../../types'; export default class ExportTaxonomies extends BaseClass { - public taxonomiesFolderPath: string; - private isLocaleBasedExportSupported = true; - private localesFilePath: string; + private taxonomies: Record>; + private taxonomiesByLocale: Record>; + private taxonomiesConfig: ExportConfig['modules']['taxonomies']; + private isLocaleBasedExportSupported: boolean = true; // Flag to track if locale-based export is supported private qs: { - asc?: string; - branch?: string; - fallback_locale?: string; include_count: boolean; - include_fallback?: boolean; + skip: number; + asc?: string; limit: number; locale?: string; - skip: number; - }; // Flag to track if locale-based export is supported - private taxonomies: Record>; - private taxonomiesByLocale: Record>; - private taxonomiesConfig: ExportConfig['modules']['taxonomies']; + branch?: string; + include_fallback?: boolean; + fallback_locale?: string; + }; + public taxonomiesFolderPath: string; + private localesFilePath: string; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -43,57 +43,87 @@ export default class ExportTaxonomies extends BaseClass { ); } - /** - * Export taxonomies - supports both locale-based and legacy export - */ - async exportTaxonomies(localeCode?: string): Promise { - const taxonomiesUID = localeCode ? Array.from(this.taxonomiesByLocale[localeCode] || []) : keys(this.taxonomies); + async start(): Promise { + log.debug('Starting export process for taxonomies...', this.exportConfig.context); - const localeInfo = localeCode ? ` for locale: ${localeCode}` : ''; - if (taxonomiesUID.length === 0) { - log.debug(`No taxonomies to export${localeInfo}`, this.exportConfig.context); - return; - } - log.debug(`Exporting detailed data for ${taxonomiesUID.length} taxonomies${localeInfo}`, this.exportConfig.context); + //create taxonomies folder + this.taxonomiesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.taxonomiesConfig.dirName, + ); + log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context); - const exportFolderPath = localeCode ? pResolve(this.taxonomiesFolderPath, localeCode) : this.taxonomiesFolderPath; - if (localeCode) { - await fsUtil.makeDirectory(exportFolderPath); - log.debug(`Created locale folder: ${exportFolderPath}`, this.exportConfig.context); + await fsUtil.makeDirectory(this.taxonomiesFolderPath); + log.debug('Created taxonomies directory.', this.exportConfig.context); + + const localesToExport = this.getLocalesToExport(); + log.debug( + `Will attempt to export taxonomies for ${localesToExport.length} locale(s): ${localesToExport.join(', ')}`, + this.exportConfig.context, + ); + + if (localesToExport.length === 0) { + log.warn('No locales found to export', this.exportConfig.context); + return; } - const onSuccess = ({ response, uid }: any) => { - const filePath = pResolve(exportFolderPath, `${uid}.json`); - log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context); - fsUtil.writeFile(filePath, response); - log.success(messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), this.exportConfig.context); - }; + // Test locale-based export support with master locale + const masterLocale = this.exportConfig.master_locale?.code; + await this.fetchTaxonomies(masterLocale, true); - const onReject = ({ error, uid }: any) => { - log.debug(`Failed to export detailed data for taxonomy: ${uid}${localeInfo}`, this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context, uid, ...(localeCode && { locale: localeCode }) }); - }; + if (!this.isLocaleBasedExportSupported) { + this.taxonomies = {}; + this.taxonomiesByLocale = {}; - for (const taxonomyUID of taxonomiesUID) { - log.debug(`Processing detailed export for taxonomy: ${taxonomyUID}${localeInfo}`, this.exportConfig.context); + // Fetch taxonomies without locale parameter + await this.fetchTaxonomies(); + await this.exportTaxonomies(); + await this.writeTaxonomiesMetadata(); + } else { + // Process all locales with locale-based export + log.debug('Localization enabled, proceeding with locale-based export', this.exportConfig.context); - const exportParams: any = { format: 'json' }; - if (localeCode) { - exportParams.locale = localeCode; - if (this.qs.include_fallback !== undefined) exportParams.include_fallback = this.qs.include_fallback; - if (this.qs.fallback_locale) exportParams.fallback_locale = this.qs.fallback_locale; + for (const localeCode of localesToExport) { + await this.fetchTaxonomies(localeCode); + await this.processLocaleExport(localeCode); } - if (this.qs.branch) exportParams.branch = this.qs.branch; - await this.makeAPICall({ - module: 'export-taxonomy', - queryParam: exportParams, - reject: onReject, - resolve: onSuccess, - uid: taxonomyUID, - }); + await this.writeTaxonomiesMetadata(); + } + + log.success( + messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies || {}).length), + this.exportConfig.context, + ); + } + + /** + * Process and export taxonomies for a specific locale + */ + async processLocaleExport(localeCode: string): Promise { + const localeTaxonomies = this.taxonomiesByLocale[localeCode]; + + if (localeTaxonomies?.size > 0) { + log.info(`Found ${localeTaxonomies.size} taxonomies for locale: ${localeCode}`, this.exportConfig.context); + await this.exportTaxonomies(localeCode); + } else { + log.debug(`No taxonomies found for locale: ${localeCode}`, this.exportConfig.context); } - log.debug(`Completed detailed taxonomy export process${localeInfo}`, this.exportConfig.context); + } + + /** + * Write taxonomies metadata file + */ + async writeTaxonomiesMetadata(): Promise { + if (!this.taxonomies || isEmpty(this.taxonomies)) { + log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); + return; + } + + const taxonomiesFilePath = pResolve(this.taxonomiesFolderPath, 'taxonomies.json'); + log.debug(`Writing taxonomies metadata to: ${taxonomiesFilePath}`, this.exportConfig.context); + fsUtil.writeFile(taxonomiesFilePath, this.taxonomies); } /** @@ -104,7 +134,7 @@ export default class ExportTaxonomies extends BaseClass { * @param {boolean} [checkLocaleSupport=false] * @returns {Promise} */ - async fetchTaxonomies(localeCode?: string, checkLocaleSupport = false): Promise { + async fetchTaxonomies(localeCode?: string, checkLocaleSupport: boolean = false): Promise { let skip = 0; const localeInfo = localeCode ? `for locale: ${localeCode}` : ''; @@ -122,7 +152,7 @@ export default class ExportTaxonomies extends BaseClass { try { const data = await this.stack.taxonomy().query(queryParams).find(); - const { count, items } = data; + const { items, count } = data; const taxonomiesCount = count ?? items?.length ?? 0; log.debug( @@ -174,58 +204,6 @@ export default class ExportTaxonomies extends BaseClass { } while (true); } - /** - * Get all locales to export - */ - getLocalesToExport(): string[] { - log.debug('Determining locales to export...', this.exportConfig.context); - - const masterLocaleCode = this.exportConfig.master_locale?.code || 'en-us'; - const localeSet = new Set([masterLocaleCode]); - - try { - const locales = fsUtil.readFile(this.localesFilePath) as Record>; - - if (locales && keys(locales || {}).length > 0) { - log.debug( - `Loaded ${keys(locales || {}).length} locales from ${this.localesFilePath}`, - this.exportConfig.context, - ); - - for (const localeUid of keys(locales)) { - const localeCode = locales[localeUid].code; - if (localeCode && !localeSet.has(localeCode)) { - localeSet.add(localeCode); - log.debug(`Added locale: ${localeCode} (uid: ${localeUid})`, this.exportConfig.context); - } - } - } else { - log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); - } - } catch (error) { - log.warn(`Failed to read locales file: ${this.localesFilePath}`, this.exportConfig.context); - } - - const localesToExport = Array.from(localeSet); - log.debug(`Total unique locales to export: ${localesToExport.length}`, this.exportConfig.context); - - return localesToExport; - } - - /** - * Process and export taxonomies for a specific locale - */ - async processLocaleExport(localeCode: string): Promise { - const localeTaxonomies = this.taxonomiesByLocale[localeCode]; - - if (localeTaxonomies?.size > 0) { - log.info(`Found ${localeTaxonomies.size} taxonomies for locale: ${localeCode}`, this.exportConfig.context); - await this.exportTaxonomies(localeCode); - } else { - log.debug(`No taxonomies found for locale: ${localeCode}`, this.exportConfig.context); - } - } - /** * remove invalid keys and write data into taxonomies * @function sanitizeTaxonomiesAttribs @@ -259,73 +237,95 @@ export default class ExportTaxonomies extends BaseClass { ); } - async start(): Promise { - log.debug('Starting export process for taxonomies...', this.exportConfig.context); - - //create taxonomies folder - this.taxonomiesFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.taxonomiesConfig.dirName, - ); - log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.taxonomiesFolderPath); - log.debug('Created taxonomies directory.', this.exportConfig.context); - - const localesToExport = this.getLocalesToExport(); - log.debug( - `Will attempt to export taxonomies for ${localesToExport.length} locale(s): ${localesToExport.join(', ')}`, - this.exportConfig.context, - ); + /** + * Export taxonomies - supports both locale-based and legacy export + */ + async exportTaxonomies(localeCode?: string): Promise { + const taxonomiesUID = localeCode ? Array.from(this.taxonomiesByLocale[localeCode] || []) : keys(this.taxonomies); - if (localesToExport.length === 0) { - log.warn('No locales found to export', this.exportConfig.context); + const localeInfo = localeCode ? ` for locale: ${localeCode}` : ''; + if (taxonomiesUID.length === 0) { + log.debug(`No taxonomies to export${localeInfo}`, this.exportConfig.context); return; } + log.debug(`Exporting detailed data for ${taxonomiesUID.length} taxonomies${localeInfo}`, this.exportConfig.context); - // Test locale-based export support with master locale - const masterLocale = this.exportConfig.master_locale?.code; - await this.fetchTaxonomies(masterLocale, true); + const exportFolderPath = localeCode ? pResolve(this.taxonomiesFolderPath, localeCode) : this.taxonomiesFolderPath; + if (localeCode) { + await fsUtil.makeDirectory(exportFolderPath); + log.debug(`Created locale folder: ${exportFolderPath}`, this.exportConfig.context); + } - if (!this.isLocaleBasedExportSupported) { - this.taxonomies = {}; - this.taxonomiesByLocale = {}; + const onSuccess = ({ response, uid }: any) => { + const filePath = pResolve(exportFolderPath, `${uid}.json`); + log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context); + fsUtil.writeFile(filePath, response); + log.success(messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), this.exportConfig.context); + }; - // Fetch taxonomies without locale parameter - await this.fetchTaxonomies(); - await this.exportTaxonomies(); - await this.writeTaxonomiesMetadata(); - } else { - // Process all locales with locale-based export - log.debug('Localization enabled, proceeding with locale-based export', this.exportConfig.context); + const onReject = ({ error, uid }: any) => { + log.debug(`Failed to export detailed data for taxonomy: ${uid}${localeInfo}`, this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context, uid, ...(localeCode && { locale: localeCode }) }); + }; - for (const localeCode of localesToExport) { - await this.fetchTaxonomies(localeCode); - await this.processLocaleExport(localeCode); + for (const taxonomyUID of taxonomiesUID) { + log.debug(`Processing detailed export for taxonomy: ${taxonomyUID}${localeInfo}`, this.exportConfig.context); + + const exportParams: any = { format: 'json' }; + if (localeCode) { + exportParams.locale = localeCode; + if (this.qs.include_fallback !== undefined) exportParams.include_fallback = this.qs.include_fallback; + if (this.qs.fallback_locale) exportParams.fallback_locale = this.qs.fallback_locale; } + if (this.qs.branch) exportParams.branch = this.qs.branch; - await this.writeTaxonomiesMetadata(); + await this.makeAPICall({ + reject: onReject, + resolve: onSuccess, + uid: taxonomyUID, + module: 'export-taxonomy', + queryParam: exportParams, + }); } - - log.success( - messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies || {}).length), - this.exportConfig.context, - ); + log.debug(`Completed detailed taxonomy export process${localeInfo}`, this.exportConfig.context); } /** - * Write taxonomies metadata file + * Get all locales to export */ - async writeTaxonomiesMetadata(): Promise { - if (!this.taxonomies || isEmpty(this.taxonomies)) { - log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); - return; + getLocalesToExport(): string[] { + log.debug('Determining locales to export...', this.exportConfig.context); + + const masterLocaleCode = this.exportConfig.master_locale?.code || 'en-us'; + const localeSet = new Set([masterLocaleCode]); + + try { + const locales = fsUtil.readFile(this.localesFilePath) as Record>; + + if (locales && keys(locales || {}).length > 0) { + log.debug( + `Loaded ${keys(locales || {}).length} locales from ${this.localesFilePath}`, + this.exportConfig.context, + ); + + for (const localeUid of keys(locales)) { + const localeCode = locales[localeUid].code; + if (localeCode && !localeSet.has(localeCode)) { + localeSet.add(localeCode); + log.debug(`Added locale: ${localeCode} (uid: ${localeUid})`, this.exportConfig.context); + } + } + } else { + log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); + } + } catch (error) { + log.warn(`Failed to read locales file: ${this.localesFilePath}`, this.exportConfig.context); } - const taxonomiesFilePath = pResolve(this.taxonomiesFolderPath, 'taxonomies.json'); - log.debug(`Writing taxonomies metadata to: ${taxonomiesFilePath}`, this.exportConfig.context); - fsUtil.writeFile(taxonomiesFilePath, this.taxonomies); + const localesToExport = Array.from(localeSet); + log.debug(`Total unique locales to export: ${localesToExport.length}`, this.exportConfig.context); + + return localesToExport; } private isLocalePlanLimitationError(error: any): boolean { diff --git a/packages/contentstack-export/src/export/modules/webhooks.ts b/packages/contentstack-export/src/export/modules/webhooks.ts index f4d797230..ef59a13c2 100644 --- a/packages/contentstack-export/src/export/modules/webhooks.ts +++ b/packages/contentstack-export/src/export/modules/webhooks.ts @@ -1,30 +1,59 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { ModuleClassParams, WebhookConfig } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { WebhookConfig, ModuleClassParams } from '../../types'; export default class ExportWebhooks extends BaseClass { + private webhooks: Record>; + private webhookConfig: WebhookConfig; public webhooksFolderPath: string; private qs: { - asc: string; include_count: boolean; skip?: number; + asc: string; }; - private webhookConfig: WebhookConfig; - private webhooks: Record>; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); this.webhooks = {}; this.webhookConfig = exportConfig.modules.webhooks; - this.qs = { asc: 'updated_at', include_count: true }; + this.qs = { include_count: true, asc: 'updated_at' }; this.exportConfig.context.module = 'webhooks'; } + async start(): Promise { + log.debug('Starting webhooks export process...', this.exportConfig.context); + + this.webhooksFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.webhookConfig.dirName, + ); + log.debug(`Webhooks folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); + + await fsUtil.makeDirectory(this.webhooksFolderPath); + log.debug('Created webhooks directory', this.exportConfig.context); + + await this.getWebhooks(); + log.debug(`Retrieved ${Object.keys(this.webhooks).length} webhooks`, this.exportConfig.context); + + if (this.webhooks === undefined || isEmpty(this.webhooks)) { + log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); + } else { + const webhooksFilePath = pResolve(this.webhooksFolderPath, this.webhookConfig.fileName); + log.debug(`Writing webhooks to: ${webhooksFilePath}`, this.exportConfig.context); + fsUtil.writeFile(webhooksFilePath, this.webhooks); + log.success( + messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), + this.exportConfig.context, + ); + } + } + async getWebhooks(skip = 0): Promise { if (skip) { this.qs.skip = skip; @@ -32,16 +61,16 @@ export default class ExportWebhooks extends BaseClass { } else { log.debug('Fetching webhooks with initial query', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); await this.stack .webhook() .fetchAll(this.qs) .then(async (data: any) => { - const { count, items } = data; + const { items, count } = data; log.debug(`Fetched ${items?.length || 0} webhooks out of total ${count}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} webhooks`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -64,45 +93,19 @@ export default class ExportWebhooks extends BaseClass { sanitizeAttribs(webhooks: Record[]) { log.debug(`Sanitizing ${webhooks.length} webhooks`, this.exportConfig.context); - + for (let index = 0; index < webhooks?.length; index++) { const webhookUid = webhooks[index].uid; const webhookName = webhooks[index]?.name; log.debug(`Processing webhook: ${webhookName} (${webhookUid})`, this.exportConfig.context); - + this.webhooks[webhookUid] = omit(webhooks[index], ['SYS_ACL']); log.success(messageHandler.parse('WEBHOOK_EXPORT_SUCCESS', webhookName), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total webhooks processed: ${Object.keys(this.webhooks).length}`, this.exportConfig.context); - } - async start(): Promise { - log.debug('Starting webhooks export process...', this.exportConfig.context); - - this.webhooksFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.webhookConfig.dirName, + log.debug( + `Sanitization complete. Total webhooks processed: ${Object.keys(this.webhooks).length}`, + this.exportConfig.context, ); - log.debug(`Webhooks folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.webhooksFolderPath); - log.debug('Created webhooks directory', this.exportConfig.context); - - await this.getWebhooks(); - log.debug(`Retrieved ${Object.keys(this.webhooks).length} webhooks`, this.exportConfig.context); - - if (this.webhooks === undefined || isEmpty(this.webhooks)) { - log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); - } else { - const webhooksFilePath = pResolve(this.webhooksFolderPath, this.webhookConfig.fileName); - log.debug(`Writing webhooks to: ${webhooksFilePath}`, this.exportConfig.context); - fsUtil.writeFile(webhooksFilePath, this.webhooks); - log.success( - messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), - this.exportConfig.context, - ); - } } } diff --git a/packages/contentstack-export/src/export/modules/workflows.ts b/packages/contentstack-export/src/export/modules/workflows.ts index d3aacf3a8..f51b0d34a 100644 --- a/packages/contentstack-export/src/export/modules/workflows.ts +++ b/packages/contentstack-export/src/export/modules/workflows.ts @@ -1,20 +1,20 @@ -import { handleAndLogError, log, messageHandler } from '@contentstack/cli-utilities'; -import isEmpty from 'lodash/isEmpty'; import omit from 'lodash/omit'; +import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; +import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; -import { ModuleClassParams, WorkflowConfig } from '../../types'; -import { fsUtil } from '../../utils'; import BaseClass from './base-class'; +import { fsUtil } from '../../utils'; +import { WorkflowConfig, ModuleClassParams } from '../../types'; export default class ExportWorkFlows extends BaseClass { + private workflows: Record>; + private workflowConfig: WorkflowConfig; public webhooksFolderPath: string; private qs: { include_count: boolean; skip?: number; }; - private workflowConfig: WorkflowConfig; - private workflows: Record>; constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); @@ -24,37 +24,30 @@ export default class ExportWorkFlows extends BaseClass { this.exportConfig.context.module = 'workflows'; } - async getRoles(roleUid: number): Promise { - log.debug(`Fetching role with UID: ${roleUid}`, this.exportConfig.context); - - return await this.stack - .role(roleUid) - .fetch({ include_permissions: true, include_rules: true }) - .then((data: any) => { - log.debug(`Successfully fetched role data for UID: ${roleUid}`, this.exportConfig.context); - return data; - }) - .catch((err: any) => { - log.debug(`Failed to fetch role data for UID: ${roleUid}`, this.exportConfig.context); - handleAndLogError( - err, - { ...this.exportConfig.context } - ); - }); - } + async start(): Promise { + this.webhooksFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.workflowConfig.dirName, + ); + log.debug(`Workflows folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - async getWorkflowRoles(workflow: Record) { - log.debug(`Processing workflow roles for workflow: ${workflow.uid}`, this.exportConfig.context); - - for (const stage of workflow?.workflow_stages) { - log.debug(`Processing workflow stage: ${stage.name}`, this.exportConfig.context); - - for (let i = 0; i < stage?.SYS_ACL?.roles?.uids?.length; i++) { - const roleUid = stage.SYS_ACL.roles.uids[i]; - log.debug(`Fetching role data for role UID: ${roleUid}`, this.exportConfig.context); - const roleData = await this.getRoles(roleUid); - stage.SYS_ACL.roles.uids[i] = roleData; - } + await fsUtil.makeDirectory(this.webhooksFolderPath); + log.debug('Created workflows directory', this.exportConfig.context); + + await this.getWorkflows(); + log.debug(`Retrieved ${Object.keys(this.workflows).length} workflows`, this.exportConfig.context); + + if (this.workflows === undefined || isEmpty(this.workflows)) { + log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); + } else { + const workflowsFilePath = pResolve(this.webhooksFolderPath, this.workflowConfig.fileName); + log.debug(`Writing workflows to: ${workflowsFilePath}`, this.exportConfig.context); + fsUtil.writeFile(workflowsFilePath, this.workflows); + log.success( + messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length), + this.exportConfig.context, + ); } } @@ -69,11 +62,11 @@ export default class ExportWorkFlows extends BaseClass { .workflow() .fetchAll(this.qs) .then(async (data: any) => { - const { count, items } = data; + const { items, count } = data; //NOTE - Handle the case where old workflow api is enabled in that case getting responses as objects. const workflowCount = count !== undefined ? count : items.length; log.debug(`Fetched ${items?.length || 0} workflows out of total ${workflowCount}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} workflows`, this.exportConfig.context); await this.sanitizeAttribs(items); @@ -96,47 +89,51 @@ export default class ExportWorkFlows extends BaseClass { async sanitizeAttribs(workflows: Record[]) { log.debug(`Sanitizing ${workflows.length} workflows`, this.exportConfig.context); - + for (let index = 0; index < workflows?.length; index++) { const workflowUid = workflows[index].uid; const workflowName = workflows[index]?.name || ''; log.debug(`Processing workflow: ${workflowName} (${workflowUid})`, this.exportConfig.context); - + await this.getWorkflowRoles(workflows[index]); this.workflows[workflowUid] = omit(workflows[index], this.workflowConfig.invalidKeys); - log.success( - messageHandler.parse('WORKFLOW_EXPORT_SUCCESS', workflowName), - this.exportConfig.context, - ); + log.success(messageHandler.parse('WORKFLOW_EXPORT_SUCCESS', workflowName), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total workflows processed: ${Object.keys(this.workflows).length}`, this.exportConfig.context); - } - async start(): Promise { - this.webhooksFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.workflowConfig.dirName, + log.debug( + `Sanitization complete. Total workflows processed: ${Object.keys(this.workflows).length}`, + this.exportConfig.context, ); - log.debug(`Workflows folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); + } - await fsUtil.makeDirectory(this.webhooksFolderPath); - log.debug('Created workflows directory', this.exportConfig.context); - - await this.getWorkflows(); - log.debug(`Retrieved ${Object.keys(this.workflows).length} workflows`, this.exportConfig.context); + async getWorkflowRoles(workflow: Record) { + log.debug(`Processing workflow roles for workflow: ${workflow.uid}`, this.exportConfig.context); - if (this.workflows === undefined || isEmpty(this.workflows)) { - log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); - } else { - const workflowsFilePath = pResolve(this.webhooksFolderPath, this.workflowConfig.fileName); - log.debug(`Writing workflows to: ${workflowsFilePath}`, this.exportConfig.context); - fsUtil.writeFile(workflowsFilePath, this.workflows); - log.success( - messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length ), - this.exportConfig.context, - ); + for (const stage of workflow?.workflow_stages) { + log.debug(`Processing workflow stage: ${stage.name}`, this.exportConfig.context); + + for (let i = 0; i < stage?.SYS_ACL?.roles?.uids?.length; i++) { + const roleUid = stage.SYS_ACL.roles.uids[i]; + log.debug(`Fetching role data for role UID: ${roleUid}`, this.exportConfig.context); + const roleData = await this.getRoles(roleUid); + stage.SYS_ACL.roles.uids[i] = roleData; + } } } + + async getRoles(roleUid: number): Promise { + log.debug(`Fetching role with UID: ${roleUid}`, this.exportConfig.context); + + return await this.stack + .role(roleUid) + .fetch({ include_rules: true, include_permissions: true }) + .then((data: any) => { + log.debug(`Successfully fetched role data for UID: ${roleUid}`, this.exportConfig.context); + return data; + }) + .catch((err: any) => { + log.debug(`Failed to fetch role data for UID: ${roleUid}`, this.exportConfig.context); + handleAndLogError(err, { ...this.exportConfig.context }); + }); + } } diff --git a/packages/contentstack-export/src/types/default-config.ts b/packages/contentstack-export/src/types/default-config.ts index 61aebe620..01cb84c89 100644 --- a/packages/contentstack-export/src/types/default-config.ts +++ b/packages/contentstack-export/src/types/default-config.ts @@ -5,23 +5,10 @@ interface AnyProperty { } export default interface DefaultConfig { - apis: { - assets: string; - content_types: string; - entries: string; - environments: string; - extension: string; - globalfields: string; - labels: string; - locales: string; - stacks: string; - userSession: string; - users: string; - webhooks: string; - }; - cdn?: string; contentVersion: number; - developerHubBaseUrl: string; + versioning: boolean; + host: string; + cdn?: string; developerHubUrls: any; // use below hosts for eu region // host:'https://eu-api.contentstack.com/v3', @@ -30,203 +17,216 @@ export default interface DefaultConfig { // use below hosts for gcp-na region // host: 'https://gcp-na-api.contentstack.com' // use below hosts for gcp-eu region - fetchConcurrency: number; - host: string; - languagesCode: string[]; - marketplaceAppEncryptionKey: string; // host: 'https://gcp-eu-api.contentstack.com' modules: { - assets: { - assetsMetaKeys: string[]; // Default keys ['uid', 'url', 'filename'] - // This is the total no. of asset objects fetched in each 'get assets' call - batchLimit: number; - // no of asset version files (of a single asset) that'll be downloaded parallel - chunkFileSize: number; // measured on Megabits (5mb) - dependencies?: Modules[]; + types: Modules[]; + locales: { dirName: string; - displayExecutionTime: boolean; - downloadLimit: number; - enableDownloadStatus: boolean; - fetchConcurrency: number; fileName: string; - host: string; - includeVersionedAssets: boolean; - invalidKeys: string[]; - securedAssets: boolean; - }; - attributes: { + requiredKeys: string[]; dependencies?: Modules[]; - dirName: string; - fileName: string; - invalidKeys: string[]; }; - audiences: { - dependencies?: Modules[]; + customRoles: { dirName: string; fileName: string; - invalidKeys: string[]; + customRolesLocalesFileName: string; + dependencies?: Modules[]; }; - 'composable-studio': { - apiBaseUrl: string; - apiVersion: string; + 'custom-roles': { dirName: string; fileName: string; - }; - content_types: { + customRolesLocalesFileName: string; dependencies?: Modules[]; - dirName: string; - fileName: string; - // total no of content types fetched in each 'get content types' call - limit: number; - validKeys: string[]; }; - 'content-types': { - dependencies?: Modules[]; + environments: { dirName: string; fileName: string; - // total no of content types fetched in each 'get content types' call - limit: number; - validKeys: string[]; - }; - 'custom-roles': { - customRolesLocalesFileName: string; dependencies?: Modules[]; + }; + labels: { dirName: string; fileName: string; - }; - customRoles: { - customRolesLocalesFileName: string; + invalidKeys: string[]; dependencies?: Modules[]; + }; + webhooks: { dirName: string; fileName: string; - }; - dependency: { - entries: string[]; - }; - entries: { - batchLimit: number; dependencies?: Modules[]; + }; + releases: { dirName: string; - downloadLimit: number; - exportVersions: boolean; fileName: string; + releasesList: string; invalidKeys: string[]; - // total no of entries fetched in each content type in a single call - limit: number; - }; - environments: { dependencies?: Modules[]; - dirName: string; - fileName: string; }; - events: { - dependencies?: Modules[]; + workflows: { dirName: string; fileName: string; invalidKeys: string[]; - }; - extensions: { dependencies?: Modules[]; + }; + 'publishing-rules': { dirName: string; fileName: string; - }; - 'global-fields': { + invalidKeys: string[]; dependencies?: Modules[]; + limit?: number; + }; + globalfields: { dirName: string; fileName: string; validKeys: string[]; - }; - globalfields: { dependencies?: Modules[]; + }; + 'global-fields': { dirName: string; fileName: string; validKeys: string[]; - }; - labels: { dependencies?: Modules[]; + }; + assets: { dirName: string; fileName: string; + // This is the total no. of asset objects fetched in each 'get assets' call + batchLimit: number; + host: string; invalidKeys: string[]; - }; - locales: { + // no of asset version files (of a single asset) that'll be downloaded parallel + chunkFileSize: number; // measured on Megabits (5mb) + downloadLimit: number; + fetchConcurrency: number; + assetsMetaKeys: string[]; // Default keys ['uid', 'url', 'filename'] + securedAssets: boolean; + displayExecutionTime: boolean; + enableDownloadStatus: boolean; + includeVersionedAssets: boolean; dependencies?: Modules[]; - dirName: string; - fileName: string; - requiredKeys: string[]; }; - marketplace_apps: { - dependencies?: Modules[]; + content_types: { dirName: string; fileName: string; - }; - 'marketplace-apps': { + validKeys: string[]; + // total no of content types fetched in each 'get content types' call + limit: number; dependencies?: Modules[]; + }; + 'content-types': { dirName: string; fileName: string; + validKeys: string[]; + // total no of content types fetched in each 'get content types' call + limit: number; + dependencies?: Modules[]; }; - masterLocale: { + entries: { dirName: string; fileName: string; - requiredKeys: string[]; + invalidKeys: string[]; + batchLimit: number; + downloadLimit: number; + // total no of entries fetched in each content type in a single call + limit: number; + dependencies?: Modules[]; + exportVersions: boolean; }; personalize: { + dirName: string; baseURL: Record; + } & AnyProperty; + variantEntry: { dirName: string; + fileName: string; + chunkFileSize: number; + query: { + skip: number; + limit: number; + include_variant: boolean; + include_count: boolean; + include_publish_details: boolean; + } & AnyProperty; } & AnyProperty; - 'publishing-rules': { - dependencies?: Modules[]; + extensions: { dirName: string; fileName: string; - invalidKeys: string[]; - limit?: number; + dependencies?: Modules[]; }; - releases: { + stack: { + dirName: string; + fileName: string; dependencies?: Modules[]; + }; + dependency: { + entries: string[]; + }; + marketplace_apps: { dirName: string; fileName: string; - invalidKeys: string[]; - releasesList: string; + dependencies?: Modules[]; }; - stack: { + 'marketplace-apps': { + dirName: string; + fileName: string; dependencies?: Modules[]; + }; + 'composable-studio': { dirName: string; fileName: string; + apiBaseUrl: string; + apiVersion: string; + }; + masterLocale: { + dirName: string; + fileName: string; + requiredKeys: string[]; }; taxonomies: { - dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; + dependencies?: Modules[]; limit: number; }; - types: Modules[]; - variantEntry: { - chunkFileSize: number; + events: { dirName: string; fileName: string; - query: { - include_count: boolean; - include_publish_details: boolean; - include_variant: boolean; - limit: number; - skip: number; - } & AnyProperty; - } & AnyProperty; - webhooks: { + invalidKeys: string[]; dependencies?: Modules[]; + }; + audiences: { dirName: string; fileName: string; - }; - workflows: { + invalidKeys: string[]; dependencies?: Modules[]; + }; + attributes: { dirName: string; fileName: string; invalidKeys: string[]; + dependencies?: Modules[]; }; }; - onlyTSModules: string[]; - personalizationEnabled: boolean; + languagesCode: string[]; + apis: { + userSession: string; + globalfields: string; + locales: string; + labels: string; + environments: string; + assets: string; + content_types: string; + entries: string; + users: string; + extension: string; + webhooks: string; + stacks: string; + }; preserveStackVersion: boolean; - versioning: boolean; + personalizationEnabled: boolean; + fetchConcurrency: number; writeConcurrency: number; + developerHubBaseUrl: string; + marketplaceAppEncryptionKey: string; + onlyTSModules: string[]; } diff --git a/packages/contentstack-export/src/types/export-config.ts b/packages/contentstack-export/src/types/export-config.ts index 7e0ce6892..8b0e1b37b 100644 --- a/packages/contentstack-export/src/types/export-config.ts +++ b/packages/contentstack-export/src/types/export-config.ts @@ -2,45 +2,45 @@ import { Context, Modules, Region } from '.'; import DefaultConfig from './default-config'; export default interface ExportConfig extends DefaultConfig { - access_token?: string; + context: Context; + cliLogsPath: string; + exportDir: string; + data: string; + management_token?: string; apiKey: string; + forceStopMarketplaceAppsPrompt: boolean; auth_token?: string; - authenticationMethod?: string; - branchAlias?: string; - branchDir?: string; - branchEnabled?: boolean; branchName?: string; - branches?: branch[]; - cliLogsPath: string; + branchAlias?: string; + securedAssets?: boolean; contentTypes?: string[]; - context: Context; - data: string; - exportDir: string; - forceStopMarketplaceAppsPrompt: boolean; + branches?: branch[]; + branchEnabled?: boolean; + branchDir?: string; + singleModuleExport?: boolean; + moduleName?: Modules; + master_locale: masterLocale; + query?: any; // Added query field headers?: { - 'X-User-Agent': string; - access_token?: string; api_key: string; + access_token?: string; authtoken?: string; + 'X-User-Agent': string; organization_uid?: string; }; - management_token?: string; - master_locale: masterLocale; - moduleName?: Modules; + access_token?: string; org_uid?: string; - query?: any; // Added query field - region: Region; - securedAssets?: boolean; - singleModuleExport?: boolean; - skipDependencies?: boolean; - skipStackSettings?: boolean; source_stack?: string; sourceStackName?: string; + region: Region; + skipStackSettings?: boolean; + skipDependencies?: boolean; + authenticationMethod?: string; } type branch = { - source: string; uid: string; + source: string; }; type masterLocale = { diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index 592aae960..fd13364a5 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -1,5 +1,4 @@ import { ContentstackClient } from '@contentstack/cli-utilities'; - import ExportConfig from './export-config'; // eslint-disable-next-line @typescript-eslint/no-redeclare @@ -16,147 +15,144 @@ export interface PrintOptions { } export interface InquirePayload { - choices?: Array; - message: string; - name: string; - transformer?: (value: string, answers: Record) => boolean | string; type: string; + name: string; + message: string; + choices?: Array; + transformer?: Function; } export interface User { - authtoken: string; email: string; + authtoken: string; } export interface Region { - cda: string; - cma: string; name: string; + cma: string; + cda: string; uiHost: string; } export type Modules = + | 'stack' | 'assets' - | 'composable-studio' - | 'content-types' - | 'custom-roles' - | 'entries' + | 'locales' | 'environments' | 'extensions' + | 'webhooks' | 'global-fields' + | 'entries' + | 'content-types' + | 'custom-roles' + | 'workflows' + | 'publishing-rules' | 'labels' - | 'locales' | 'marketplace-apps' - | 'personalize' - | 'publishing-rules' - | 'stack' | 'taxonomies' - | 'webhooks' - | 'workflows'; + | 'personalize' + | 'composable-studio'; export type ModuleClassParams = { + stackAPIClient: ReturnType; exportConfig: ExportConfig; moduleName: Modules; - stackAPIClient: ReturnType; }; export interface ExternalConfig extends ExportConfig { - branchName: string; - data: string; - email?: string; - fetchConcurrency: number; master_locale: { - code: string; name: string; + code: string; }; - moduleName: Modules; - password?: string; - securedAssets: boolean; source_stack?: string; + data: string; + branchName: string; + moduleName: Modules; + fetchConcurrency: number; writeConcurrency: number; + securedAssets: boolean; + email?: string; + password?: string; } export interface ExtensionsConfig { - dependencies?: Modules[]; dirName: string; fileName: string; + dependencies?: Modules[]; limit?: number; } export interface MarketplaceAppsConfig { - dependencies?: Modules[]; dirName: string; fileName: string; + dependencies?: Modules[]; } export interface EnvironmentConfig { - dependencies?: Modules[]; dirName: string; fileName: string; + dependencies?: Modules[]; limit?: number; } export interface LabelConfig { - dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; + dependencies?: Modules[]; limit?: number; } export interface WebhookConfig { - dependencies?: Modules[]; dirName: string; fileName: string; + dependencies?: Modules[]; limit?: number; } export interface WorkflowConfig { - dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; + dependencies?: Modules[]; limit?: number; } export interface PublishingRulesConfig { - dependencies?: Modules[]; dirName: string; fileName: string; invalidKeys: string[]; + dependencies?: Modules[]; limit?: number; } export interface CustomRoleConfig { - customRolesLocalesFileName: string; - dependencies?: Modules[]; dirName: string; fileName: string; + customRolesLocalesFileName: string; + dependencies?: Modules[]; } export interface StackConfig { - dependencies?: Modules[]; dirName: string; fileName: string; + dependencies?: Modules[]; limit?: number; } export interface ComposableStudioConfig { - apiBaseUrl: string; - apiVersion: string; dirName: string; fileName: string; + apiBaseUrl: string; + apiVersion: string; } export interface ComposableStudioProject { + name: string; + description: string; canvasUrl: string; connectedStackApiKey: string; contentTypeUid: string; - createdAt: string; - createdBy: string; - deletedAt: boolean; - description: string; - name: string; organizationUid: string; settings: { configuration: { @@ -164,9 +160,12 @@ export interface ComposableStudioProject { locale: string; }; }; - uid: string; - updatedAt: string; + createdBy: string; updatedBy: string; + deletedAt: boolean; + createdAt: string; + updatedAt: string; + uid: string; } export interface Context { module: string; diff --git a/packages/contentstack-export/src/types/marketplace-app.ts b/packages/contentstack-export/src/types/marketplace-app.ts index ec7497a2d..684d9015a 100644 --- a/packages/contentstack-export/src/types/marketplace-app.ts +++ b/packages/contentstack-export/src/types/marketplace-app.ts @@ -1,35 +1,35 @@ type AppLocation = - | 'cs.cm.stack.asset_sidebar' | 'cs.cm.stack.config' - | 'cs.cm.stack.custom_field' | 'cs.cm.stack.dashboard' - | 'cs.cm.stack.rte' | 'cs.cm.stack.sidebar' + | 'cs.cm.stack.custom_field' + | 'cs.cm.stack.rte' + | 'cs.cm.stack.asset_sidebar' | 'cs.org.config'; interface ExtensionMeta { - blur?: boolean; - data_type?: string; - default_width?: 'full' | 'half'; - description?: string; - enabled?: boolean; - extension_uid?: string; + uid?: string; name?: string; + description?: string; path?: string; signed: boolean; - uid?: string; + extension_uid?: string; + data_type?: string; + enabled?: boolean; width?: number; + blur?: boolean; + default_width?: 'full' | 'half'; } interface Extension { - meta: ExtensionMeta[]; type: AppLocation; + meta: ExtensionMeta[]; } interface LocationConfiguration { + signed: boolean; base_url: string; locations: Extension[]; - signed: boolean; } interface AnyProperty { @@ -37,29 +37,29 @@ interface AnyProperty { } type Manifest = { + uid: string; + name: string; + icon?: string; + hosting?: any; + version?: number; description: string; + organization_uid: string; framework_version?: string; - hosting?: any; - icon?: string; - name: string; oauth?: any; - organization_uid: string; - target_type: 'organization' | 'stack'; + webhook?: any; ui_location: LocationConfiguration; - uid: string; - version?: number; + target_type: 'stack' | 'organization'; visibility: 'private' | 'public' | 'public_unlisted'; - webhook?: any; } & AnyProperty; type Installation = { - configuration: any; + uid: string; + status: string; manifest: Manifest; + configuration: any; server_configuration: any; - status: string; target: { type: string; uid: string }; ui_location: LocationConfiguration; - uid: string; } & AnyProperty; export { Installation, Manifest }; diff --git a/packages/contentstack-export/src/utils/basic-login.ts b/packages/contentstack-export/src/utils/basic-login.ts index 584b5debc..6a9d9cabd 100644 --- a/packages/contentstack-export/src/utils/basic-login.ts +++ b/packages/contentstack-export/src/utils/basic-login.ts @@ -7,8 +7,7 @@ * MIT Licensed */ -import { authHandler, log, managementSDKClient } from '@contentstack/cli-utilities'; - +import { log, managementSDKClient, authHandler } from '@contentstack/cli-utilities'; import { ExternalConfig } from '../types'; const login = async (config: ExternalConfig): Promise => { @@ -17,18 +16,16 @@ const login = async (config: ExternalConfig): Promise => { const response = await client.login({ email: config.email, password: config.password }).catch(Promise.reject); if (response?.user?.authtoken) { config.headers = { - 'X-User-Agent': 'contentstack-export/v', - access_token: config.access_token, api_key: config.source_stack, + access_token: config.access_token, authtoken: response.user.authtoken, + 'X-User-Agent': 'contentstack-export/v', }; await authHandler.setConfigData('basicAuth', response.user); log.success(`Contentstack account authenticated successfully!`, config.context); return config; } else { log.error(`Failed to log in!`, config.context); - // CLI: exit after unrecoverable auth failure (same behavior as before lint pass) - // eslint-disable-next-line n/no-process-exit -- intentional CLI termination process.exit(1); } } else if (!config.email && !config.password && config.source_stack && config.access_token) { @@ -41,9 +38,9 @@ const login = async (config: ExternalConfig): Promise => { config.context, ); config.headers = { - 'X-User-Agent': 'contentstack-export/v', - access_token: config.access_token, api_key: config.source_stack, + access_token: config.access_token, + 'X-User-Agent': 'contentstack-export/v', }; return config; } diff --git a/packages/contentstack-export/src/utils/common-helper.ts b/packages/contentstack-export/src/utils/common-helper.ts index 9a4bd34fc..6c3de9a5b 100644 --- a/packages/contentstack-export/src/utils/common-helper.ts +++ b/packages/contentstack-export/src/utils/common-helper.ts @@ -4,12 +4,12 @@ * MIT Licensed */ -import { getLogPath, isAuthenticated, sanitizePath } from '@contentstack/cli-utilities'; import * as path from 'path'; import promiseLimit from 'promise-limit'; +import { isAuthenticated, getLogPath, sanitizePath } from '@contentstack/cli-utilities'; -import { ExportConfig, ExternalConfig } from '../types'; import { fsUtil } from './file-helper'; +import { ExternalConfig, ExportConfig } from '../types'; export const validateConfig = function (config: ExternalConfig) { if (!config.host || !config.cdn) { diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index fbfcbfaad..2303f3937 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -1,13 +1,12 @@ -import { cliux, configHandler,isAuthenticated, log, sanitizePath } from '@contentstack/cli-utilities'; -import { filter, includes } from 'lodash'; import merge from 'merge'; import * as path from 'path'; - +import { configHandler, isAuthenticated, cliux, sanitizePath, log } from '@contentstack/cli-utilities'; import defaultConfig from '../config'; -import { ExportConfig } from '../types'; -import login from './basic-login'; import { readFile } from './file-helper'; -import { askAPIKey, askExportDir } from './interactive'; +import { askExportDir, askAPIKey } from './interactive'; +import login from './basic-login'; +import { filter, includes } from 'lodash'; +import { ExportConfig } from '../types'; const setupConfig = async (exportCmdFlags: any): Promise => { let config = merge({}, defaultConfig); @@ -44,7 +43,7 @@ const setupConfig = async (exportCmdFlags: any): Promise => { if (managementTokenAlias) { log.debug('Using management token alias', { alias: managementTokenAlias }); - const { apiKey, token } = configHandler.get(`tokens.${managementTokenAlias}`) || {}; + const { token, apiKey } = configHandler.get(`tokens.${managementTokenAlias}`) || {}; config.management_token = token; config.apiKey = apiKey; authenticationMethod = 'Management Token'; @@ -98,7 +97,7 @@ const setupConfig = async (exportCmdFlags: any): Promise => { if (exportCmdFlags['branch-alias']) { config.branchAlias = exportCmdFlags['branch-alias']; - } + } if (exportCmdFlags['branch']) { config.branchName = exportCmdFlags['branch']; } @@ -134,7 +133,7 @@ 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 }); diff --git a/packages/contentstack-export/src/utils/file-helper.ts b/packages/contentstack-export/src/utils/file-helper.ts index 52a4541a7..b96ee98c1 100644 --- a/packages/contentstack-export/src/utils/file-helper.ts +++ b/packages/contentstack-export/src/utils/file-helper.ts @@ -1,8 +1,8 @@ -import { FsUtility, sanitizePath } from '@contentstack/cli-utilities'; -import bigJSON from 'big-json'; import * as fs from 'fs'; -import mkdirp from 'mkdirp'; import * as path from 'path'; +import mkdirp from 'mkdirp'; +import bigJSON from 'big-json'; +import { FsUtility, sanitizePath } from '@contentstack/cli-utilities'; export const readFileSync = function (filePath: string, parse: boolean): unknown { let data; @@ -81,7 +81,7 @@ export const writeLargeFile = function (filePath: string, data: any): Promise { resolve(''); @@ -92,9 +92,9 @@ export const writeLargeFile = function (filePath: string, data: any): Promise { return cliux.inquire({ + type: 'input', message: 'CLI_AUTH_LOGIN_ENTER_PASSWORD', name: 'password', transformer: (pswd: string) => { @@ -12,43 +13,42 @@ export const askPassword = async () => { } return pswdMasked; }, - type: 'input', }); }; export const askOTPChannel = async (): Promise => { return cliux.inquire({ + type: 'list', + name: 'otpChannel', + message: 'CLI_AUTH_LOGIN_ASK_CHANNEL_FOR_OTP', choices: [ { name: 'Authy App', value: 'authy' }, { name: 'SMS', value: 'sms' }, ], - message: 'CLI_AUTH_LOGIN_ASK_CHANNEL_FOR_OTP', - name: 'otpChannel', - type: 'list', }); }; export const askOTP = async (): Promise => { return cliux.inquire({ + type: 'input', message: 'CLI_AUTH_LOGIN_ENTER_SECURITY_CODE', name: 'tfaToken', - type: 'input', }); }; export const askUsername = async (): Promise => { return cliux.inquire({ + type: 'input', message: 'CLI_AUTH_LOGIN_ENTER_EMAIL_ADDRESS', name: 'username', - type: 'input', }); }; export const askExportDir = async (): Promise => { let result = await cliux.inquire({ + type: 'input', message: 'Enter the path for storing the content: (current folder)', name: 'dir', - type: 'input', validate: validatePath, }); if (!result) { @@ -61,8 +61,8 @@ export const askExportDir = async (): Promise => { export const askAPIKey = async (): Promise => { return await cliux.inquire({ + type: 'input', message: 'Enter the stack api key', name: 'apiKey', - type: 'input', }); }; diff --git a/packages/contentstack-export/src/utils/logger.ts b/packages/contentstack-export/src/utils/logger.ts index 821be1d65..337a9d897 100644 --- a/packages/contentstack-export/src/utils/logger.ts +++ b/packages/contentstack-export/src/utils/logger.ts @@ -4,12 +4,12 @@ * MIT Licensed */ -import { redactObject, sanitizePath } from '@contentstack/cli-utilities'; -import mkdirp from 'mkdirp'; -import * as path from 'path'; import * as winston from 'winston'; - +import * as path from 'path'; +import mkdirp from 'mkdirp'; import { ExportConfig } from '../types'; +import { sanitizePath, redactObject } from '@contentstack/cli-utilities'; +const slice = Array.prototype.slice; const ansiRegexPattern = [ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', @@ -39,17 +39,17 @@ function returnString(args: unknown[]) { return returnStr; } const myCustomLevels = { + levels: { + warn: 1, + info: 2, + debug: 3, + }, colors: { - debug: 'green', - error: 'red', //colors aren't being used anywhere as of now, we're using chalk to add colors while logging info: 'blue', + debug: 'green', warn: 'yellow', - }, - levels: { - debug: 3, - info: 2, - warn: 1, + error: 'red', }, }; @@ -67,66 +67,70 @@ function init(_logPath: string) { successTransport = { filename: path.join(sanitizePath(logsDir), 'success.log'), - level: 'info', maxFiles: 20, maxsize: 1000000, tailable: true, + level: 'info', }; errorTransport = { filename: path.join(sanitizePath(logsDir), 'error.log'), - level: 'error', maxFiles: 20, maxsize: 1000000, tailable: true, + level: 'error', }; logger = winston.createLogger({ - levels: myCustomLevels.levels, transports: [ new winston.transports.File(successTransport), new winston.transports.Console({ format: winston.format.simple() }), ], + levels: myCustomLevels.levels, }); errorLogger = winston.createLogger({ - levels: { error: 0 }, transports: [ new winston.transports.File(errorTransport), new winston.transports.Console({ + level: 'error', format: winston.format.combine( winston.format.colorize({ all: true, colors: { error: 'red' } }), winston.format.simple(), ), - level: 'error', }), ], + levels: { error: 0 }, }); } return { - debug: function (...args: unknown[]) { + log: function (message: any) { + const args = slice.call(arguments); const logString = returnString(args); if (logString) { - logger.log('debug', logString); + logger.log('info', logString); } }, - error: function (...args: unknown[]) { + warn: function () { + const args = slice.call(arguments); const logString = returnString(args); if (logString) { - errorLogger.log('error', logString); + logger.log('warn', logString); } }, - log: function (...args: unknown[]) { + error: function (message: any) { + const args = slice.call(arguments); const logString = returnString(args); if (logString) { - logger.log('info', logString); + errorLogger.log('error', logString); } }, - warn: function (...args: unknown[]) { + debug: function () { + const args = slice.call(arguments); const logString = returnString(args); if (logString) { - logger.log('warn', logString); + logger.log('debug', logString); } }, }; diff --git a/packages/contentstack-export/src/utils/marketplace-app-helper.ts b/packages/contentstack-export/src/utils/marketplace-app-helper.ts index efbe1dc3f..f77c2ccb1 100644 --- a/packages/contentstack-export/src/utils/marketplace-app-helper.ts +++ b/packages/contentstack-export/src/utils/marketplace-app-helper.ts @@ -1,4 +1,10 @@ -import { NodeCrypto, cliux, createDeveloperHubUrl, handleAndLogError, managementSDKClient } from '@contentstack/cli-utilities'; +import { + cliux, + handleAndLogError, + NodeCrypto, + managementSDKClient, + createDeveloperHubUrl, +} from '@contentstack/cli-utilities'; import { ExportConfig } from '../types'; @@ -12,7 +18,7 @@ export async function getOrgUid(config: ExportConfig): Promise { .stack({ api_key: config.source_stack }) .fetch() .catch((error: any) => { - handleAndLogError(error, {...config.context}); + handleAndLogError(error, { ...config.context }); }); return tempStackData?.org_uid; @@ -25,15 +31,15 @@ export async function createNodeCryptoInstance(config: ExportConfig): Promise { if (!url) return "Encryption key can't be empty."; return true; }, + message: 'Enter Marketplace app configurations encryption key', }); } diff --git a/packages/contentstack-export/src/utils/setup-branches.ts b/packages/contentstack-export/src/utils/setup-branches.ts index d9183901c..e5097800c 100644 --- a/packages/contentstack-export/src/utils/setup-branches.ts +++ b/packages/contentstack-export/src/utils/setup-branches.ts @@ -1,8 +1,8 @@ -import { sanitizePath } from '@contentstack/cli-utilities'; import * as path from 'path'; +import { sanitizePath } from '@contentstack/cli-utilities'; import { ExportConfig } from '../types'; -import { makeDirectory, writeFileSync } from './file-helper'; +import { writeFileSync, makeDirectory } from './file-helper'; const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { if (typeof config !== 'object') { @@ -15,7 +15,6 @@ const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { const result = await stackAPIClient .branch(config.branchName) .fetch() - // eslint-disable-next-line @typescript-eslint/no-empty-function -- ignore branch fetch failure; handled below .catch((_err: Error) => {}); if (result && typeof result === 'object') { branches.push(result); @@ -28,7 +27,6 @@ const setupBranches = async (config: ExportConfig, stackAPIClient: any) => { .branch() .query() .find() - // eslint-disable-next-line @typescript-eslint/no-empty-function -- ignore list fetch failure; handled below .catch((_err: Error) => {}); if (result && result.items && Array.isArray(result.items) && result.items.length > 0) { branches = result.items; diff --git a/packages/contentstack-export/src/utils/setup-export-dir.ts b/packages/contentstack-export/src/utils/setup-export-dir.ts index 5d8332ab0..cc49ee2c8 100644 --- a/packages/contentstack-export/src/utils/setup-export-dir.ts +++ b/packages/contentstack-export/src/utils/setup-export-dir.ts @@ -1,5 +1,5 @@ -import { sanitizePath } from '@contentstack/cli-utilities'; import path from 'path'; +import { sanitizePath } from '@contentstack/cli-utilities'; import { ExportConfig } from '../types'; import { makeDirectory } from './file-helper'; @@ -8,7 +8,9 @@ export default async function setupExportDir(exportConfig: ExportConfig) { makeDirectory(exportConfig.exportDir); if (exportConfig.branches) { return Promise.all( - exportConfig.branches.map((branch) => makeDirectory(path.join(sanitizePath(exportConfig.exportDir), sanitizePath(branch.uid)))), + exportConfig.branches.map((branch) => + makeDirectory(path.join(sanitizePath(exportConfig.exportDir), sanitizePath(branch.uid))), + ), ); } } From 756877b8daa02d8a1e273ca4883061f7ac6a4bac Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Wed, 22 Apr 2026 17:25:12 +0530 Subject: [PATCH 8/9] chore: version bumps --- .talismanrc | 30 +- packages/contentstack-bootstrap/package.json | 4 +- packages/contentstack-clone/package.json | 6 +- packages/contentstack-export/package.json | 2 +- packages/contentstack-import/package.json | 2 +- packages/contentstack-seed/package.json | 4 +- pnpm-lock.yaml | 278 +++++++++---------- 7 files changed, 148 insertions(+), 178 deletions(-) diff --git a/.talismanrc b/.talismanrc index 6199b48e8..2da7e187e 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,30 +1,4 @@ fileignoreconfig: - - filename: packages/contentstack-export/src/export/modules/environments.ts - checksum: 3b606a0cab740e20fbda0a9d25d76dc7971f264b447da9b135ad1e7749b314d2 - - filename: packages/contentstack-export/src/export/modules/webhooks.ts - checksum: 11ca5c4e0e1887ea1629ae4a1a762dc47a0e01f5d0f8096ee36e61183a959107 - - filename: packages/contentstack-export/src/utils/export-config-handler.ts - checksum: 94e83a42ad4150ccfb6c02f6f4fac59e9fd6f58a31988b919a6ff6e027afa805 - - filename: packages/contentstack-export/src/export/modules/workflows.ts - checksum: ef3d6e36cc07eca762f94c5f7f68c5c0d49e884b6099e81a1830249cac24a287 - - filename: packages/contentstack-export/src/types/default-config.ts - checksum: 0cc62919207384ec710ea3f8a3445d6e5bd78cc2c5306b9e74aaeec688eb028d - - filename: packages/contentstack-export/src/export/modules/custom-roles.ts - checksum: 8a0cdd00b048fb6c5c8990cc881a324229e225970ec78ce5861da63fb3a875b4 - - filename: packages/contentstack-export/src/export/modules/assets.ts - checksum: 7d64a43878f19da561da4159271873035752587a016eb7af0bb8a5592740da9d - - filename: packages/contentstack-export/src/export/modules/publishing-rules.ts - checksum: 4a4278d29878fc3627f216ee168a0896cca7644bc06f4e983f4ae0b25fefabb7 - - filename: packages/contentstack-export/src/config/index.ts - checksum: 2c811d2bd7b6657b567fd120cfaf05306ca751109c070bf7b49c18d06b211764 - - filename: packages/contentstack-export/src/export/modules/locales.ts - checksum: 7226915d3e9f69111bf6f3a669edd28f55167fdc86a3b1d7583e3986825aa0e5 - - filename: packages/contentstack-export/src/export/modules/labels.ts - checksum: 1c970c204c6ff78fe66151352263cbb24eb86d2c7cb2e0050d1734dd002425ef - - filename: packages/contentstack-export/src/export/modules/extensions.ts - checksum: a08f2f63a13e9c41bac3c84ca52ea3ca1a147ca548e4e66ed682c320b7a830a8 - - filename: packages/contentstack-export/src/export/modules/entries.ts - checksum: 691df8e31ba2a2a719ea46f1b3a0e7abe0b90355f4e91f211956189dd12aa403 - - filename: packages/contentstack-export/src/export/modules/stack.ts - checksum: 316c172556694cc5421c0aca1c9470c3aaa588a87922812322a85d11816a1c90 + - filename: pnpm-lock.yaml + checksum: 48a1b9aca69c8decfed0f5333c8f4a8fa4689f1cb9c00a91dd18532418ea910f version: '1.0' diff --git a/packages/contentstack-bootstrap/package.json b/packages/contentstack-bootstrap/package.json index d0e8e55df..d4589a633 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.1", + "version": "1.19.2", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "scripts": { @@ -16,7 +16,7 @@ "test:report": "nyc --reporter=lcov mocha \"test/**/*.test.js\"" }, "dependencies": { - "@contentstack/cli-cm-seed": "~1.15.1", + "@contentstack/cli-cm-seed": "~1.15.2", "@contentstack/cli-command": "~1.8.1", "@contentstack/cli-config": "~1.20.2", "@contentstack/cli-utilities": "~1.18.2", diff --git a/packages/contentstack-clone/package.json b/packages/contentstack-clone/package.json index b305d768a..242924f8f 100644 --- a/packages/contentstack-clone/package.json +++ b/packages/contentstack-clone/package.json @@ -1,13 +1,13 @@ { "name": "@contentstack/cli-cm-clone", "description": "Contentstack stack clone plugin", - "version": "1.21.2", + "version": "1.21.3", "author": "Contentstack", "bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues", "dependencies": { "@colors/colors": "^1.6.0", - "@contentstack/cli-cm-export": "~1.24.2", - "@contentstack/cli-cm-import": "~1.32.2", + "@contentstack/cli-cm-export": "~1.25.0", + "@contentstack/cli-cm-import": "~1.33.0", "@contentstack/cli-command": "~1.8.1", "@contentstack/cli-utilities": "~1.18.2", "@oclif/core": "^4.10.5", diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index 610f2d0e0..94e9024c2 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-export", "description": "Contentstack CLI plugin to export content from stack", - "version": "1.24.2", + "version": "1.25.0", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { diff --git a/packages/contentstack-import/package.json b/packages/contentstack-import/package.json index c8c4c56ca..7d52187f6 100644 --- a/packages/contentstack-import/package.json +++ b/packages/contentstack-import/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-import", "description": "Contentstack CLI plugin to import content into stack", - "version": "1.32.2", + "version": "1.33.0", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { diff --git a/packages/contentstack-seed/package.json b/packages/contentstack-seed/package.json index 31f7a7b2f..26401c0da 100644 --- a/packages/contentstack-seed/package.json +++ b/packages/contentstack-seed/package.json @@ -1,11 +1,11 @@ { "name": "@contentstack/cli-cm-seed", "description": "create a Stack from existing content types, entries, assets, etc.", - "version": "1.15.1", + "version": "1.15.2", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-cm-import": "~1.32.1", + "@contentstack/cli-cm-import": "~1.33.0", "@contentstack/cli-command": "~1.8.1", "@contentstack/cli-utilities": "~1.18.2", "inquirer": "8.2.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 394f661f4..fc1a86203 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,7 +18,7 @@ importers: version: 9.1.7 pnpm: specifier: ^10.28.0 - version: 10.33.0 + version: 10.33.1 packages/contentstack-audit: dependencies: @@ -108,7 +108,7 @@ importers: packages/contentstack-bootstrap: dependencies: '@contentstack/cli-cm-seed': - specifier: ~1.15.1 + specifier: ~1.15.2 version: link:../contentstack-seed '@contentstack/cli-command': specifier: ~1.8.1 @@ -306,10 +306,10 @@ importers: specifier: ^1.6.0 version: 1.6.0 '@contentstack/cli-cm-export': - specifier: ~1.24.2 + specifier: ~1.25.0 version: link:../contentstack-export '@contentstack/cli-cm-import': - specifier: ~1.32.2 + specifier: ~1.33.0 version: link:../contentstack-import '@contentstack/cli-command': specifier: ~1.8.1 @@ -879,7 +879,7 @@ importers: packages/contentstack-seed: dependencies: '@contentstack/cli-cm-import': - specifier: ~1.32.1 + specifier: ~1.33.0 version: link:../contentstack-import '@contentstack/cli-command': specifier: ~1.8.1 @@ -1022,44 +1022,44 @@ packages: resolution: {integrity: sha512-0XLrOT4Cm3NEhhiME7l/8LbTXS4KdsbR4dSrY207KNKTcHLLTZ9EXt4ZpgnTfLvWQF3pGP2us4Zi1fYLo0N+Ow==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.974.2': - resolution: {integrity: sha512-oav5AOAz+1XkwUfp6SrEm42UPDpUP5D4jNYXkDwFR1VfWqYX62+jpytdfzURmJ9McSoJIQwi0OJlC4oCi6t0VQ==} + '@aws-sdk/core@3.974.3': + resolution: {integrity: sha512-W3aJJm2clu8OmsrwMOMnfof13O6LGnbknnZIQeSRbxjqKah2nVvkjbUBBZVhWrt08KC69H7WsINTdrxC/2SXQw==} engines: {node: '>=20.0.0'} '@aws-sdk/crc64-nvme@3.972.7': resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.28': - resolution: {integrity: sha512-87GdRJ2OR0qR4VkMjXN/SZi66DZsunW2qQCbtw9rKw3Y7JurFi6tQWYKOSLY/gOADrU6OxGqFmdw3hKzZqDZOQ==} + '@aws-sdk/credential-provider-env@3.972.29': + resolution: {integrity: sha512-rf+AlUxgTeSzQ/4zoS0D+Bt7XvgpY48PnWG8Yg/N9fdMgyK2Jaqa+6tLZp4MYMIMHkGrfAxnbSeb2YLMGFMg6g==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.30': - resolution: {integrity: sha512-6quozmW2PKwBJTUQLb+lk1q8w5Pm45qaqhx4Tld9EIqYYQOVGj+MT0a8NRVS7QgWJj7rzGlB7rQu3KYBFHemJw==} + '@aws-sdk/credential-provider-http@3.972.31': + resolution: {integrity: sha512-TR2/lQ3qKFj2EOrsiASzemsNEz2uzZ/SUBf48+U4Cr9a/FZlHfH/hwAeBJNBp1gMyJNxROJZhT3dn1cO+jnYfQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.32': - resolution: {integrity: sha512-Nkr+UKtczZlocUjc6g96WzQadZSIZO/HVXPki4qbfaVOZYSbfLQKWKfADtJ0kGYsCvSYOZrO66tSc9dkboUt/w==} + '@aws-sdk/credential-provider-ini@3.972.33': + resolution: {integrity: sha512-UwdbJbOrgnOxZbshaNZ4DzX35h5wQd33MNYTGzWhN3ORG9lG9KQbDX6l6tDJSAdaGTktJoZPSritmUoW1rYkRA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.32': - resolution: {integrity: sha512-UxgwT1HmZz1QPXuBy5ZUPJNFXOSlhwdQL61eGhWRthF0xRrT02BCOVJ1p5Ejg5AXfnESTWoKPJ7v/sCkNUtB9g==} + '@aws-sdk/credential-provider-login@3.972.33': + resolution: {integrity: sha512-WyZuPVoDM1HGNl41eVg8HSSXIB+FGkuuK63GhDbh4TMdfWU03AciWvF/QqOVWvJtWVYaLddANJ+aUklVr2ieuw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.33': - resolution: {integrity: sha512-6pGQnEdSeRvBViTQh/FwaRKB38a3Th+W2mVxuvqAd2Z1Ayo3e6eJ5QqJoZwEMwR6xoxkl3wz3qAfiB1xRhMC+w==} + '@aws-sdk/credential-provider-node@3.972.34': + resolution: {integrity: sha512-sPcisURibKU4x0PCWJkWF1KJYm49Cph9dCn/PAnG5FU0wq5Id3g2v7RuEWAtNlKv1Af4gUJYBVGOeNpSEEx41A==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.28': - resolution: {integrity: sha512-CRAlD8u6oNBhjnX/3ekVGocarD+lFmEn/qeDzytgIdmwrmwMJGFPqS9lGwEfhOTihZKrQ0xSp3z6paX+iXJJhA==} + '@aws-sdk/credential-provider-process@3.972.29': + resolution: {integrity: sha512-DURisqWS3bUgiwMXTmzymVNGlcRW0FnbPZ3SZknhmxnCXm3n9idkTJ6T+Uir359KRKtJNFLRViskk8HsSVLi1w==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.32': - resolution: {integrity: sha512-whhmQghRYOt9mJxFyVMhX7eB8n0oA25OCvqoR7dzFAZjmioCkf7WVB22Bc6llM5cFpBXFX7s4Jv+xVq32VPGWg==} + '@aws-sdk/credential-provider-sso@3.972.33': + resolution: {integrity: sha512-9y9obU4IQWru9f+NiiscUeyCe5ZmQav4FKEb1qfUNrik/C3BzBGUnHQWyPEyXjOX9cb+vx1TYx0qZBtinKdzTA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.32': - resolution: {integrity: sha512-Z0Y0LDaqyQDznlmr9gv6n4+eWKKWNgmi9j5L6RENr6wyOCguhO8FRPmqDbVLSw0DPdMqICKnA3PurJiS8bD6Cw==} + '@aws-sdk/credential-provider-web-identity@3.972.33': + resolution: {integrity: sha512-RazhlN0YAkna2T2p2v4YuuRlVBVRNo8V0SL+9JePTWDndEUAeOBAjYeQfAMbtDyCh120+zA0Op6V0jS4dw2+iw==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-bucket-endpoint@3.972.10': @@ -1070,8 +1070,8 @@ packages: resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.974.10': - resolution: {integrity: sha512-R9oqyD1hR7aF2UQaYBo90/ILNn8Sq7gl/2Y4WkDDvsaqklqPomso++sFbgYgNmN/Kfx6gqvJwcjSkxJHEBK1tQ==} + '@aws-sdk/middleware-flexible-checksums@3.974.11': + resolution: {integrity: sha512-jTrJFs4SMs9xjih45+QHtU79piovA6CAlofMt4jeknN5ef9zsVEHDtuwCnEe/3eANWewa9fd6Tvc54xEPpQ3RA==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-host-header@3.972.10': @@ -1090,32 +1090,32 @@ packages: resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.31': - resolution: {integrity: sha512-5hS08Fp0Rm+59uGCmkWhZmveXiA7OUV7Wa+IARejdzf9JTZ1qAVeIOE9JoBpsLPvUgEjmsGNHBuFbtGmYyqiqQ==} + '@aws-sdk/middleware-sdk-s3@3.972.32': + resolution: {integrity: sha512-dc2O2x0V5pGJhmdQYQveUIFtMZsur7GrGuSgoKM4oQJuEcfvwnJ3sj+ip6WnxR5l6TrX5zkl4KgcgswOy3wAzQ==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-ssec@3.972.10': resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.32': - resolution: {integrity: sha512-HQ0x9DDKqLZOGhDiL2eicYXXkYT5dogE4mw0lAfHCpJ6t7MM0PNIsJl2TZzWKU9SpBzOMXHRa7K6ZLKUJu1y0w==} + '@aws-sdk/middleware-user-agent@3.972.33': + resolution: {integrity: sha512-mqtT3Fo7xanWMk2SbAcKLGGI/q1GHWNrExBj7cnWP2W2mkTMheXB4ntJvwPZ1UxPrQobrsv2dWFXmaOJeSOiDg==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.997.0': - resolution: {integrity: sha512-4bI5GHjUiY5R8N6PtchpG6tW2Dl8I2IcZNg3JwqwxHRXjfvQlPoo4VMknG4qkd5W0t3Y20rQ6C7pSR561YG5JQ==} + '@aws-sdk/nested-clients@3.997.1': + resolution: {integrity: sha512-Afc9hc2WZs3X4Jb8dnxyuYiZsLoWRO51roTCRf497gPnAKN2WRdXANu1vaVCTzwnDMOYFXb/cYv4ZSjxqAqcKA==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.12': - resolution: {integrity: sha512-QQI43Mxd53nBij0pm8HXC+t4IOC6gnhhZfzxE0OATQyO6QfPV4e+aTIRRuAJKA6Nig/cR8eLwPryqYTX9ZrjAQ==} + '@aws-sdk/region-config-resolver@3.972.13': + resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.19': - resolution: {integrity: sha512-7Sy8+GhfwUi06NQNLplxuJuXMKJURDsNQfK8yTW6E9wN2J1B+8S5dWZG7vg3InvPPhaXqkcYTr8pzeE+dLjMbQ==} + '@aws-sdk/signature-v4-multi-region@3.996.20': + resolution: {integrity: sha512-MEj6DhEcaO8RgVtFCJ+xpCQnZC3Iesr09avdY75qkMQfckQULu447IegK7Rs1MCGerVBfKnJQ4q+pQq9hI5lng==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1033.0': - resolution: {integrity: sha512-/TsXhqjyRAFb0xVgmbFAha3cJfZdWjnyn6ohJ3AB4E3peLgxNcmKfYr45hruHymyJAydiHoXC3N1a8qgl41cog==} + '@aws-sdk/token-providers@3.1034.0': + resolution: {integrity: sha512-8E+KGcD4ET0H9FXJ2/ZWbfFnQNYEkTZZYJxAs1lkdJlve1AYuqaydInIFfvNgoz5GbYtzbK8/ugsSMu5wPm6kA==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.8': @@ -1126,8 +1126,8 @@ packages: resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.996.7': - resolution: {integrity: sha512-ty4LQxN1QC+YhUP28NfEgZDEGXkyqOQy+BDriBozqHsrYO4JMgiPhfizqOGF7P+euBTZ5Ez6SKlLAMCLo8tzmw==} + '@aws-sdk/util-endpoints@3.996.8': + resolution: {integrity: sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==} engines: {node: '>=20.0.0'} '@aws-sdk/util-locate-window@3.965.5': @@ -1137,8 +1137,8 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.10': resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} - '@aws-sdk/util-user-agent-node@3.973.18': - resolution: {integrity: sha512-Nh4YvAL0Mzv5jBvzXLFL0tLf7WPrRMnYZQ5jlFuyS0xiVJQsObMUKAkbYjmt/e04wpQqUaa+Is7k+mBr89A9yA==} + '@aws-sdk/util-user-agent-node@3.973.19': + resolution: {integrity: sha512-ZAfHjpzdbrzkAftC139JoYGfXzDh5HY+AxRzw8pGJ8cULsf+l721sKAMK8mV5NvRETaW/BwghSwQhGgoNgrxMw==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1355,9 +1355,6 @@ packages: '@contentstack/utils@1.9.1': resolution: {integrity: sha512-THZM0rNuq0uOSKkKnvzp8lsPDvvdKIvJIcMa9JBv4foL9rC8RWkWffa2yMyb+9m/5HZrdAmpEWdubkGwARa8WQ==} - '@contentstack/utils@1.9.1': - resolution: {integrity: sha512-THZM0rNuq0uOSKkKnvzp8lsPDvvdKIvJIcMa9JBv4foL9rC8RWkWffa2yMyb+9m/5HZrdAmpEWdubkGwARa8WQ==} - '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -3081,8 +3078,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001788: - resolution: {integrity: sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==} + caniuse-lite@1.0.30001790: + resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -3536,8 +3533,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.340: - resolution: {integrity: sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==} + electron-to-chromium@1.5.343: + resolution: {integrity: sha512-YHnQ3MXI08icvL9ZKnEBy05F2EQ8ob01UaMOuMbM8l+4UcAq6MPPbBTJBbsBUg3H8JeZNt+O4fjsoWth3p6IFg==} elegant-spinner@1.0.1: resolution: {integrity: sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==} @@ -5229,8 +5226,8 @@ packages: resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} engines: {node: '>=8'} - node-releases@2.0.37: - resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + node-releases@2.0.38: + resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -5497,8 +5494,8 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - pnpm@10.33.0: - resolution: {integrity: sha512-EFaLtKavtYyes2MNqQzJUWQXq+vT+rvmc58K55VyjaFJHp21pUTHatjrdXD1xLs9bGN7LLQb/c20f6gjyGSTGQ==} + pnpm@10.33.1: + resolution: {integrity: sha512-Bbo8HV0cGPaN8GRw10BV5i1B/BEKDGYNsbLfsnhTJ/BM8PaDRdRgm8Ugief6A0PDFZOy+VlOLF1dpCYjCsyYIA==} engines: {node: '>=18.12'} hasBin: true @@ -6112,8 +6109,8 @@ packages: resolution: {integrity: sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==} engines: {node: '>=4.0.0'} - tapable@2.3.2: - resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} tar@7.5.13: @@ -6654,17 +6651,17 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.2 - '@aws-sdk/credential-provider-node': 3.972.33 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/credential-provider-node': 3.972.34 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.32 - '@aws-sdk/region-config-resolver': 3.972.12 + '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/region-config-resolver': 3.972.13 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.7 + '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.18 + '@aws-sdk/util-user-agent-node': 3.973.19 '@smithy/config-resolver': 4.4.17 '@smithy/core': 3.23.16 '@smithy/fetch-http-handler': 5.3.17 @@ -6701,24 +6698,24 @@ snapshots: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.2 - '@aws-sdk/credential-provider-node': 3.972.33 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/credential-provider-node': 3.972.34 '@aws-sdk/middleware-bucket-endpoint': 3.972.10 '@aws-sdk/middleware-expect-continue': 3.972.10 - '@aws-sdk/middleware-flexible-checksums': 3.974.10 + '@aws-sdk/middleware-flexible-checksums': 3.974.11 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-location-constraint': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-sdk-s3': 3.972.31 + '@aws-sdk/middleware-sdk-s3': 3.972.32 '@aws-sdk/middleware-ssec': 3.972.10 - '@aws-sdk/middleware-user-agent': 3.972.32 - '@aws-sdk/region-config-resolver': 3.972.12 - '@aws-sdk/signature-v4-multi-region': 3.996.19 + '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/region-config-resolver': 3.972.13 + '@aws-sdk/signature-v4-multi-region': 3.996.20 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.7 + '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.18 + '@aws-sdk/util-user-agent-node': 3.973.19 '@smithy/config-resolver': 4.4.17 '@smithy/core': 3.23.16 '@smithy/eventstream-serde-browser': 4.2.14 @@ -6756,7 +6753,7 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.974.2': + '@aws-sdk/core@3.974.3': dependencies: '@aws-sdk/types': 3.973.8 '@aws-sdk/xml-builder': 3.972.18 @@ -6769,6 +6766,7 @@ snapshots: '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.3 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 @@ -6777,17 +6775,17 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.28': + '@aws-sdk/credential-provider-env@3.972.29': dependencies: - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.30': + '@aws-sdk/credential-provider-http@3.972.31': dependencies: - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/types': 3.973.8 '@smithy/fetch-http-handler': 5.3.17 '@smithy/node-http-handler': 4.6.0 @@ -6798,16 +6796,16 @@ snapshots: '@smithy/util-stream': 4.5.24 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.32': + '@aws-sdk/credential-provider-ini@3.972.33': dependencies: - '@aws-sdk/core': 3.974.2 - '@aws-sdk/credential-provider-env': 3.972.28 - '@aws-sdk/credential-provider-http': 3.972.30 - '@aws-sdk/credential-provider-login': 3.972.32 - '@aws-sdk/credential-provider-process': 3.972.28 - '@aws-sdk/credential-provider-sso': 3.972.32 - '@aws-sdk/credential-provider-web-identity': 3.972.32 - '@aws-sdk/nested-clients': 3.997.0 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/credential-provider-env': 3.972.29 + '@aws-sdk/credential-provider-http': 3.972.31 + '@aws-sdk/credential-provider-login': 3.972.33 + '@aws-sdk/credential-provider-process': 3.972.29 + '@aws-sdk/credential-provider-sso': 3.972.33 + '@aws-sdk/credential-provider-web-identity': 3.972.33 + '@aws-sdk/nested-clients': 3.997.1 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -6817,10 +6815,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.32': + '@aws-sdk/credential-provider-login@3.972.33': dependencies: - '@aws-sdk/core': 3.974.2 - '@aws-sdk/nested-clients': 3.997.0 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/nested-clients': 3.997.1 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 @@ -6830,14 +6828,14 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.33': + '@aws-sdk/credential-provider-node@3.972.34': dependencies: - '@aws-sdk/credential-provider-env': 3.972.28 - '@aws-sdk/credential-provider-http': 3.972.30 - '@aws-sdk/credential-provider-ini': 3.972.32 - '@aws-sdk/credential-provider-process': 3.972.28 - '@aws-sdk/credential-provider-sso': 3.972.32 - '@aws-sdk/credential-provider-web-identity': 3.972.32 + '@aws-sdk/credential-provider-env': 3.972.29 + '@aws-sdk/credential-provider-http': 3.972.31 + '@aws-sdk/credential-provider-ini': 3.972.33 + '@aws-sdk/credential-provider-process': 3.972.29 + '@aws-sdk/credential-provider-sso': 3.972.33 + '@aws-sdk/credential-provider-web-identity': 3.972.33 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -6847,20 +6845,20 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.28': + '@aws-sdk/credential-provider-process@3.972.29': dependencies: - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.32': + '@aws-sdk/credential-provider-sso@3.972.33': dependencies: - '@aws-sdk/core': 3.974.2 - '@aws-sdk/nested-clients': 3.997.0 - '@aws-sdk/token-providers': 3.1033.0 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/nested-clients': 3.997.1 + '@aws-sdk/token-providers': 3.1034.0 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -6869,10 +6867,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.32': + '@aws-sdk/credential-provider-web-identity@3.972.33': dependencies: - '@aws-sdk/core': 3.974.2 - '@aws-sdk/nested-clients': 3.997.0 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/nested-clients': 3.997.1 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -6898,12 +6896,12 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.974.10': + '@aws-sdk/middleware-flexible-checksums@3.974.11': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/crc64-nvme': 3.972.7 '@aws-sdk/types': 3.973.8 '@smithy/is-array-buffer': 4.2.2 @@ -6942,9 +6940,9 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.31': + '@aws-sdk/middleware-sdk-s3@3.972.32': dependencies: - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-arn-parser': 3.972.3 '@smithy/core': 3.23.16 @@ -6965,32 +6963,32 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.32': + '@aws-sdk/middleware-user-agent@3.972.33': dependencies: - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.7 + '@aws-sdk/util-endpoints': 3.996.8 '@smithy/core': 3.23.16 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 '@smithy/util-retry': 4.3.3 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.0': + '@aws-sdk/nested-clients@3.997.1': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.2 + '@aws-sdk/core': 3.974.3 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.32 - '@aws-sdk/region-config-resolver': 3.972.12 - '@aws-sdk/signature-v4-multi-region': 3.996.19 + '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/region-config-resolver': 3.972.13 + '@aws-sdk/signature-v4-multi-region': 3.996.20 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.7 + '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.18 + '@aws-sdk/util-user-agent-node': 3.973.19 '@smithy/config-resolver': 4.4.17 '@smithy/core': 3.23.16 '@smithy/fetch-http-handler': 5.3.17 @@ -7020,7 +7018,7 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.972.12': + '@aws-sdk/region-config-resolver@3.972.13': dependencies: '@aws-sdk/types': 3.973.8 '@smithy/config-resolver': 4.4.17 @@ -7028,19 +7026,19 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.19': + '@aws-sdk/signature-v4-multi-region@3.996.20': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.31 + '@aws-sdk/middleware-sdk-s3': 3.972.32 '@aws-sdk/types': 3.973.8 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1033.0': + '@aws-sdk/token-providers@3.1034.0': dependencies: - '@aws-sdk/core': 3.974.2 - '@aws-sdk/nested-clients': 3.997.0 + '@aws-sdk/core': 3.974.3 + '@aws-sdk/nested-clients': 3.997.1 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -7058,7 +7056,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.996.7': + '@aws-sdk/util-endpoints@3.996.8': dependencies: '@aws-sdk/types': 3.973.8 '@smithy/types': 4.14.1 @@ -7077,9 +7075,9 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.18': + '@aws-sdk/util-user-agent-node@3.973.19': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.32 + '@aws-sdk/middleware-user-agent': 3.972.33 '@aws-sdk/types': 3.973.8 '@smithy/node-config-provider': 4.3.14 '@smithy/types': 4.14.1 @@ -7535,8 +7533,6 @@ snapshots: '@contentstack/utils@1.9.1': {} - '@contentstack/utils@1.9.1': {} - '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -10001,9 +9997,9 @@ snapshots: browserslist@4.28.2: dependencies: baseline-browser-mapping: 2.10.20 - caniuse-lite: 1.0.30001788 - electron-to-chromium: 1.5.340 - node-releases: 2.0.37 + caniuse-lite: 1.0.30001790 + electron-to-chromium: 1.5.343 + node-releases: 2.0.38 update-browserslist-db: 1.2.3(browserslist@4.28.2) bs-logger@0.2.6: @@ -10085,7 +10081,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001788: {} + caniuse-lite@1.0.30001790: {} capital-case@1.0.4: dependencies: @@ -10563,7 +10559,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.340: {} + electron-to-chromium@1.5.343: {} elegant-spinner@1.0.1: {} @@ -10580,7 +10576,7 @@ snapshots: enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.2 + tapable: 2.3.3 entities@4.5.0: {} @@ -10745,7 +10741,7 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) eslint-config-xo-space: 0.35.0(eslint@8.57.1) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-mocha: 10.5.0(eslint@8.57.1) eslint-plugin-n: 15.7.0(eslint@8.57.1) eslint-plugin-perfectionist: 2.11.0(eslint@8.57.1)(typescript@5.9.3) @@ -10807,7 +10803,7 @@ snapshots: eslint-config-xo: 0.49.0(eslint@8.57.1) eslint-config-xo-space: 0.35.0(eslint@8.57.1) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) eslint-plugin-jsdoc: 50.8.0(eslint@8.57.1) eslint-plugin-mocha: 10.5.0(eslint@8.57.1) eslint-plugin-n: 17.24.0(eslint@8.57.1)(typescript@5.9.3) @@ -10859,7 +10855,7 @@ snapshots: tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -10964,7 +10960,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11022,7 +11018,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13010,7 +13006,7 @@ snapshots: dependencies: process-on-spawn: 1.1.0 - node-releases@2.0.37: {} + node-releases@2.0.38: {} normalize-package-data@2.5.0: dependencies: @@ -13397,7 +13393,7 @@ snapshots: pluralize@8.0.0: {} - pnpm@10.33.0: {} + pnpm@10.33.1: {} possible-typed-array-names@1.1.0: {} @@ -14058,7 +14054,7 @@ snapshots: typical: 2.6.1 wordwrapjs: 3.0.0 - tapable@2.3.2: {} + tapable@2.3.3: {} tar@7.5.13: dependencies: From c71d0b5f3d26d65f626d19293ba56b125a302349 Mon Sep 17 00:00:00 2001 From: harshitha-cstk Date: Fri, 24 Apr 2026 13:47:06 +0530 Subject: [PATCH 9/9] version bump --- packages/contentstack-variants/package.json | 2 +- pnpm-lock.yaml | 426 ++++++++++---------- 2 files changed, 217 insertions(+), 211 deletions(-) diff --git a/packages/contentstack-variants/package.json b/packages/contentstack-variants/package.json index 14639db2c..fe5cadb48 100644 --- a/packages/contentstack-variants/package.json +++ b/packages/contentstack-variants/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-variants", - "version": "1.4.2", + "version": "1.4.3", "description": "Variants plugin", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc1a86203..5847da2b4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,7 +18,7 @@ importers: version: 9.1.7 pnpm: specifier: ^10.28.0 - version: 10.33.1 + version: 10.33.2 packages/contentstack-audit: dependencies: @@ -1022,44 +1022,44 @@ packages: resolution: {integrity: sha512-0XLrOT4Cm3NEhhiME7l/8LbTXS4KdsbR4dSrY207KNKTcHLLTZ9EXt4ZpgnTfLvWQF3pGP2us4Zi1fYLo0N+Ow==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.974.3': - resolution: {integrity: sha512-W3aJJm2clu8OmsrwMOMnfof13O6LGnbknnZIQeSRbxjqKah2nVvkjbUBBZVhWrt08KC69H7WsINTdrxC/2SXQw==} + '@aws-sdk/core@3.974.5': + resolution: {integrity: sha512-lMPlYlYfQdNZhlkJgnkmESwrY+hNh3PljmZ+37oAqLNdJ6rnILAwFSyc6B3bJeDOtMORNnMQIej0aTRuOlDyhQ==} engines: {node: '>=20.0.0'} '@aws-sdk/crc64-nvme@3.972.7': resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.29': - resolution: {integrity: sha512-rf+AlUxgTeSzQ/4zoS0D+Bt7XvgpY48PnWG8Yg/N9fdMgyK2Jaqa+6tLZp4MYMIMHkGrfAxnbSeb2YLMGFMg6g==} + '@aws-sdk/credential-provider-env@3.972.31': + resolution: {integrity: sha512-X/yGB73LmDW/6MdDJGCDzZBUXnM3ys4vs9l+5ZTJmiEswDdP1OjeoAFlFjVGS9o4KB2wZWQ9KOfdVNSSK6Ep3w==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.31': - resolution: {integrity: sha512-TR2/lQ3qKFj2EOrsiASzemsNEz2uzZ/SUBf48+U4Cr9a/FZlHfH/hwAeBJNBp1gMyJNxROJZhT3dn1cO+jnYfQ==} + '@aws-sdk/credential-provider-http@3.972.33': + resolution: {integrity: sha512-c0ZF+lwoWVvX5iCaGKL5T/4DnIw88CGqxA0BcBs3U86mIp5EZYPVg+KSPkMXOyokmADvNewiMUfSG2uFwjRp0g==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.33': - resolution: {integrity: sha512-UwdbJbOrgnOxZbshaNZ4DzX35h5wQd33MNYTGzWhN3ORG9lG9KQbDX6l6tDJSAdaGTktJoZPSritmUoW1rYkRA==} + '@aws-sdk/credential-provider-ini@3.972.35': + resolution: {integrity: sha512-jsU4u/cRkKFLKQS0k918FQ27fzXLG5ENiLWQMYE6581zLeI2hWh04ptlrvZMB3wJT/5d+vSzJk74X1CMFr4y8Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.33': - resolution: {integrity: sha512-WyZuPVoDM1HGNl41eVg8HSSXIB+FGkuuK63GhDbh4TMdfWU03AciWvF/QqOVWvJtWVYaLddANJ+aUklVr2ieuw==} + '@aws-sdk/credential-provider-login@3.972.35': + resolution: {integrity: sha512-5oa3j0cA50jPqgNhZ9XdJVopuzUf1klRb28/2MfLYWWiPi9DRVvbrBWT+DidbHTT36520VuXZJahQwR+YgSjrg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.34': - resolution: {integrity: sha512-sPcisURibKU4x0PCWJkWF1KJYm49Cph9dCn/PAnG5FU0wq5Id3g2v7RuEWAtNlKv1Af4gUJYBVGOeNpSEEx41A==} + '@aws-sdk/credential-provider-node@3.972.36': + resolution: {integrity: sha512-4nT2T8Z7vH8KE9EdjEsuIlHpZSlcaK2PrKbQBjuUGU46BCCzF3WvP0u0Uiosni3Ykmmn4rWLVawoOCLotUtCbg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.29': - resolution: {integrity: sha512-DURisqWS3bUgiwMXTmzymVNGlcRW0FnbPZ3SZknhmxnCXm3n9idkTJ6T+Uir359KRKtJNFLRViskk8HsSVLi1w==} + '@aws-sdk/credential-provider-process@3.972.31': + resolution: {integrity: sha512-eKeT4MXumpBJsrDLCYcSzIkFPVTFn/es7It2oogp2OhU/ic7P/+xzFpQx9ZhwtXS57Mc5S42BPWi7lHmvs/nYg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.33': - resolution: {integrity: sha512-9y9obU4IQWru9f+NiiscUeyCe5ZmQav4FKEb1qfUNrik/C3BzBGUnHQWyPEyXjOX9cb+vx1TYx0qZBtinKdzTA==} + '@aws-sdk/credential-provider-sso@3.972.35': + resolution: {integrity: sha512-bCuBdfnj0KGDMdLp6utMTLiJcFN2ek9EgZinxQZZSc3FxjJ/HSqeqab2cjbnoNfy8RM6suDCsRkmVY1izp9I+A==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.33': - resolution: {integrity: sha512-RazhlN0YAkna2T2p2v4YuuRlVBVRNo8V0SL+9JePTWDndEUAeOBAjYeQfAMbtDyCh120+zA0Op6V0jS4dw2+iw==} + '@aws-sdk/credential-provider-web-identity@3.972.35': + resolution: {integrity: sha512-swW6Bwvl8lanyEMtZOWE/oR6yqcRQH4HTQZUVsnDVgoXvRjRywpYpLv2BWwjUFyjPrqsdX6FeTkf4tMSe/qFTQ==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-bucket-endpoint@3.972.10': @@ -1070,8 +1070,8 @@ packages: resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.974.11': - resolution: {integrity: sha512-jTrJFs4SMs9xjih45+QHtU79piovA6CAlofMt4jeknN5ef9zsVEHDtuwCnEe/3eANWewa9fd6Tvc54xEPpQ3RA==} + '@aws-sdk/middleware-flexible-checksums@3.974.13': + resolution: {integrity: sha512-b6QUe2hQX9XsnCzp6mtzVaERhganDKeb8lmGL6pVhr7rRVH9S9keDFW7uKytuuqmcY5943FixoGqn/QL+sbUBA==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-host-header@3.972.10': @@ -1090,32 +1090,32 @@ packages: resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.32': - resolution: {integrity: sha512-dc2O2x0V5pGJhmdQYQveUIFtMZsur7GrGuSgoKM4oQJuEcfvwnJ3sj+ip6WnxR5l6TrX5zkl4KgcgswOy3wAzQ==} + '@aws-sdk/middleware-sdk-s3@3.972.34': + resolution: {integrity: sha512-/UL96JKjsjdodcRRMKl99tLQvK6Oi9ptLC9iU1yiTF/ruaDX0mtBBtnLNZDxIZRJOCVOtB49ed1YaTadqygk8Q==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-ssec@3.972.10': resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.33': - resolution: {integrity: sha512-mqtT3Fo7xanWMk2SbAcKLGGI/q1GHWNrExBj7cnWP2W2mkTMheXB4ntJvwPZ1UxPrQobrsv2dWFXmaOJeSOiDg==} + '@aws-sdk/middleware-user-agent@3.972.35': + resolution: {integrity: sha512-hOFWNOjVmOocpRlrU04nYxjMOeoe0Obu5AXEuhB8zblMCPl3cG1hdluQCZERRKFyhMQjwZnDbhSHjoMUjetFGw==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.997.1': - resolution: {integrity: sha512-Afc9hc2WZs3X4Jb8dnxyuYiZsLoWRO51roTCRf497gPnAKN2WRdXANu1vaVCTzwnDMOYFXb/cYv4ZSjxqAqcKA==} + '@aws-sdk/nested-clients@3.997.3': + resolution: {integrity: sha512-SivE6GP228IVgfsrr2c/vqTg95X0Qj39Yw4uIrcddpkUzIltNMoNOR62leHOLhODfjv9K8X2mPTwS69A5kT0nQ==} engines: {node: '>=20.0.0'} '@aws-sdk/region-config-resolver@3.972.13': resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.20': - resolution: {integrity: sha512-MEj6DhEcaO8RgVtFCJ+xpCQnZC3Iesr09avdY75qkMQfckQULu447IegK7Rs1MCGerVBfKnJQ4q+pQq9hI5lng==} + '@aws-sdk/signature-v4-multi-region@3.996.22': + resolution: {integrity: sha512-/rXhMXteD+BqhFd0nYprAgcZ/KtU+963uftPqd3tiFcFfooHZINXUGtOmo2SQjRVauCTNqIEzkwuSETdZFqTTA==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1034.0': - resolution: {integrity: sha512-8E+KGcD4ET0H9FXJ2/ZWbfFnQNYEkTZZYJxAs1lkdJlve1AYuqaydInIFfvNgoz5GbYtzbK8/ugsSMu5wPm6kA==} + '@aws-sdk/token-providers@3.1036.0': + resolution: {integrity: sha512-aNSJ6jjDYayxN9ZA1JpycVScX93Lx03kKZ1EXt3DGOTahcWVLJj3oLAlop0xKP+vP2Ga2t49p1tEaMkTbCCaZA==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.8': @@ -1137,8 +1137,8 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.10': resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} - '@aws-sdk/util-user-agent-node@3.973.19': - resolution: {integrity: sha512-ZAfHjpzdbrzkAftC139JoYGfXzDh5HY+AxRzw8pGJ8cULsf+l721sKAMK8mV5NvRETaW/BwghSwQhGgoNgrxMw==} + '@aws-sdk/util-user-agent-node@3.973.21': + resolution: {integrity: sha512-Av4UHTcAWgdvbN0IP9pbtf4Qa1+6LtJqQdZWj5pLn5J67w0pnJJAZZ+7JPPcj2KN3378zD2JDM9DwJKEyvyMTQ==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1146,8 +1146,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.18': - resolution: {integrity: sha512-BMDNVG1ETXRhl1tnisQiYBef3RShJ1kfZA7x7afivTFMLirfHNTb6U71K569HNXhSXbQZsweHvSDZ6euBw8hPA==} + '@aws-sdk/xml-builder@3.972.19': + resolution: {integrity: sha512-Cw8IOMdBUEIl8ZlhRC3Dc/E64D5B5/8JhV6vhPLiPfJwcRC84S6F8aBOIi/N4vR9ZyA4I5Cc0Ateb/9EHaJXeQ==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.4': @@ -1915,6 +1915,9 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@nodable/entities@2.1.0': + resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2048,8 +2051,8 @@ packages: resolution: {integrity: sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.16': - resolution: {integrity: sha512-JStomOrINQA1VqNEopLsgcdgwd42au7mykKqVr30XFw89wLt9sDxJDi4djVPRwQmmzyTGy/uOvTc2ultMpFi1w==} + '@smithy/core@3.23.17': + resolution: {integrity: sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==} engines: {node: '>=18.0.0'} '@smithy/credential-provider-imds@4.2.14': @@ -2112,16 +2115,16 @@ packages: resolution: {integrity: sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.31': - resolution: {integrity: sha512-KJPdCIN2kOE2aGmqZd7eUTr4WQwOGgtLWgUkswGJggs7rBcQYQjcZMEDa3C0DwbOiXS9L8/wDoQHkfxBYLfiLw==} + '@smithy/middleware-endpoint@4.4.32': + resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.5.4': - resolution: {integrity: sha512-/z7nIFK+ZRW3Ie/l3NEVGdy34LvmEOzBrtBAvgWZ/4PrKX0xP3kWm8pkfcwUk523SqxZhdbQP9JSXgjF77Uhpw==} + '@smithy/middleware-retry@4.5.5': + resolution: {integrity: sha512-wnYOpB5vATFKWrY2Z9Alb0KhjZI6AbzU6Fbz3Hq2GnURdRYWB4q+qWivQtSTwXcmWUA3MZ6krfwL6Cq5MAbxsA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.19': - resolution: {integrity: sha512-Q6y+W9h3iYVMCKWDoVge+OC1LKFqbEKaq8SIWG2X2bWJRpd/6dDLyICcNLT6PbjH3Rr6bmg/SeDB25XFOFfeEw==} + '@smithy/middleware-serde@4.2.20': + resolution: {integrity: sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==} engines: {node: '>=18.0.0'} '@smithy/middleware-stack@4.2.14': @@ -2132,8 +2135,8 @@ packages: resolution: {integrity: sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.6.0': - resolution: {integrity: sha512-P734cAoTFtuGfWa/R3jgBnGlURt2w9bYEBwQNMKf58sRM9RShirB2mKwLsVP+jlG/wxpCu8abv8NxdUts8tdLA==} + '@smithy/node-http-handler@4.6.1': + resolution: {integrity: sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==} engines: {node: '>=18.0.0'} '@smithy/property-provider@4.2.14': @@ -2164,8 +2167,8 @@ packages: resolution: {integrity: sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.12.12': - resolution: {integrity: sha512-daO7SJn4eM6ArbmrEs+/BTbH7af8AEbSL3OMQdcRvvn8tuUcR5rU2n6DgxIV53aXMS42uwK8NgKKCh5XgqYOPQ==} + '@smithy/smithy-client@4.12.13': + resolution: {integrity: sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==} engines: {node: '>=18.0.0'} '@smithy/types@4.14.1': @@ -2200,12 +2203,12 @@ packages: resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.48': - resolution: {integrity: sha512-hxVRVPYaRDWa6YQdse1aWX1qrksmLsvNyGBKdc32q4jFzSjxYVNWfstknAfR228TnzS4tzgswXRuYIbhXBuXFQ==} + '@smithy/util-defaults-mode-browser@4.3.49': + resolution: {integrity: sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.53': - resolution: {integrity: sha512-ybgCk+9JdBq8pYC8Y6U5fjyS8e4sboyAShetxPNL0rRBtaVl56GSFAxsolVBIea1tXR4LPIzL8i6xqmcf0+DCQ==} + '@smithy/util-defaults-mode-node@4.2.54': + resolution: {integrity: sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@3.4.2': @@ -2220,12 +2223,12 @@ packages: resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.3.3': - resolution: {integrity: sha512-idjUvd4M9Jj6rXkhqw4H4reHoweuK4ZxYWyOrEp4N2rOF5VtaOlQGLDQJva/8WanNXk9ScQtsAb7o5UHGvFm4A==} + '@smithy/util-retry@4.3.4': + resolution: {integrity: sha512-FY1UQQ1VFmMwiYp1GVS4MeaGD5O0blLNYK0xCRHU+mJgeoH/hSY8Ld8sJWKQ6uznkh14HveRGQJncgPyNl9J+A==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.24': - resolution: {integrity: sha512-na5vv2mBSDzXewLEEoWGI7LQQkfpmFEomBsmOpzLFjqGctm0iMwXY5lAwesY9pIaErkccW0qzEOUcYP+WKneXg==} + '@smithy/util-stream@4.5.25': + resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@4.2.2': @@ -2746,8 +2749,8 @@ packages: ajv: optional: true - ajv@6.14.0: - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} @@ -2966,8 +2969,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.20: - resolution: {integrity: sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==} + baseline-browser-mapping@2.10.21: + resolution: {integrity: sha512-Q+rUQ7Uz8AHM7DEaNdwvfFCTq7a43lNTzuS94eiWqwyxfV/wJv+oUivef51T91mmRY4d4A1u9rcSvkeufCVXlA==} engines: {node: '>=6.0.0'} hasBin: true @@ -3533,8 +3536,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.343: - resolution: {integrity: sha512-YHnQ3MXI08icvL9ZKnEBy05F2EQ8ob01UaMOuMbM8l+4UcAq6MPPbBTJBbsBUg3H8JeZNt+O4fjsoWth3p6IFg==} + electron-to-chromium@1.5.344: + resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==} elegant-spinner@1.0.1: resolution: {integrity: sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==} @@ -3553,8 +3556,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.20.1: - resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + enhanced-resolve@5.21.0: + resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -3925,8 +3928,8 @@ packages: fast-xml-builder@1.1.5: resolution: {integrity: sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==} - fast-xml-parser@5.5.8: - resolution: {integrity: sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==} + fast-xml-parser@5.7.1: + resolution: {integrity: sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==} hasBin: true fastest-levenshtein@1.0.16: @@ -5494,8 +5497,8 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - pnpm@10.33.1: - resolution: {integrity: sha512-Bbo8HV0cGPaN8GRw10BV5i1B/BEKDGYNsbLfsnhTJ/BM8PaDRdRgm8Ugief6A0PDFZOy+VlOLF1dpCYjCsyYIA==} + pnpm@10.33.2: + resolution: {integrity: sha512-qQ+vb+6rca1sblf5Tg/hoS9dzCLNdU20CulZPraj4LaxLjVAIYuzeuCDQEsfLObbKkEh6XmCm0r/lLmfSdoc+A==} engines: {node: '>=18.12'} hasBin: true @@ -6651,42 +6654,42 @@ snapshots: dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.3 - '@aws-sdk/credential-provider-node': 3.972.34 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/credential-provider-node': 3.972.36 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/middleware-user-agent': 3.972.35 '@aws-sdk/region-config-resolver': 3.972.13 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.19 + '@aws-sdk/util-user-agent-node': 3.973.21 '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/fetch-http-handler': 5.3.17 '@smithy/hash-node': 4.2.14 '@smithy/invalid-dependency': 4.2.14 '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.31 - '@smithy/middleware-retry': 4.5.4 - '@smithy/middleware-serde': 4.2.19 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.48 - '@smithy/util-defaults-mode-node': 4.2.53 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 - '@smithy/util-stream': 4.5.24 + '@smithy/util-retry': 4.3.4 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 '@smithy/util-waiter': 4.2.16 tslib: 2.8.1 @@ -6698,26 +6701,26 @@ snapshots: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.3 - '@aws-sdk/credential-provider-node': 3.972.34 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/credential-provider-node': 3.972.36 '@aws-sdk/middleware-bucket-endpoint': 3.972.10 '@aws-sdk/middleware-expect-continue': 3.972.10 - '@aws-sdk/middleware-flexible-checksums': 3.974.11 + '@aws-sdk/middleware-flexible-checksums': 3.974.13 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-location-constraint': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-sdk-s3': 3.972.32 + '@aws-sdk/middleware-sdk-s3': 3.972.34 '@aws-sdk/middleware-ssec': 3.972.10 - '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/middleware-user-agent': 3.972.35 '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.20 + '@aws-sdk/signature-v4-multi-region': 3.996.22 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.19 + '@aws-sdk/util-user-agent-node': 3.973.21 '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/eventstream-serde-browser': 4.2.14 '@smithy/eventstream-serde-config-resolver': 4.3.14 '@smithy/eventstream-serde-node': 4.2.14 @@ -6728,45 +6731,45 @@ snapshots: '@smithy/invalid-dependency': 4.2.14 '@smithy/md5-js': 4.2.14 '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.31 - '@smithy/middleware-retry': 4.5.4 - '@smithy/middleware-serde': 4.2.19 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.48 - '@smithy/util-defaults-mode-node': 4.2.53 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 - '@smithy/util-stream': 4.5.24 + '@smithy/util-retry': 4.3.4 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 '@smithy/util-waiter': 4.2.16 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.974.3': + '@aws-sdk/core@3.974.5': dependencies: '@aws-sdk/types': 3.973.8 - '@aws-sdk/xml-builder': 3.972.18 - '@smithy/core': 3.23.16 + '@aws-sdk/xml-builder': 3.972.19 + '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.4 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 @@ -6775,37 +6778,37 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.29': + '@aws-sdk/credential-provider-env@3.972.31': dependencies: - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.31': + '@aws-sdk/credential-provider-http@3.972.33': dependencies: - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/types': 3.973.8 '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.33': + '@aws-sdk/credential-provider-ini@3.972.35': dependencies: - '@aws-sdk/core': 3.974.3 - '@aws-sdk/credential-provider-env': 3.972.29 - '@aws-sdk/credential-provider-http': 3.972.31 - '@aws-sdk/credential-provider-login': 3.972.33 - '@aws-sdk/credential-provider-process': 3.972.29 - '@aws-sdk/credential-provider-sso': 3.972.33 - '@aws-sdk/credential-provider-web-identity': 3.972.33 - '@aws-sdk/nested-clients': 3.997.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/credential-provider-env': 3.972.31 + '@aws-sdk/credential-provider-http': 3.972.33 + '@aws-sdk/credential-provider-login': 3.972.35 + '@aws-sdk/credential-provider-process': 3.972.31 + '@aws-sdk/credential-provider-sso': 3.972.35 + '@aws-sdk/credential-provider-web-identity': 3.972.35 + '@aws-sdk/nested-clients': 3.997.3 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -6815,10 +6818,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.33': + '@aws-sdk/credential-provider-login@3.972.35': dependencies: - '@aws-sdk/core': 3.974.3 - '@aws-sdk/nested-clients': 3.997.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 @@ -6828,14 +6831,14 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.34': + '@aws-sdk/credential-provider-node@3.972.36': dependencies: - '@aws-sdk/credential-provider-env': 3.972.29 - '@aws-sdk/credential-provider-http': 3.972.31 - '@aws-sdk/credential-provider-ini': 3.972.33 - '@aws-sdk/credential-provider-process': 3.972.29 - '@aws-sdk/credential-provider-sso': 3.972.33 - '@aws-sdk/credential-provider-web-identity': 3.972.33 + '@aws-sdk/credential-provider-env': 3.972.31 + '@aws-sdk/credential-provider-http': 3.972.33 + '@aws-sdk/credential-provider-ini': 3.972.35 + '@aws-sdk/credential-provider-process': 3.972.31 + '@aws-sdk/credential-provider-sso': 3.972.35 + '@aws-sdk/credential-provider-web-identity': 3.972.35 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -6845,20 +6848,20 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.29': + '@aws-sdk/credential-provider-process@3.972.31': dependencies: - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.33': + '@aws-sdk/credential-provider-sso@3.972.35': dependencies: - '@aws-sdk/core': 3.974.3 - '@aws-sdk/nested-clients': 3.997.1 - '@aws-sdk/token-providers': 3.1034.0 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/token-providers': 3.1036.0 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -6867,10 +6870,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.33': + '@aws-sdk/credential-provider-web-identity@3.972.35': dependencies: - '@aws-sdk/core': 3.974.3 - '@aws-sdk/nested-clients': 3.997.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -6896,12 +6899,12 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.974.11': + '@aws-sdk/middleware-flexible-checksums@3.974.13': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/crc64-nvme': 3.972.7 '@aws-sdk/types': 3.973.8 '@smithy/is-array-buffer': 4.2.2 @@ -6909,7 +6912,7 @@ snapshots: '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 @@ -6940,20 +6943,20 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.32': + '@aws-sdk/middleware-sdk-s3@3.972.34': dependencies: - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 @@ -6963,56 +6966,56 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.33': + '@aws-sdk/middleware-user-agent@3.972.35': dependencies: - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.4 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.1': + '@aws-sdk/nested-clients@3.997.3': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.3 + '@aws-sdk/core': 3.974.5 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/middleware-user-agent': 3.972.35 '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.20 + '@aws-sdk/signature-v4-multi-region': 3.996.22 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.19 + '@aws-sdk/util-user-agent-node': 3.973.21 '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/fetch-http-handler': 5.3.17 '@smithy/hash-node': 4.2.14 '@smithy/invalid-dependency': 4.2.14 '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.31 - '@smithy/middleware-retry': 4.5.4 - '@smithy/middleware-serde': 4.2.19 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.48 - '@smithy/util-defaults-mode-node': 4.2.53 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.4 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: @@ -7026,19 +7029,19 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.20': + '@aws-sdk/signature-v4-multi-region@3.996.22': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.32 + '@aws-sdk/middleware-sdk-s3': 3.972.34 '@aws-sdk/types': 3.973.8 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1034.0': + '@aws-sdk/token-providers@3.1036.0': dependencies: - '@aws-sdk/core': 3.974.3 - '@aws-sdk/nested-clients': 3.997.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -7075,19 +7078,19 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.19': + '@aws-sdk/util-user-agent-node@3.973.21': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.33 + '@aws-sdk/middleware-user-agent': 3.972.35 '@aws-sdk/types': 3.973.8 '@smithy/node-config-provider': 4.3.14 '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.18': + '@aws-sdk/xml-builder@3.972.19': dependencies: '@smithy/types': 4.14.1 - fast-xml-parser: 5.5.8 + fast-xml-parser: 5.7.1 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.4': {} @@ -7700,7 +7703,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: - ajv: 6.14.0 + ajv: 6.15.0 debug: 4.4.3(supports-color@8.1.1) espree: 9.6.1 globals: 13.24.0 @@ -7714,7 +7717,7 @@ snapshots: '@eslint/eslintrc@3.3.5': dependencies: - ajv: 6.14.0 + ajv: 6.15.0 debug: 4.4.3(supports-color@8.1.1) espree: 10.4.0 globals: 14.0.0 @@ -8423,6 +8426,8 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@nodable/entities@2.1.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -8628,7 +8633,7 @@ snapshots: '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/core@3.23.16': + '@smithy/core@3.23.17': dependencies: '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 @@ -8636,7 +8641,7 @@ snapshots: '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 '@smithy/uuid': 1.1.2 tslib: 2.8.1 @@ -8732,10 +8737,10 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.31': + '@smithy/middleware-endpoint@4.4.32': dependencies: - '@smithy/core': 3.23.16 - '@smithy/middleware-serde': 4.2.19 + '@smithy/core': 3.23.17 + '@smithy/middleware-serde': 4.2.20 '@smithy/node-config-provider': 4.3.14 '@smithy/shared-ini-file-loader': 4.4.9 '@smithy/types': 4.14.1 @@ -8743,22 +8748,22 @@ snapshots: '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/middleware-retry@4.5.4': + '@smithy/middleware-retry@4.5.5': dependencies: - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/protocol-http': 5.3.14 '@smithy/service-error-classification': 4.3.0 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.4 '@smithy/uuid': 1.1.2 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.19': + '@smithy/middleware-serde@4.2.20': dependencies: - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -8775,7 +8780,7 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/node-http-handler@4.6.0': + '@smithy/node-http-handler@4.6.1': dependencies: '@smithy/protocol-http': 5.3.14 '@smithy/querystring-builder': 4.2.14 @@ -8823,14 +8828,14 @@ snapshots: '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/smithy-client@4.12.12': + '@smithy/smithy-client@4.12.13': dependencies: - '@smithy/core': 3.23.16 - '@smithy/middleware-endpoint': 4.4.31 + '@smithy/core': 3.23.17 + '@smithy/middleware-endpoint': 4.4.32 '@smithy/middleware-stack': 4.2.14 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 tslib: 2.8.1 '@smithy/types@4.14.1': @@ -8871,20 +8876,20 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.48': + '@smithy/util-defaults-mode-browser@4.3.49': dependencies: '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.53': + '@smithy/util-defaults-mode-node@4.2.54': dependencies: '@smithy/config-resolver': 4.4.17 '@smithy/credential-provider-imds': 4.2.14 '@smithy/node-config-provider': 4.3.14 '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -8903,16 +8908,16 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-retry@4.3.3': + '@smithy/util-retry@4.3.4': dependencies: '@smithy/service-error-classification': 4.3.0 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-stream@4.5.24': + '@smithy/util-stream@4.5.25': dependencies: '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-buffer-from': 4.2.2 @@ -9704,7 +9709,7 @@ snapshots: optionalDependencies: ajv: 8.18.0 - ajv@6.14.0: + ajv@6.15.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 @@ -9948,7 +9953,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.20: {} + baseline-browser-mapping@2.10.21: {} big-json@3.2.0: dependencies: @@ -9996,9 +10001,9 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.20 + baseline-browser-mapping: 2.10.21 caniuse-lite: 1.0.30001790 - electron-to-chromium: 1.5.343 + electron-to-chromium: 1.5.344 node-releases: 2.0.38 update-browserslist-db: 1.2.3(browserslist@4.28.2) @@ -10559,7 +10564,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.343: {} + electron-to-chromium@1.5.344: {} elegant-spinner@1.0.1: {} @@ -10573,7 +10578,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.20.1: + enhanced-resolve@5.21.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -11085,7 +11090,7 @@ snapshots: eslint-plugin-n@17.24.0(eslint@8.57.1)(typescript@4.9.5): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - enhanced-resolve: 5.20.1 + enhanced-resolve: 5.21.0 eslint: 8.57.1 eslint-plugin-es-x: 7.8.0(eslint@8.57.1) get-tsconfig: 4.14.0 @@ -11100,7 +11105,7 @@ snapshots: eslint-plugin-n@17.24.0(eslint@8.57.1)(typescript@5.9.3): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - enhanced-resolve: 5.20.1 + enhanced-resolve: 5.21.0 eslint: 8.57.1 eslint-plugin-es-x: 7.8.0(eslint@8.57.1) get-tsconfig: 4.14.0 @@ -11235,7 +11240,7 @@ snapshots: '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.3.0 - ajv: 6.14.0 + ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.3(supports-color@8.1.1) @@ -11282,7 +11287,7 @@ snapshots: '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - ajv: 6.14.0 + ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.3(supports-color@8.1.1) @@ -11417,8 +11422,9 @@ snapshots: dependencies: path-expression-matcher: 1.5.0 - fast-xml-parser@5.5.8: + fast-xml-parser@5.7.1: dependencies: + '@nodable/entities': 2.1.0 fast-xml-builder: 1.1.5 path-expression-matcher: 1.5.0 strnum: 2.2.3 @@ -13393,7 +13399,7 @@ snapshots: pluralize@8.0.0: {} - pnpm@10.33.1: {} + pnpm@10.33.2: {} possible-typed-array-names@1.1.0: {}