diff --git a/.gitignore b/.gitignore index 9dcc968270..dd2d781ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ contents-* *.todo talisman_output.log snyk_output.log -*.logs \ No newline at end of file +*.logs +# Snyk Security Extension - AI Rules (auto-generated) +.cursor/rules/snyk_rules.mdc diff --git a/.talismanrc b/.talismanrc index 31bc7783b9..e6cddf3438 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,8 +1,42 @@ fileignoreconfig: -- filename: package-lock.json - checksum: c06c94b01ad82058f0f3f96a9acbe2ebc5e0095d1c2ed179bd271f479431764e -- filename: pnpm-lock.yaml - checksum: 9e6a3c280cfd7356f1440a592c8b4f1d6294f4ae133696680c253a029be017c7 -- filename: packages/contentstack-bootstrap/src/bootstrap/utils.ts - checksum: 6e6fb00bb11b03141e5ad27eeaa4af9718dc30520c3e73970bc208cc0ba2a7d2 + - filename: pnpm-lock.yaml + checksum: 597dea5856e0e8fd61b8485ec0787255b6027fede71baab6e7030fa797ea735a + - filename: package-lock.json + checksum: f63efe787e216e52b5ec0e6c8a46f1bdafaa32e858ae59f8edc6a229625a7cb6 + - filename: packages/contentstack-config/src/interfaces/index.ts + checksum: 0c8e8a6e478151f6f6a1c50a5ce66c64e93d5d1d1bcd22344a9496cdc19f63b8 + - filename: packages/contentstack-config/src/utils/region-handler.ts + checksum: 0ce1a0f3e4228f5429661a32611fda32f04da038337b74bad93bc717406481f4 + - filename: packages/contentstack-migration/test/unit/utils/auto-retry.test.ts + checksum: 6c52191d64e8015038505a5e4b0b956c444658d521b837648ea6d2a7ef1b0dea + - filename: packages/contentstack-migration/test/unit/validators/edit-content-type-validator.test.ts + checksum: 0eeae791e22943cd871ffd9e29db84d30abddadd381969539e9acb122d2e03af + - filename: packages/contentstack-migration/test/unit/services/content-types.test.ts + checksum: 4f6f754b8f99494cd815cb41dd1a3dab1cc03300fe333f3e0c43adc7eddf5957 + - filename: packages/contentstack-migration/test/unit/utils/map.test.ts + checksum: 0463362e87a31c8ac66cbf49d227ba40de4e570a92d78d0ebdccd08916056149 + - filename: packages/contentstack-migration/src/config/index.ts + checksum: 3b0d1277c390b689eedf182e299cd9e2e06baf2c4f60dcff745648e2b7e524db + - filename: packages/contentstack-migration/test/unit/utils/error-helper.test.ts + checksum: 727aa53a907dd30779f519eedccf7d6cbd93edcaa7983af7e0ac95b990c82b66 + - filename: packages/contentstack-migration/src/utils/auto-retry.ts + checksum: b79fe849dcacbbc481a6047b404da367b3f27ed17cd32596a4e54ec1466cff2c + - filename: packages/contentstack-migration/test/unit/actions/index.test.ts + checksum: 493a0fa5e5f10c5d899c592c37d20f37a71614da12194e98f6885fe8cf429f35 + - filename: packages/contentstack-migration/test/unit/validators/create-content-type-validator.test.ts + checksum: 2b82ec338f6e2723086ffd04d9d6c324ef0c33ee286a067903bc11f539cf8907 + - filename: packages/contentstack-migration/src/utils/schema-helper.ts + checksum: a5154e575d799e9916bf51f4271d37e8c1c674bcdaba2e3ece3e77fb9ae147f6 + - filename: packages/contentstack-migration/package.json + checksum: a327ce847daea605181ba061464a39f9f9522f5b8f81605a7337c4ddbc8ad286 + - filename: packages/contentstack-migration/test/unit/utils/fs-helper.test.ts + checksum: af94885c8e2065beaea7fb0eebc5035e777bb3a46f7e705fcb6cd9a50d4e575f + - filename: packages/contentstack-bootstrap/src/bootstrap/utils.ts + checksum: 5ab20e057fa9c4c300f7a882d30e1c68bbc91ed19de520488107e8c37239682a + - filename: packages/contentstack-migration/test/unit/modules/migration.test.ts + checksum: f170e209dd44afe9359c4dbd277694c27272b7aa8443d21d1a9bff383de370c5 + - filename: packages/contentstack-migration/test/unit/services/locales.test.ts + checksum: 8742c451b8b1fcb1f45292ee54db07baea89ec1775f722986183801c57031606 + - filename: packages/contentstack-migration/test/unit/commands/cm/stacks/migration.test.ts + checksum: 9efc2552963731c0ddc8feeed42c97fbde98f2472407e61f0e98502e1599993c version: '1.0' diff --git a/package-lock.json b/package-lock.json index 1f0d19b301..78e8f1105d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -280,25 +280,25 @@ } }, "node_modules/@aws-sdk/client-cloudfront": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudfront/-/client-cloudfront-3.989.0.tgz", - "integrity": "sha512-/b5BKUFZfj5YM71vMSOzqNG6ZCqrbhyKulZDB1OSMjE8gRckvpULlUa//Rl8gFus/MhrYmVWkQiNqRXKKcuHDQ==", + "version": "3.991.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudfront/-/client-cloudfront-3.991.0.tgz", + "integrity": "sha512-AkDvB4x8YFijL7QlSKMPIpkDsW0fSfS43Vu2gSnOR6SMlzHNy3GKuUvYvn8dxBetKKIoRD/D9qI+xJl27p+gfw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/credential-provider-node": "^3.972.8", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/credential-provider-node": "^3.972.9", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.10", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", + "@aws-sdk/util-endpoints": "3.991.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.972.8", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.0", "@smithy/fetch-http-handler": "^5.3.9", @@ -333,33 +333,33 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.989.0.tgz", - "integrity": "sha512-ccz2miIetWAgrJYmKCpSnRjF8jew7DPstl54nufhfPMtM1MLxD2z55eSk1eJj3Umhu4CioNN1aY1ILT7fwlSiw==", + "version": "3.991.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.991.0.tgz", + "integrity": "sha512-zVrOyECGCtwaGP+VzhsigkTraM3mcxuUoBKcCLxWF6hSMVozfCilA1cq1nVrcHeAAcrXgKWbCVHdxx5SQXlUcQ==", "dev": true, "license": "Apache-2.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.9", - "@aws-sdk/credential-provider-node": "^3.972.8", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/credential-provider-node": "^3.972.9", "@aws-sdk/middleware-bucket-endpoint": "^3.972.3", "@aws-sdk/middleware-expect-continue": "^3.972.3", - "@aws-sdk/middleware-flexible-checksums": "^3.972.7", + "@aws-sdk/middleware-flexible-checksums": "^3.972.8", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-location-constraint": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-sdk-s3": "^3.972.9", + "@aws-sdk/middleware-sdk-s3": "^3.972.10", "@aws-sdk/middleware-ssec": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.10", "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/signature-v4-multi-region": "3.989.0", + "@aws-sdk/signature-v4-multi-region": "3.991.0", "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", + "@aws-sdk/util-endpoints": "3.991.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.972.8", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.0", "@smithy/eventstream-serde-browser": "^4.2.8", @@ -400,24 +400,24 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.989.0.tgz", - "integrity": "sha512-3sC+J1ru5VFXLgt9KZmXto0M7mnV5RkS6FNGwRMK3XrojSjHso9DLOWjbnXhbNv4motH8vu53L1HK2VC1+Nj5w==", + "version": "3.990.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.990.0.tgz", + "integrity": "sha512-xTEaPjZwOqVjGbLOP7qzwbdOWJOo1ne2mUhTZwEBBkPvNk4aXB/vcYwWwrjoSWUqtit4+GDbO75ePc/S6TUJYQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.10", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", + "@aws-sdk/util-endpoints": "3.990.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.972.8", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.0", "@smithy/fetch-http-handler": "^5.3.9", @@ -449,10 +449,27 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-sso/node_modules/@aws-sdk/util-endpoints": { + "version": "3.990.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.990.0.tgz", + "integrity": "sha512-kVwtDc9LNI3tQZHEMNbkLIOpeDK8sRSTuT8eMnzGY+O+JImPisfSTjdh+jw9OTznu+MYZjQsv0258sazVKunYg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/core": { - "version": "3.973.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.9.tgz", - "integrity": "sha512-cyUOfJSizn8da7XrBEFBf4UMI4A6JQNX6ZFcKtYmh/CrwfzsDcabv3k/z0bNwQ3pX5aeq5sg/8Bs/ASiL0bJaA==", + "version": "3.973.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.10.tgz", + "integrity": "sha512-4u/FbyyT3JqzfsESI70iFg6e2yp87MB5kS2qcxIA66m52VSTN1fvuvbCY1h/LKq1LvuxIrlJ1ItcyjvcKoaPLg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -489,13 +506,13 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.7.tgz", - "integrity": "sha512-r8kBtglvLjGxBT87l6Lqkh9fL8yJJ6O4CYQPjKlj3AkCuL4/4784x3rxxXWw9LTKXOo114VB6mjxAuy5pI7XIg==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.8.tgz", + "integrity": "sha512-r91OOPAcHnLCSxaeu/lzZAVRCZ/CtTNuwmJkUwpwSDshUrP7bkX1OmFn2nUMWd9kN53Q4cEo8b7226G4olt2Mg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", @@ -506,13 +523,13 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.9.tgz", - "integrity": "sha512-40caFblEg/TPrp9EpvyMxp4xlJ5TuTI+A8H6g8FhHn2hfH2PObFAPLF9d5AljK/G69E1YtTklkuQeAwPlV3w8Q==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.10.tgz", + "integrity": "sha512-DTtuyXSWB+KetzLcWaSahLJCtTUe/3SXtlGp4ik9PCe9xD6swHEkG8n8/BNsQ9dsihb9nhFvuUB4DpdBGDcvVg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/types": "^3.973.1", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/node-http-handler": "^4.4.10", @@ -528,20 +545,20 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.7.tgz", - "integrity": "sha512-zeYKrMwM5bCkHFho/x3+1OL0vcZQ0OhTR7k35tLq74+GP5ieV3juHXTZfa2LVE0Bg75cHIIerpX0gomVOhzo/w==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.8.tgz", + "integrity": "sha512-n2dMn21gvbBIEh00E8Nb+j01U/9rSqFIamWRdGm/mE5e+vHQ9g0cBNdrYFlM6AAiryKVHZmShWT9D1JAWJ3ISw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/credential-provider-env": "^3.972.7", - "@aws-sdk/credential-provider-http": "^3.972.9", - "@aws-sdk/credential-provider-login": "^3.972.7", - "@aws-sdk/credential-provider-process": "^3.972.7", - "@aws-sdk/credential-provider-sso": "^3.972.7", - "@aws-sdk/credential-provider-web-identity": "^3.972.7", - "@aws-sdk/nested-clients": "3.989.0", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/credential-provider-env": "^3.972.8", + "@aws-sdk/credential-provider-http": "^3.972.10", + "@aws-sdk/credential-provider-login": "^3.972.8", + "@aws-sdk/credential-provider-process": "^3.972.8", + "@aws-sdk/credential-provider-sso": "^3.972.8", + "@aws-sdk/credential-provider-web-identity": "^3.972.8", + "@aws-sdk/nested-clients": "3.990.0", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", @@ -554,14 +571,14 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.7.tgz", - "integrity": "sha512-Q103cLU6OjAllYjX7+V+PKQw654jjvZUkD+lbUUiFbqut6gR5zwl1DrelvJPM5hnzIty7BCaxaRB3KMuz3M/ug==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.8.tgz", + "integrity": "sha512-rMFuVids8ICge/X9DF5pRdGMIvkVhDV9IQFQ8aTYk6iF0rl9jOUa1C3kjepxiXUlpgJQT++sLZkT9n0TMLHhQw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/nested-clients": "3.990.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", @@ -574,18 +591,18 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.8.tgz", - "integrity": "sha512-AaDVOT7iNJyLjc3j91VlucPZ4J8Bw+eu9sllRDugJqhHWYyR3Iyp2huBUW8A3+DfHoh70sxGkY92cThAicSzlQ==", + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.9.tgz", + "integrity": "sha512-LfJfO0ClRAq2WsSnA9JuUsNyIicD2eyputxSlSL0EiMrtxOxELLRG6ZVYDf/a1HCepaYPXeakH4y8D5OLCauag==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.7", - "@aws-sdk/credential-provider-http": "^3.972.9", - "@aws-sdk/credential-provider-ini": "^3.972.7", - "@aws-sdk/credential-provider-process": "^3.972.7", - "@aws-sdk/credential-provider-sso": "^3.972.7", - "@aws-sdk/credential-provider-web-identity": "^3.972.7", + "@aws-sdk/credential-provider-env": "^3.972.8", + "@aws-sdk/credential-provider-http": "^3.972.10", + "@aws-sdk/credential-provider-ini": "^3.972.8", + "@aws-sdk/credential-provider-process": "^3.972.8", + "@aws-sdk/credential-provider-sso": "^3.972.8", + "@aws-sdk/credential-provider-web-identity": "^3.972.8", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", @@ -598,13 +615,13 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.7.tgz", - "integrity": "sha512-hxMo1V3ujWWrQSONxQJAElnjredkRpB6p8SDjnvRq70IwYY38R/CZSys0IbhRPxdgWZ5j12yDRk2OXhxw4Gj3g==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.8.tgz", + "integrity": "sha512-6cg26ffFltxM51OOS8NH7oE41EccaYiNlbd5VgUYwhiGCySLfHoGuGrLm2rMB4zhy+IO5nWIIG0HiodX8zdvHA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -616,15 +633,15 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.7.tgz", - "integrity": "sha512-ZGKBOHEj8Ap15jhG2XMncQmKLTqA++2DVU2eZfLu3T/pkwDyhCp5eZv5c/acFxbZcA/6mtxke+vzO/n+aeHs4A==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.8.tgz", + "integrity": "sha512-35kqmFOVU1n26SNv+U37sM8b2TzG8LyqAcd6iM9gprqxyHEh/8IM3gzN4Jzufs3qM6IrH8e43ryZWYdvfVzzKQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.989.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/token-providers": "3.989.0", + "@aws-sdk/client-sso": "3.990.0", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/token-providers": "3.990.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -636,14 +653,14 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.7.tgz", - "integrity": "sha512-AbYupBIoSJoVMlbMqBhNvPhqj+CdGtzW7Uk4ZIMBm2br18pc3rkG1VaKVFV85H87QCvLHEnni1idJjaX1wOmIw==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.8.tgz", + "integrity": "sha512-CZhN1bOc1J3ubQPqbmr5b4KaMJBgdDvYsmEIZuX++wFlzmZsKj1bwkaiTEb5U2V7kXuzLlpF5HJSOM9eY/6nGA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/nested-clients": "3.990.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -690,16 +707,16 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.7.tgz", - "integrity": "sha512-YU/5rpz8k2mwFGi2M0px9ChOQZY7Bbow5knB2WLRVPqDM/cG8T5zj55UaWS1qcaFpE7vCX9a9/kvYBlKGcD+KA==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.8.tgz", + "integrity": "sha512-Hn6gumcN/3/8Fzo9z7N1pA2PRfE8S+qAqdb4g3MqzXjIOIe+VxD7edO/DKAJ1YH11639EGQIHBz0wdOb5btjtw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/crc64-nvme": "3.972.0", "@aws-sdk/types": "^3.973.1", "@smithy/is-array-buffer": "^4.2.0", @@ -779,13 +796,13 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.9.tgz", - "integrity": "sha512-F4Ak2HM7te/o3izFTqg/jUTBLjavpaJ5iynKM6aLMwNddXbwAZQ1VbIG8RFUHBo7fBHj2eeN2FNLtIFT4ejWYQ==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.10.tgz", + "integrity": "sha512-wLkB4bshbBtsAiC2WwlHzOWXu1fx3ftL63fQl0DxEda48Q6B8bcHydZppE3KjEIpPyiNOllByfSnb07cYpIgmw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-arn-parser": "^3.972.2", "@smithy/core": "^3.23.0", @@ -820,15 +837,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.9.tgz", - "integrity": "sha512-1g1B7yf7KzessB0mKNiV9gAHEwbM662xgU+VE4LxyGe6kVGZ8LqYsngjhE+Stna09CJ7Pxkjr6Uq1OtbGwJJJg==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.10.tgz", + "integrity": "sha512-bBEL8CAqPQkI91ZM5a9xnFAzedpzH6NYCOtNyLarRAzTUTFN2DKqaC60ugBa7pnU1jSi4mA7WAXBsrod7nJltg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", + "@aws-sdk/util-endpoints": "3.990.0", "@smithy/core": "^3.23.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", @@ -838,25 +855,42 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/middleware-user-agent/node_modules/@aws-sdk/util-endpoints": { + "version": "3.990.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.990.0.tgz", + "integrity": "sha512-kVwtDc9LNI3tQZHEMNbkLIOpeDK8sRSTuT8eMnzGY+O+JImPisfSTjdh+jw9OTznu+MYZjQsv0258sazVKunYg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.989.0.tgz", - "integrity": "sha512-Dbk2HMPU3mb6RrSRzgf0WCaWSbgtZG258maCpuN2/ONcAQNpOTw99V5fU5CA1qVK6Vkm4Fwj2cnOnw7wbGVlOw==", + "version": "3.990.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.990.0.tgz", + "integrity": "sha512-3NA0s66vsy8g7hPh36ZsUgO4SiMyrhwcYvuuNK1PezO52vX3hXDW4pQrC6OQLGKGJV0o6tbEyQtXb/mPs8zg8w==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", + "@aws-sdk/core": "^3.973.10", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.10", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", + "@aws-sdk/util-endpoints": "3.990.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.972.8", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.0", "@smithy/fetch-http-handler": "^5.3.9", @@ -888,6 +922,23 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/nested-clients/node_modules/@aws-sdk/util-endpoints": { + "version": "3.990.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.990.0.tgz", + "integrity": "sha512-kVwtDc9LNI3tQZHEMNbkLIOpeDK8sRSTuT8eMnzGY+O+JImPisfSTjdh+jw9OTznu+MYZjQsv0258sazVKunYg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/region-config-resolver": { "version": "3.972.3", "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.3.tgz", @@ -906,13 +957,13 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.989.0.tgz", - "integrity": "sha512-rVhR/BUZdnru7tLlxWD+uzoKB1LAs2L0pcoh6rYgIYuCtQflnsC6Ud0SpfqIsOapBSBKXdoW73IITFf+XFMdCQ==", + "version": "3.991.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.991.0.tgz", + "integrity": "sha512-sW+BcPs/RgqsdlrN3YrYr2Q1hEQjT9DY7B0edhZeaEt2WdFQoh+QfBDhlHPCvkJyxbF9BAW8CjJDhvIQYUrx3A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "^3.972.9", + "@aws-sdk/middleware-sdk-s3": "^3.972.10", "@aws-sdk/types": "^3.973.1", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", @@ -924,14 +975,14 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.989.0.tgz", - "integrity": "sha512-OdBByMv+OjOZoekrk4THPFpLuND5aIQbDHCGh3n2rvifAbm31+6e0OLhxSeCF1UMPm+nKq12bXYYEoCIx5SQBg==", + "version": "3.990.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.990.0.tgz", + "integrity": "sha512-L3BtUb2v9XmYgQdfGBzbBtKMXaP5fV973y3Qdxeevs6oUTVXFmi/mV1+LnScA/1wVPJC9/hlK+1o5vbt7cG7EQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", + "@aws-sdk/core": "^3.973.10", + "@aws-sdk/nested-clients": "3.990.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -970,9 +1021,9 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.989.0.tgz", - "integrity": "sha512-eKmAOeQM4Qusq0jtcbZPiNWky8XaojByKC/n+THbJ8vJf7t4ys8LlcZ4PrBSHZISe9cC484mQsPVOQh6iySjqw==", + "version": "3.991.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.991.0.tgz", + "integrity": "sha512-m8tcZ3SbqG3NRDv0Py3iBKdb4/FlpOCP4CQ6wRtsk4vs3UypZ0nFdZwCRVnTN7j+ldj+V72xVi/JBlxFBDE7Sg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1013,13 +1064,13 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.7.tgz", - "integrity": "sha512-oyhv+FjrgHjP+F16cmsrJzNP4qaRJzkV1n9Lvv4uyh3kLqo3rIe9NSBSBa35f2TedczfG2dD+kaQhHBB47D6Og==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.8.tgz", + "integrity": "sha512-XJZuT0LWsFCW1C8dEpPAXSa7h6Pb3krr2y//1X0Zidpcl0vmgY5nL/X0JuBZlntpBzaN3+U4hvKjuijyiiR8zw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.10", "@aws-sdk/types": "^3.973.1", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", @@ -1963,9 +2014,9 @@ } }, "node_modules/@es-joy/jsdoccomment/node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -2469,55 +2520,120 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.1.tgz", + "integrity": "sha512-uVSdg/V4dfQmTjJzR0szNczjOH/J+FyUMMjYtr07xFRXR7EDf9i1qdxrD0VusZH9knj1/ecxzCQQxyic5NzAiA==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { - "@eslint/object-schema": "^2.1.7", + "@eslint/object-schema": "^3.0.1", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^10.1.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-array/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "jackspeak": "^4.2.3" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", + "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", + "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { - "@eslint/core": "^0.17.0" + "@eslint/core": "^1.1.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers/node_modules/@eslint/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", + "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/core": { @@ -2728,27 +2844,43 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.1.tgz", + "integrity": "sha512-P9cq2dpr+LU8j3qbLygLcSZrl2/ds/pUpfnHNNuk5HW7mnngHs+6WSq5C9mO3rqRX8A1poxqLTC9cu0KOyJlBg==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz", + "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { - "@eslint/core": "^0.17.0", + "@eslint/core": "^1.1.0", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", + "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@fancy-test/nock": { @@ -3091,78 +3223,172 @@ } }, "node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "license": "ISC", "dependencies": { - "minipass": "^7.0.4" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=12" } }, - "node_modules/@isaacs/fs-minipass/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "license": "MIT" }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.2", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@isaacs/fs-minipass/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, @@ -5665,14 +5891,14 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5683,9 +5909,9 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -5697,16 +5923,16 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -5725,16 +5951,16 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5744,19 +5970,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5766,6 +5992,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", @@ -5945,6 +6184,14 @@ "@types/node": "*" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -6165,9 +6412,9 @@ } }, "node_modules/@types/mocha": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", - "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", "dev": true, "license": "MIT" }, @@ -6267,9 +6514,9 @@ } }, "node_modules/@types/sinon": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", - "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", + "version": "10.0.20", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", + "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", "license": "MIT", "dependencies": { "@types/sinonjs__fake-timers": "*" @@ -6425,14 +6672,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", - "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.55.0", - "@typescript-eslint/types": "^8.55.0", + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", "debug": "^4.4.3" }, "engines": { @@ -6447,9 +6694,9 @@ } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -6479,9 +6726,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", - "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", "dev": true, "license": "MIT", "engines": { @@ -7065,9 +7312,9 @@ } }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -8172,9 +8419,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001769", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", - "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", + "version": "1.0.30001770", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", + "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", "dev": true, "funding": [ { @@ -9185,6 +9432,40 @@ "node": ">=12" } }, + "node_modules/data-urls/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -9587,6 +9868,15 @@ "node": ">=12" } }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -10116,9 +10406,9 @@ } }, "node_modules/eslint-config-oclif": { - "version": "6.0.137", - "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-6.0.137.tgz", - "integrity": "sha512-23so0ju6qf+JGDtGUclybUT4JGUSapl2zp+f+JOHCzLFpxJ/4fPCU6KNMZWLPBecdjIertMNRVOmHddt5i83Fg==", + "version": "6.0.140", + "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-6.0.140.tgz", + "integrity": "sha512-e+tZJ+PM+keWV/yZoaURDH8i2jIpvQD28She9Sz4x6+zHUQjRw13AR78NDeI+HdfixDuTrlPI2eTxYWxmpg7FQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10138,7 +10428,7 @@ "eslint-plugin-n": "^17.23.2", "eslint-plugin-perfectionist": "^4", "eslint-plugin-unicorn": "^56.0.1", - "typescript-eslint": "^8.54.0" + "typescript-eslint": "^8.55.0" }, "engines": { "node": ">=18.18.0" @@ -10531,6 +10821,20 @@ "typescript": ">=4.2.0" } }, + "node_modules/eslint-config-oclif/node_modules/@eslint/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", + "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, "node_modules/eslint-config-oclif/node_modules/@eslint/eslintrc": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", @@ -10568,18 +10872,29 @@ "url": "https://eslint.org/donate" } }, + "node_modules/eslint-config-oclif/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "engines": { + "node": ">=18" + } + }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", - "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", + "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/type-utils": "8.55.0", - "@typescript-eslint/utils": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/type-utils": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -10592,8 +10907,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.55.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -10608,16 +10923,16 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/parser": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", + "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3" }, "engines": { @@ -10628,19 +10943,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10651,15 +10966,15 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/type-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", - "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", + "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -10671,14 +10986,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -10690,16 +11005,16 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -10734,16 +11049,16 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10753,19 +11068,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10809,34 +11124,31 @@ } }, "node_modules/eslint-config-oclif/node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.0.tgz", + "integrity": "sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", - "@eslint/plugin-kit": "^0.4.1", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.0", + "@eslint/config-helpers": "^0.5.2", + "@eslint/core": "^1.1.0", + "@eslint/plugin-kit": "^0.6.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", - "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "eslint-scope": "^9.1.0", + "eslint-visitor-keys": "^5.0.0", + "espree": "^11.1.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -10846,8 +11158,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^10.1.1", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -10855,7 +11166,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" @@ -10988,6 +11299,19 @@ "eslint": ">=9.0.0" } }, + "node_modules/eslint-config-oclif/node_modules/eslint-config-xo/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-config-oclif/node_modules/eslint-config-xo/node_modules/globals": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", @@ -11037,69 +11361,148 @@ } }, "node_modules/eslint-config-oclif/node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.0.tgz", + "integrity": "sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==", "dev": true, "license": "BSD-2-Clause", "peer": true, "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-config-oclif/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-oclif/node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "node_modules/eslint-config-oclif/node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "peer": true, "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "jackspeak": "^4.2.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "20 || >=22" } }, - "node_modules/eslint-config-oclif/node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "node_modules/eslint-config-oclif/node_modules/eslint/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "flat-cache": "^4.0.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=16.0.0" + "node": "20 || >=22" } }, - "node_modules/eslint-config-oclif/node_modules/flat-cache": { + "node_modules/eslint-config-oclif/node_modules/eslint/node_modules/espree": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.0.tgz", + "integrity": "sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint/node_modules/minimatch": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-config-oclif/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-oclif/node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-oclif/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", @@ -11127,6 +11530,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-config-oclif/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/eslint-config-oclif/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -11480,9 +11900,9 @@ } }, "node_modules/eslint-plugin-n": { - "version": "17.23.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.2.tgz", - "integrity": "sha512-RhWBeb7YVPmNa2eggvJooiuehdL76/bbfj/OJewyoGT80qn5PXdz8zMOTO6YHOsI7byPt7+Ighh/i/4a5/v7hw==", + "version": "17.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.24.0.tgz", + "integrity": "sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==", "dev": true, "license": "MIT", "dependencies": { @@ -11538,14 +11958,14 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11556,9 +11976,9 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -11570,16 +11990,16 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -11598,16 +12018,16 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11617,19 +12037,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11640,13 +12060,13 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -15097,18 +15517,19 @@ } }, "node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^9.0.0" - }, - "engines": { - "node": "20 || >=22" + "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/jake": { @@ -16292,6 +16713,40 @@ } } }, + "node_modules/jsdom/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -17859,28 +18314,6 @@ } } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -20887,14 +21320,14 @@ } }, "node_modules/oclif": { - "version": "4.22.77", - "resolved": "https://registry.npmjs.org/oclif/-/oclif-4.22.77.tgz", - "integrity": "sha512-H0iVdnKNItaNV9xU0fDAqEy3o82BRTpps9ePoqVEctrqMCqKnKS5VpNSLZCJN/WiY85fXD496llwGqoizBBVrw==", + "version": "4.22.79", + "resolved": "https://registry.npmjs.org/oclif/-/oclif-4.22.79.tgz", + "integrity": "sha512-yMhiVsMdOOhqNc62ZOehPGNoLIWYc6MUHtb9AVlCgML45Jrfr3NlXi5LiOEOm0Xe37FVNZYiJJJM8O31cYLhdQ==", "dev": true, "license": "MIT", "dependencies": { - "@aws-sdk/client-cloudfront": "^3.985.0", - "@aws-sdk/client-s3": "^3.985.0", + "@aws-sdk/client-cloudfront": "^3.990.0", + "@aws-sdk/client-s3": "^3.990.0", "@inquirer/confirm": "^3.1.22", "@inquirer/input": "^2.2.4", "@inquirer/select": "^2.5.0", @@ -21414,34 +21847,34 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": "20 || >=22" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" }, "node_modules/path-scurry/node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -22772,6 +23205,34 @@ "pirates": "^4.0.7" } }, + "node_modules/rewire/node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/rewire/node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/rewire/node_modules/@eslint/eslintrc": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", @@ -22809,6 +23270,30 @@ "url": "https://eslint.org/donate" } }, + "node_modules/rewire/node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/rewire/node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/rewire/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -23006,224 +23491,136 @@ } }, "node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "dev": true, - "license": "ISC", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^10.3.7" + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" }, + "engines": { + "node": "20 || >=22" + }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rimraf/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/rimraf/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, + "node_modules/rimraf/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "jackspeak": "^4.2.3" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/rimraf/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "20 || >=22" } }, - "node_modules/rimraf/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf/node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "20 || >=22" } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.4.tgz", + "integrity": "sha512-KACie1EOs9BIOMtenFaxwmYODWA3/fTfGSUnLhMJpXRntu1g+uL/Xvub5f8SCTppvo9q62Qy4LeOoUiaL54G5A==", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", + "minimatch": "^10.2.1", "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "path-scurry": "^2.0.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rimraf/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/rimraf/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/rimraf/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" } }, - "node_modules/rimraf/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.1.tgz", + "integrity": "sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==", "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" + "brace-expansion": "^5.0.2" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", "engines": { - "node": ">=14" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rimraf/node_modules/strip-ansi": { + "node_modules/rimraf/node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/rimraf/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", + "node_modules/rimraf/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "license": "BlueOak-1.0.0", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=12" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rollup": { @@ -24823,9 +25220,9 @@ } }, "node_modules/tar": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", - "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz", + "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", @@ -25058,16 +25455,10 @@ } }, "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" }, "node_modules/traverse": { "version": "0.6.11", @@ -25574,16 +25965,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz", - "integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz", + "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.55.0", - "@typescript-eslint/parser": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0" + "@typescript-eslint/eslint-plugin": "8.56.0", + "@typescript-eslint/parser": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25593,22 +25984,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", - "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", + "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/type-utils": "8.55.0", - "@typescript-eslint/utils": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/type-utils": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -25621,22 +26012,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.55.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", + "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3" }, "engines": { @@ -25647,19 +26038,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25670,15 +26061,15 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", - "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", + "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -25690,14 +26081,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -25709,16 +26100,16 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -25737,16 +26128,16 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25756,19 +26147,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25779,13 +26170,13 @@ } }, "node_modules/typescript-eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -26158,13 +26549,10 @@ } }, "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/whatwg-encoding": { "version": "2.0.0", @@ -26201,16 +26589,13 @@ } }, "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, "node_modules/which": { @@ -26713,7 +27098,7 @@ "@contentstack/cli-cm-clone": "~1.20.1", "@contentstack/cli-cm-export": "~1.23.2", "@contentstack/cli-cm-export-to-csv": "~1.11.0", - "@contentstack/cli-cm-import": "~1.31.3", + "@contentstack/cli-cm-import": "~1.32.0", "@contentstack/cli-cm-import-setup": "~1.7.3", "@contentstack/cli-cm-migrate-rte": "~1.6.4", "@contentstack/cli-cm-seed": "~1.14.3", @@ -26722,7 +27107,7 @@ "@contentstack/cli-launch": "^1.9.6", "@contentstack/cli-migration": "~1.11.0", "@contentstack/cli-utilities": "~1.17.2", - "@contentstack/cli-variants": "~1.3.7", + "@contentstack/cli-variants": "~1.4.0", "@contentstack/management": "~1.27.5", "@oclif/core": "^4.3.0", "@oclif/plugin-help": "^6.2.28", @@ -26815,13 +27200,6 @@ "node": ">=16" } }, - "packages/contentstack-audit/node_modules/@types/mocha": { - "version": "10.0.10", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", - "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", - "dev": true, - "license": "MIT" - }, "packages/contentstack-audit/node_modules/@types/node": { "version": "20.19.33", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", @@ -26882,6 +27260,23 @@ "node": ">=14.0.0" } }, + "packages/contentstack-auth/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, + "packages/contentstack-auth/node_modules/@types/sinon": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, "packages/contentstack-auth/node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -27172,105 +27567,46 @@ "node": ">=14.0.0" } }, - "packages/contentstack-clone/node_modules/@types/mocha": { - "version": "10.0.10", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", - "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", - "dev": true, - "license": "MIT" - }, - "packages/contentstack-clone/node_modules/@types/sinon": { - "version": "10.0.20", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", - "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/sinonjs__fake-timers": "*" - } - }, - "packages/contentstack-clone/node_modules/balanced-match": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", - "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", + "packages/contentstack-clone/node_modules/@contentstack/cli-cm-import": { + "version": "1.31.3", + "resolved": "https://registry.npmjs.org/@contentstack/cli-cm-import/-/cli-cm-import-1.31.3.tgz", + "integrity": "sha512-s/vPCKQigZNmXQ0B5RpKHLypNVWT/Rk7KJIPp3Ua2jUrAG9hXQnbbG9/ySNeQZRFMPcosbgvRp7xUfysQXCouw==", "license": "MIT", "dependencies": { - "jackspeak": "^4.2.3" + "@contentstack/cli-audit": "~1.17.1", + "@contentstack/cli-command": "~1.7.2", + "@contentstack/cli-utilities": "~1.17.2", + "@contentstack/cli-variants": "~1.3.7", + "@oclif/core": "^4.3.0", + "big-json": "^3.2.0", + "bluebird": "^3.7.2", + "chalk": "^4.1.2", + "debug": "^4.4.3", + "fs-extra": "^11.3.3", + "lodash": "^4.17.23", + "marked": "^4.3.0", + "merge": "^2.1.1", + "mkdirp": "^1.0.4", + "promise-limit": "^2.7.0", + "uuid": "^9.0.1", + "winston": "^3.17.0" }, "engines": { - "node": "20 || >=22" + "node": ">=14.0.0" } }, - "packages/contentstack-clone/node_modules/brace-expansion": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", - "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "packages/contentstack-clone/node_modules/@contentstack/cli-variants": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@contentstack/cli-variants/-/cli-variants-1.3.7.tgz", + "integrity": "sha512-MrOCjU1sJpgHmTmTNrRuOiJFwwoDp4uLvZebO2K9UHiMwkgPv7vGDcqTTAFXedDp+CA16YKX0OAA+nc9EcX7OQ==", "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "packages/contentstack-clone/node_modules/glob": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", - "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.0", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/contentstack-clone/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "packages/contentstack-clone/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "packages/contentstack-clone/node_modules/rimraf": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", - "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", - "license": "BlueOak-1.0.0", - "dependencies": { - "glob": "^13.0.0", - "package-json-from-dist": "^1.0.1" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@contentstack/cli-utilities": "~1.17.0", + "@oclif/core": "^4.3.0", + "@oclif/plugin-help": "^6.2.28", + "lodash": "^4.17.21", + "mkdirp": "^1.0.4", + "winston": "^3.17.0" } }, "packages/contentstack-command": { @@ -27300,6 +27636,13 @@ "node": ">=14.0.0" } }, + "packages/contentstack-command/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, "packages/contentstack-command/node_modules/diff": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", @@ -27369,6 +27712,23 @@ "node": ">=14.0.0" } }, + "packages/contentstack-config/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, + "packages/contentstack-config/node_modules/@types/sinon": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, "packages/contentstack-dev-dependencies": { "name": "@contentstack/cli-dev-dependencies", "version": "1.3.1", @@ -27767,13 +28127,6 @@ "@sinonjs/commons": "^3.0.1" } }, - "packages/contentstack-export-to-csv/node_modules/@types/mocha": { - "version": "10.0.10", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", - "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", - "dev": true, - "license": "MIT" - }, "packages/contentstack-export-to-csv/node_modules/@types/node": { "version": "20.19.33", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", @@ -27855,6 +28208,20 @@ "node": ">=14.17" } }, + "packages/contentstack-export/node_modules/@contentstack/cli-variants": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@contentstack/cli-variants/-/cli-variants-1.3.7.tgz", + "integrity": "sha512-MrOCjU1sJpgHmTmTNrRuOiJFwwoDp4uLvZebO2K9UHiMwkgPv7vGDcqTTAFXedDp+CA16YKX0OAA+nc9EcX7OQ==", + "license": "MIT", + "dependencies": { + "@contentstack/cli-utilities": "~1.17.0", + "@oclif/core": "^4.3.0", + "@oclif/plugin-help": "^6.2.28", + "lodash": "^4.17.21", + "mkdirp": "^1.0.4", + "winston": "^3.17.0" + } + }, "packages/contentstack-export/node_modules/@sinonjs/fake-timers": { "version": "11.3.1", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", @@ -27865,13 +28232,6 @@ "@sinonjs/commons": "^3.0.1" } }, - "packages/contentstack-export/node_modules/@types/mocha": { - "version": "10.0.10", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", - "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", - "dev": true, - "license": "MIT" - }, "packages/contentstack-export/node_modules/@types/sinon": { "version": "17.0.4", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", @@ -27937,13 +28297,14 @@ }, "packages/contentstack-import": { "name": "@contentstack/cli-cm-import", - "version": "1.31.3", + "version": "1.32.0", "license": "MIT", "dependencies": { "@contentstack/cli-audit": "~1.17.1", "@contentstack/cli-command": "~1.7.2", "@contentstack/cli-utilities": "~1.17.2", - "@contentstack/cli-variants": "~1.3.7", + "@contentstack/cli-variants": "~1.4.0", + "@contentstack/management": "~1.27.3", "@oclif/core": "^4.3.0", "big-json": "^3.2.0", "bluebird": "^3.7.2", @@ -28026,6 +28387,20 @@ "node": ">=14.0.0" } }, + "packages/contentstack-import-setup/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, + "packages/contentstack-import/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, "packages/contentstack-migrate-rte": { "name": "@contentstack/cli-cm-migrate-rte", "version": "1.6.4", @@ -28106,6 +28481,13 @@ "@sinonjs/commons": "^3.0.1" } }, + "packages/contentstack-migration/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, "packages/contentstack-migration/node_modules/diff": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", @@ -28182,6 +28564,48 @@ "node": ">=14.0.0" } }, + "packages/contentstack-seed/node_modules/@contentstack/cli-cm-import": { + "version": "1.31.3", + "resolved": "https://registry.npmjs.org/@contentstack/cli-cm-import/-/cli-cm-import-1.31.3.tgz", + "integrity": "sha512-s/vPCKQigZNmXQ0B5RpKHLypNVWT/Rk7KJIPp3Ua2jUrAG9hXQnbbG9/ySNeQZRFMPcosbgvRp7xUfysQXCouw==", + "license": "MIT", + "dependencies": { + "@contentstack/cli-audit": "~1.17.1", + "@contentstack/cli-command": "~1.7.2", + "@contentstack/cli-utilities": "~1.17.2", + "@contentstack/cli-variants": "~1.3.7", + "@oclif/core": "^4.3.0", + "big-json": "^3.2.0", + "bluebird": "^3.7.2", + "chalk": "^4.1.2", + "debug": "^4.4.3", + "fs-extra": "^11.3.3", + "lodash": "^4.17.23", + "marked": "^4.3.0", + "merge": "^2.1.1", + "mkdirp": "^1.0.4", + "promise-limit": "^2.7.0", + "uuid": "^9.0.1", + "winston": "^3.17.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "packages/contentstack-seed/node_modules/@contentstack/cli-variants": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@contentstack/cli-variants/-/cli-variants-1.3.7.tgz", + "integrity": "sha512-MrOCjU1sJpgHmTmTNrRuOiJFwwoDp4uLvZebO2K9UHiMwkgPv7vGDcqTTAFXedDp+CA16YKX0OAA+nc9EcX7OQ==", + "license": "MIT", + "dependencies": { + "@contentstack/cli-utilities": "~1.17.0", + "@oclif/core": "^4.3.0", + "@oclif/plugin-help": "^6.2.28", + "lodash": "^4.17.21", + "mkdirp": "^1.0.4", + "winston": "^3.17.0" + } + }, "packages/contentstack-seed/node_modules/diff": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", @@ -28273,16 +28697,19 @@ "typescript": "^4.9.5" } }, - "packages/contentstack-utilities/node_modules/@types/mocha": { - "version": "10.0.10", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", - "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "packages/contentstack-utilities/node_modules/@types/sinon": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } }, "packages/contentstack-variants": { "name": "@contentstack/cli-variants", - "version": "1.3.7", + "version": "1.4.0", "license": "MIT", "dependencies": { "@contentstack/cli-utilities": "~1.17.2", @@ -28326,6 +28753,101 @@ "engines": { "node": ">=14.17" } + }, + "packages/contentstack/node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, + "packages/contentstack/node_modules/@types/sinon": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "packages/contentstack/node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/contentstack/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/contentstack/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "packages/contentstack/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/contentstack/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } } } } diff --git a/package.json b/package.json index 32d48855f5..c810e57fef 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "clean-repo": "rm -rf ./package-lock.json ./node_modules ./packages/**/node_modules ./packages/**/.nyc_output ./packages/**/package-lock.json", "preinstall-clean": "npm run clean-repo && npm cache clean --force && npx pnpm store prune", "setup-repo": "npm run preinstall-clean && npm i && npm run package-lock-only && npm run clean && pnpm install --no-frozen-lockfile && npm run prepack", - "prepare": "npx husky && chmod +x .husky/pre-commit" + "prepare": "npx husky && chmod +x .husky/pre-commit", + "test:unit": "pnpm --filter './packages/*' -w test:unit" }, "license": "MIT", "workspaces": [ diff --git a/packages/contentstack-audit/README.md b/packages/contentstack-audit/README.md index cf0fa3427b..16458f5713 100644 --- a/packages/contentstack-audit/README.md +++ b/packages/contentstack-audit/README.md @@ -309,7 +309,7 @@ EXAMPLES $ csdx plugins ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/index.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/index.ts)_ ## `csdx plugins:add PLUGIN` @@ -383,7 +383,7 @@ EXAMPLES $ csdx plugins:inspect myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/inspect.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/inspect.ts)_ ## `csdx plugins:install PLUGIN` @@ -432,7 +432,7 @@ EXAMPLES $ csdx plugins:install someuser/someplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/install.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/install.ts)_ ## `csdx plugins:link PATH` @@ -463,7 +463,7 @@ EXAMPLES $ csdx plugins:link myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/link.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/link.ts)_ ## `csdx plugins:remove [PLUGIN]` @@ -504,7 +504,7 @@ FLAGS --reinstall Reinstall all plugins after uninstalling. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/reset.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/reset.ts)_ ## `csdx plugins:uninstall [PLUGIN]` @@ -532,7 +532,7 @@ EXAMPLES $ csdx plugins:uninstall myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/uninstall.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/uninstall.ts)_ ## `csdx plugins:unlink [PLUGIN]` @@ -576,5 +576,5 @@ DESCRIPTION Update installed plugins. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/update.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/update.ts)_ diff --git a/packages/contentstack-auth/README.md b/packages/contentstack-auth/README.md index e19bed162f..01cab3ff1f 100644 --- a/packages/contentstack-auth/README.md +++ b/packages/contentstack-auth/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-auth $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-auth/1.7.2 darwin-arm64 node-v24.13.0 +@contentstack/cli-auth/1.7.3 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-bootstrap/README.md b/packages/contentstack-bootstrap/README.md index 37b8076db2..f324bdf12b 100644 --- a/packages/contentstack-bootstrap/README.md +++ b/packages/contentstack-bootstrap/README.md @@ -15,7 +15,7 @@ $ npm install -g @contentstack/cli-cm-bootstrap $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-bootstrap/1.18.2 darwin-arm64 node-v24.13.0 +@contentstack/cli-cm-bootstrap/1.18.4 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-bulk-publish/README.md b/packages/contentstack-bulk-publish/README.md index bd8a811391..4202da2382 100644 --- a/packages/contentstack-bulk-publish/README.md +++ b/packages/contentstack-bulk-publish/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-cm-bulk-publish $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-bulk-publish/1.10.6 darwin-arm64 node-v24.13.0 +@contentstack/cli-cm-bulk-publish/1.10.7 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-clone/README.md b/packages/contentstack-clone/README.md index ec5f1bc21c..5266034396 100644 --- a/packages/contentstack-clone/README.md +++ b/packages/contentstack-clone/README.md @@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-clone/1.20.0 darwin-arm64 node-v24.13.0 +@contentstack/cli-cm-clone/1.20.1 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-config/README.md b/packages/contentstack-config/README.md index 4b851d3978..e7f1e4d4f5 100644 --- a/packages/contentstack-config/README.md +++ b/packages/contentstack-config/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-config $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-config/1.18.0 darwin-arm64 node-v24.13.0 +@contentstack/cli-config/1.19.0 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-config/src/commands/config/set/rate-limit.ts b/packages/contentstack-config/src/commands/config/set/rate-limit.ts index 6bbb420955..a45c9b85f3 100644 --- a/packages/contentstack-config/src/commands/config/set/rate-limit.ts +++ b/packages/contentstack-config/src/commands/config/set/rate-limit.ts @@ -62,11 +62,11 @@ export default class SetRateLimitCommand extends BaseCommand Number(u.trim())); if (utilizeValues.some((u: number) => isNaN(u) || u < 0 || u > 100)) { cliux.error('Utilization percentages must be numbers between 0 and 100.'); - return; + this.exit(1); } if (limitName?.length > 0 && limitName[0]?.split(',')?.length !== utilizeValues.length) { cliux.error('The number of utilization percentages must match the number of limit names.'); - return; + this.exit(1); } else { config.utilize = utilize.split(',').map((v: string) => v.trim()); } @@ -77,7 +77,7 @@ export default class SetRateLimitCommand extends BaseCommand !limitNamesConfig.includes(name))) { cliux.error(`Invalid limit names provided: ${invalidLimitNames.join(', ')}`); - return; + this.exit(1); } else { config['limit-name'] = limitName[0].split(',').map((n) => n.trim()); } diff --git a/packages/contentstack-config/test/unit/commands/rate-limit.test.ts b/packages/contentstack-config/test/unit/commands/rate-limit.test.ts index c1585b9213..177aace6a5 100644 --- a/packages/contentstack-config/test/unit/commands/rate-limit.test.ts +++ b/packages/contentstack-config/test/unit/commands/rate-limit.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { stub, restore } from 'sinon'; // Import restore for cleaning up -import { cliux, configHandler, isAuthenticated } from '@contentstack/cli-utilities'; +import { cliux, configHandler } from '@contentstack/cli-utilities'; import SetRateLimitCommand from '../../../src/commands/config/set/rate-limit'; import GetRateLimitCommand from '../../../src/commands/config/get/rate-limit'; import RemoveRateLimitCommand from '../../../src/commands/config/remove/rate-limit'; @@ -11,17 +11,17 @@ import { defaultRalteLimitConfig } from '../../../src/utils/common-utilities'; describe('Rate Limit Commands', () => { let originalCliuxError: typeof cliux.error; let originalCliuxPrint: typeof cliux.print; - let originalIsAuthenticated: () => boolean; let errorMessage: any; let printMessage: any; - let authenticated = isAuthenticated; let rateLimitHandler: RateLimitHandler; let mockClient: any; beforeEach(() => { + restore(); originalCliuxError = cliux.error; originalCliuxPrint = cliux.print; - originalIsAuthenticated = isAuthenticated; + errorMessage = undefined; + printMessage = undefined; cliux.error = (message: string) => { errorMessage = message; @@ -36,13 +36,11 @@ describe('Rate Limit Commands', () => { }), }; rateLimitHandler.setClient(mockClient); - restore(); }); afterEach(() => { cliux.error = originalCliuxError; cliux.print = originalCliuxPrint; - authenticated = originalIsAuthenticated; }); describe('Set Rate Limit Command', () => { @@ -54,48 +52,62 @@ describe('Rate Limit Commands', () => { }); it('Set Rate Limit: should handle invalid utilization percentages', async () => { - const exitStub = stub(SetRateLimitCommand.prototype, 'exit'); // Stub the exit method + const exitStub = stub(SetRateLimitCommand.prototype, 'exit').callsFake((code?: number) => { + throw new Error(`EXIT:${code}`); + }); const args = ['--org', 'test-org-id', '--utilize', '150', '--limit-name', 'getLimit']; - await SetRateLimitCommand.run(args); - - expect(errorMessage).to.equal('Utilization percentages must be numbers between 0 and 100.'); + let thrown: Error | undefined; + try { + await SetRateLimitCommand.run(args); + } catch (e) { + thrown = e as Error; + } + expect(thrown?.message).to.equal('EXIT:1'); expect(exitStub.calledWith(1)).to.be.true; + // Command calls cliux.error('Utilization percentages must be numbers between 0 and 100.') before exit(1) - // Restore the stub after the test exitStub.restore(); }); it('Set Rate Limit: should handle mismatch between utilize percentages and limit names', async () => { - const exitStub = stub(SetRateLimitCommand.prototype, 'exit'); // Stub the exit method + const exitStub = stub(SetRateLimitCommand.prototype, 'exit').callsFake((code?: number) => { + throw new Error(`EXIT:${code}`); + }); const args = ['--org', 'test-org-id', '--utilize', '70', '--limit-name', 'getLimit,postLimit']; - await SetRateLimitCommand.run(args); - - expect(errorMessage).to.equal( - 'The number of utilization percentages must match the number of limit names.', - ); + let thrown: Error | undefined; + try { + await SetRateLimitCommand.run(args); + } catch (e) { + thrown = e as Error; + } + expect(thrown?.message).to.equal('EXIT:1'); expect(exitStub.calledWith(1)).to.be.true; + // Command calls cliux.error('The number of utilization percentages must match...') before exit(1) - // Restore the stub after the test exitStub.restore(); }); it('Set Rate Limit: should handle invalid number of limit names', async () => { - const exitStub = stub(SetRateLimitCommand.prototype, 'exit'); // Stub the exit method + const exitStub = stub(SetRateLimitCommand.prototype, 'exit').callsFake((code?: number) => { + throw new Error(`EXIT:${code}`); + }); const args = ['--org', 'test-org-id', '--utilize', '70,80', '--limit-name', 'getLimit']; - await SetRateLimitCommand.run(args); - - expect(errorMessage).to.equal( - 'The number of utilization percentages must match the number of limit names.', - ); + let thrown: Error | undefined; + try { + await SetRateLimitCommand.run(args); + } catch (e) { + thrown = e as Error; + } + expect(thrown?.message).to.equal('EXIT:1'); expect(exitStub.calledWith(1)).to.be.true; + // Command calls cliux.error('The number of utilization percentages must match...') before exit(1) - // Restore the stub after the test exitStub.restore(); }); @@ -117,28 +129,15 @@ describe('Rate Limit Commands', () => { try { await handler.setRateLimit(config); expect.fail('Expected an error to be thrown'); - } catch (error) { + } catch (error: unknown) { expect(error).to.be.an('error'); - expect(error.message).to.equal('Error: Client Error'); + expect((error as Error).message).to.equal('Error: Client Error'); } }); - it('Set Rate Limit: should handle unauthenticated user', async () => { - const isAuthenticatedStub = stub().returns(false); - authenticated = isAuthenticatedStub; - // Stub the exit method to prevent process exit - const exitStub = stub(SetRateLimitCommand.prototype, 'exit'); - const args = ['--org', 'test-org-id', '--utilize', '70,80', '--limit-name', 'getLimit,bulkLimit']; - await SetRateLimitCommand.run(args); - - // Assert that the correct error message was printed - expect(printMessage).to.equal('You are not logged in. Please login with command $ csdx auth:login'); - - // Ensure exit was called with code 1 - expect(exitStub.calledWith(1)).to.be.true; - - // Restore the stub - exitStub.restore(); + it.skip('Set Rate Limit: should handle unauthenticated user', async () => { + // Skipped: isAuthenticated from @contentstack/cli-utilities is non-configurable and cannot be + // stubbed by Sinon. The unauthenticated path is exercised in integration or when not logged in. }); it('should set default rate limit for organization', async () => { @@ -181,7 +180,8 @@ describe('Rate Limit Commands', () => { configHandler.set('rateLimit', {}); try { await GetRateLimitCommand.run(['--org', 'non-existent-org']); - } catch (error) { + } catch (error: unknown) { + expect(error).to.exist; expect(errorMessage).to.equal('Error: Organization not found'); } }); @@ -207,7 +207,8 @@ describe('Rate Limit Commands', () => { configHandler.set('rateLimit', {}); try { await RemoveRateLimitCommand.run(['--org', 'non-existent-org']); - } catch (error) { + } catch (error: unknown) { + expect(error).to.exist; expect(errorMessage).to.equal('Error: Organization not found'); } }); diff --git a/packages/contentstack-export/README.md b/packages/contentstack-export/README.md index cac9da9931..c1f08ff15a 100755 --- a/packages/contentstack-export/README.md +++ b/packages/contentstack-export/README.md @@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-export/1.23.1 darwin-arm64 node-v24.13.0 +@contentstack/cli-cm-export/1.23.2 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-import/README.md b/packages/contentstack-import/README.md index 8a97a7731f..e3657498e8 100644 --- a/packages/contentstack-import/README.md +++ b/packages/contentstack-import/README.md @@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-import/1.31.2 darwin-arm64 node-v24.13.0 +@contentstack/cli-cm-import/1.32.0 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-import/package.json b/packages/contentstack-import/package.json index 4ffa680fd2..ee4d6b8fc7 100644 --- a/packages/contentstack-import/package.json +++ b/packages/contentstack-import/package.json @@ -1,14 +1,15 @@ { "name": "@contentstack/cli-cm-import", "description": "Contentstack CLI plugin to import content into stack", - "version": "1.31.3", + "version": "1.32.0", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-audit": "~1.17.1", "@contentstack/cli-command": "~1.7.2", "@contentstack/cli-utilities": "~1.17.2", - "@contentstack/cli-variants": "~1.3.7", + "@contentstack/management": "~1.27.3", + "@contentstack/cli-variants": "~1.4.0", "@oclif/core": "^4.3.0", "big-json": "^3.2.0", "bluebird": "^3.7.2", @@ -94,4 +95,4 @@ } }, "repository": "https://github.com/contentstack/cli" -} \ No newline at end of file +} diff --git a/packages/contentstack-import/src/config/index.ts b/packages/contentstack-import/src/config/index.ts index 76b70e1121..b3f0b7f2b7 100644 --- a/packages/contentstack-import/src/config/index.ts +++ b/packages/contentstack-import/src/config/index.ts @@ -45,6 +45,7 @@ const config: DefaultConfig = { 'variant-entries', 'labels', 'webhooks', + 'publish', ], locales: { dirName: 'locales', @@ -206,6 +207,18 @@ const config: DefaultConfig = { apiBaseUrl: 'https://composable-studio-api.contentstack.com', apiVersion: 'v1', }, + publish: { + dirName: 'publish', + pendingAssetsFileName: 'pending-assets.json', + successAssetsFileName: 'success-assets.json', + failedAssetsFileName: 'failed-assets.json', + pendingEntriesFileName: 'pending-entries.json', + successEntriesFileName: 'success-entries.json', + failedEntriesFileName: 'failed-entries.json', + pendingVariantEntriesFileName: 'pending-variant-entries.json', + successVariantEntriesFileName: 'success-variant-entries.json', + failedVariantEntriesFileName: 'failed-variant-entries.json', + }, }, languagesCode: [ 'af-za', @@ -443,7 +456,7 @@ const config: DefaultConfig = { getEncryptionKeyMaxRetry: 3, // useBackedupDir: '', // backupConcurrency: 10, - onlyTSModules: ['taxonomies', 'personalize', 'variant-entries', 'stack'], + onlyTSModules: ['taxonomies', 'personalize', 'variant-entries', 'stack', 'publish'], auditConfig: { noLog: false, // Skip logs printing on terminal skipConfirm: true, // Skip confirmation if any diff --git a/packages/contentstack-import/src/import/modules/assets.ts b/packages/contentstack-import/src/import/modules/assets.ts index e78f97929c..ed240a2599 100644 --- a/packages/contentstack-import/src/import/modules/assets.ts +++ b/packages/contentstack-import/src/import/modules/assets.ts @@ -9,11 +9,11 @@ import { existsSync } from 'node:fs'; import includes from 'lodash/includes'; import { v4 as uuid } from 'uuid'; import { resolve as pResolve, join } from 'node:path'; -import { FsUtility, log, handleAndLogError } from '@contentstack/cli-utilities'; +import { FsUtility, log, handleAndLogError, sanitizePath } from '@contentstack/cli-utilities'; import config from '../../config'; import { ModuleClassParams } from '../../types'; -import { formatDate } from '../../utils'; +import { formatDate, fsUtil } from '../../utils'; import BaseClass, { ApiOptions } from './base-class'; export default class ImportAssets extends BaseClass { @@ -29,6 +29,7 @@ export default class ImportAssets extends BaseClass { private assetsUidMap: Record = {}; private assetsUrlMap: Record = {}; private assetsFolderMap: Record = {}; + private pendingPublishAssets: Array<{ oldUid: string; newUid: string }> = []; private rootFolder: { uid: string; name: string; parent_uid: string; created_at: string }; constructor({ importConfig, stackAPIClient }: ModuleClassParams) { @@ -54,11 +55,11 @@ export default class ImportAssets extends BaseClass { */ async start(): Promise { try { - // NOTE Step 1: Import folders and create uid mapping file + // NOTE Step 1: Import folders and create uid mapping file log.debug('Starting folder import process...', this.importConfig.context); await this.importFolders(); - // NOTE Step 2: Import versioned assets and create it mapping files (uid, url) + // NOTE Step 2: Import versioned assets and create it mapping files (uid, url) if (this.assetConfig.includeVersionedAssets) { const versionsPath = `${this.assetsPath}/versions`; if (existsSync(versionsPath)) { @@ -69,17 +70,15 @@ export default class ImportAssets extends BaseClass { } } - // NOTE Step 3: Import Assets and create it mapping files (uid, url) + // NOTE Step 3: Import Assets and create it mapping files (uid, url) log.debug('Starting assets import...', this.importConfig.context); await this.importAssets(); - // NOTE Step 4: Publish assets - if (!this.importConfig.skipAssetsPublish) { - log.debug('Starting assets publishing...', this.importConfig.context); - await this.publish(); - } + // NOTE Step 4: Save publish details for deferred publishing + log.debug('Saving asset publish details for deferred publishing', this.importConfig.context); + await this.savePublishDetails(); - log.success('Assets imported successfully!', this.importConfig.context); + log.success('Assets imported successfully', this.importConfig.context); } catch (error) { handleAndLogError(error, { ...this.importConfig.context }); } @@ -179,9 +178,18 @@ export default class ImportAssets extends BaseClass { log.debug(`Found ${indexerCount} asset chunks to process`, this.importConfig.context); - const onSuccess = ({ response = {}, apiData: { uid, url, title } = undefined }: any) => { + const onSuccess = ({ response = {}, apiData: { uid, url, title, publish_details } = undefined }: any) => { this.assetsUidMap[uid] = response.uid; this.assetsUrlMap[url] = response.url; + // Track assets with valid publish_details for deferred publishing + if (!isEmpty(publish_details)) { + const validPublishDetails = filter(publish_details, ({ environment }: any) => + this.environments?.hasOwnProperty(environment), + ); + if (validPublishDetails.length > 0) { + this.pendingPublishAssets.push({ oldUid: uid, newUid: response.uid }); + } + } log.debug(`Created asset: ${title} (Mapped ${uid} → ${response.uid})`, this.importConfig.context); log.success(`Created asset: '${title}'`, this.importConfig.context); }; @@ -387,6 +395,30 @@ export default class ImportAssets extends BaseClass { } } + /** + * @method savePublishDetails + * @description Saves pending asset UID mappings for deferred publishing + * @returns {Promise} Promise + */ + async savePublishDetails(): Promise { + if (this.pendingPublishAssets.length === 0) { + log.info('No assets with publish details to track', this.importConfig.context); + return; + } + + const publishConfig = this.importConfig.modules.publish; + const publishDirPath = join(sanitizePath(this.importConfig.backupDir), 'mapper', publishConfig.dirName); + const pendingFilePath = join(publishDirPath, publishConfig.pendingAssetsFileName); + + // Ensure the publish directory exists + await fsUtil.makeDirectory(publishDirPath); + + const assetCount = this.pendingPublishAssets.length; + log.debug(`Writing ${assetCount} pending asset UID mappings to file`, this.importConfig.context); + await fsUtil.writeFile(pendingFilePath, this.pendingPublishAssets); + log.success(`Saved ${assetCount} assets for deferred publishing`, this.importConfig.context); + } + /** * @method constructFolderImportOrder * @param {Record[]} folders object diff --git a/packages/contentstack-import/src/import/modules/base-class.ts b/packages/contentstack-import/src/import/modules/base-class.ts index a0eb770750..028ea39c7b 100644 --- a/packages/contentstack-import/src/import/modules/base-class.ts +++ b/packages/contentstack-import/src/import/modules/base-class.ts @@ -48,6 +48,7 @@ export type ApiModuleType = | 'create-entries' | 'update-entries' | 'publish-entries' + | 'publish-variant-entries' | 'delete-entries' | 'create-taxonomies' | 'create-terms' @@ -402,6 +403,8 @@ export default abstract class BaseClass { }) .then(onSuccess) .catch(onReject); + case 'publish-variant-entries': + return Promise.resolve(); case 'delete-entries': return this.stack .contentType(apiData.cTUid) diff --git a/packages/contentstack-import/src/import/modules/entries.ts b/packages/contentstack-import/src/import/modules/entries.ts index 9e319be8a6..e6ac82f7f9 100644 --- a/packages/contentstack-import/src/import/modules/entries.ts +++ b/packages/contentstack-import/src/import/modules/entries.ts @@ -57,6 +57,7 @@ export default class EntriesImport extends BaseClass { public rteCTs: any; public rteCTsWithRef: any; public entriesForVariant: Array<{ content_type: string; locale: string; entry_uid: string }> = []; + private pendingPublishEntries: Record> = {}; private composableStudioSuccessPath: string; private composableStudioExportPath: string; @@ -195,6 +196,20 @@ export default class EntriesImport extends BaseClass { this.locales.unshift(this.importConfig.master_locale); // adds master locale to the list log.debug(`Processing entries for ${values(this.locales).length} locales`, this.importConfig.context); + // Load environments early for publish details tracking during entry creation + this.envs = fileHelper.readFileSync(this.envPath) || {}; + if (Object.keys(this.envs).length === 0) { + log.warn( + 'No environments file found. Entries with publish details will not be tracked for deferred publishing', + this.importConfig.context, + ); + } else { + log.debug( + `Loaded ${Object.keys(this.envs).length} environments for publish details tracking`, + this.importConfig.context, + ); + } + //Create Entries log.info('Starting entry creation process...', this.importConfig.context); const entryRequestOptions = this.populateEntryCreatePayload(); @@ -273,32 +288,13 @@ export default class EntriesImport extends BaseClass { }); log.success('Entries imported successfully', this.importConfig.context); - // Publishing entries - if (!this.importConfig.skipEntriesPublish) { - log.info('Starting entry publishing process...', this.importConfig.context); - this.envs = fileHelper.readFileSync(this.envPath) || {}; - if (Object.keys(this.envs).length === 0) { - log.warn( - `No environments file found at ${this.envPath}. Entries will not be published.`, - this.importConfig.context, - ); - return; - } else { - log.debug(`Loaded ${Object.keys(this.envs).length} environments.`, this.importConfig.context); - } - - for (let entryRequestOption of entryRequestOptions) { - await this.publishEntries(entryRequestOption).catch((error) => { - handleAndLogError( - error, - { ...this.importConfig.context, cTUid: entryRequestOption.cTUid, locale: entryRequestOption.locale }, - `Error in publishing entries of ${entryRequestOption.cTUid} in locale ${entryRequestOption.locale}`, - ); - }); - } - log.success('All the entries have been published successfully', this.importConfig.context); + // Save publish details for deferred publishing (environments already loaded earlier) + log.debug('Saving entry publish details for deferred publishing', this.importConfig.context); + if (Object.keys(this.envs).length === 0) { + log.warn('No environments found. Entry publish details will not be saved', this.importConfig.context); } else { - log.info('Skipping entry publishing as per configuration...', this.importConfig.context); + await this.savePublishDetails(); + log.success('Entry publish details saved for deferred publishing', this.importConfig.context); } log.debug('Creating entry data for variant entries...', this.importConfig.context); @@ -478,6 +474,8 @@ export default class EntriesImport extends BaseClass { log.debug(`Found content type schema for ${cTUid}`, this.importConfig.context); const onSuccess = ({ response, apiData: entry, additionalInfo }: any) => { + const entriesWithPublishDetails: Set = additionalInfo.entriesWithPublishDetails; + if (additionalInfo[entry.uid]?.isLocalized) { let oldUid = additionalInfo[entry.uid].entryOldUid; this.entriesForVariant.push({ content_type: cTUid, entry_uid: oldUid, locale }); @@ -486,6 +484,13 @@ export default class EntriesImport extends BaseClass { this.importConfig.context, ); log.debug(`Mapped localized entry UID: ${entry.uid} → ${oldUid}`, this.importConfig.context); + + // Track for deferred publishing if has valid publish_details + // oldUid is the original entry UID from source data (set in serializeEntries) + if (entriesWithPublishDetails?.has(oldUid)) { + this.trackPendingPublishEntry(cTUid, locale, oldUid, this.entriesUidMapper[oldUid] || response.uid); + } + entry.uid = oldUid; entry.entryOldUid = oldUid; entry.sourceEntryFilePath = path.join(sanitizePath(basePath), sanitizePath(additionalInfo.entryFileName)); // stores source file path temporarily @@ -506,6 +511,12 @@ export default class EntriesImport extends BaseClass { log.debug(`Marked entry for auto-cleanup: ${response.uid} in master locale`, this.importConfig.context); } this.entriesUidMapper[entry.uid] = response.uid; + + // Track for deferred publishing if has valid publish_details + if (entriesWithPublishDetails?.has(entry.uid)) { + this.trackPendingPublishEntry(cTUid, locale, entry.uid, response.uid); + } + entry.sourceEntryFilePath = path.join(sanitizePath(basePath), sanitizePath(additionalInfo.entryFileName)); // stores source file path temporarily entry.entryOldUid = entry.uid; // stores old uid temporarily entriesCreateFileHelper.writeIntoFile({ [entry.uid]: entry } as any, { mapKeyVal: true }); @@ -552,6 +563,19 @@ export default class EntriesImport extends BaseClass { let apiContent = values(chunk as Record[]); log.debug(`Processing ${apiContent.length} entries in chunk ${index}`, this.importConfig.context); + // Identify entries with valid publish_details for deferred publishing + const entriesWithPublishDetails: Set = new Set(); + for (const entry of apiContent) { + if (!isEmpty(entry.publish_details)) { + const validPublishDetails = entry.publish_details.filter((pubDetail: any) => + this.envs?.hasOwnProperty(pubDetail.environment), + ); + if (validPublishDetails.length > 0) { + entriesWithPublishDetails.add(entry.uid); + } + } + } + await this.makeConcurrentCall({ apiContent, processName, @@ -563,7 +587,14 @@ export default class EntriesImport extends BaseClass { entity: 'create-entries', includeParamOnCompletion: true, serializeData: this.serializeEntries.bind(this), - additionalInfo: { contentType, locale, cTUid, entryFileName: indexer[index], isMasterLocale }, + additionalInfo: { + contentType, + locale, + cTUid, + entryFileName: indexer[index], + isMasterLocale, + entriesWithPublishDetails, + }, }, concurrencyLimit: this.importConcurrency, }).then(() => { @@ -1290,4 +1321,51 @@ export default class EntriesImport extends BaseClass { apiOptions.apiData = requestObject; return apiOptions; } + + /** + * @method trackPendingPublishEntry + * @description Tracks an entry for deferred publishing by storing its UID mapping + * @param {string} cTUid - Content type UID + * @param {string} locale - Locale code + * @param {string} oldUid - Original entry UID + * @param {string} newUid - New entry UID + */ + trackPendingPublishEntry(cTUid: string, locale: string, oldUid: string, newUid: string): void { + if (!this.pendingPublishEntries[cTUid]) { + this.pendingPublishEntries[cTUid] = []; + } + this.pendingPublishEntries[cTUid].push({ locale, oldUid, newUid }); + } + + /** + * @method savePublishDetails + * @description Saves pending entry UID mappings for deferred publishing + * @returns {Promise} Promise + */ + async savePublishDetails(): Promise { + const contentTypeCount = Object.keys(this.pendingPublishEntries).length; + if (contentTypeCount === 0) { + log.info('No entries with publish details to track', this.importConfig.context); + return; + } + + const publishConfig = this.importConfig.modules.publish; + const publishDirPath = path.join(sanitizePath(this.importConfig.backupDir), 'mapper', publishConfig.dirName); + const pendingFilePath = path.join(publishDirPath, publishConfig.pendingEntriesFileName); + + // Ensure the publish directory exists + await fsUtil.makeDirectory(publishDirPath); + + let entryCount = 0; + for (const list of Object.values(this.pendingPublishEntries)) { + entryCount += list.length; + } + + log.debug(`Writing ${entryCount} pending entry UID mappings to file`, this.importConfig.context); + await fsUtil.writeFile(pendingFilePath, this.pendingPublishEntries); + log.success( + `Saved ${entryCount} entries for deferred publishing across ${contentTypeCount} content types`, + this.importConfig.context, + ); + } } diff --git a/packages/contentstack-import/src/import/modules/publish.ts b/packages/contentstack-import/src/import/modules/publish.ts new file mode 100644 index 0000000000..a9bd0aeb0f --- /dev/null +++ b/packages/contentstack-import/src/import/modules/publish.ts @@ -0,0 +1,735 @@ +import map from 'lodash/map'; +import uniq from 'lodash/uniq'; +import values from 'lodash/values'; +import filter from 'lodash/filter'; +import isEmpty from 'lodash/isEmpty'; +import forEach from 'lodash/forEach'; +import indexOf from 'lodash/indexOf'; +import { join } from 'node:path'; +import { FsUtility, log, handleAndLogError, sanitizePath } from '@contentstack/cli-utilities'; + +import { ModuleClassParams, PublishConfig } from '../../types'; +import { fsUtil, fileHelper } from '../../utils'; +import BaseClass, { ApiOptions } from './base-class'; +import { VariantHttpClient } from '@contentstack/cli-variants'; + +export default class ImportPublish extends BaseClass { + private publishDirPath: string; + private assetsPath: string; + private entriesPath: string; + private pendingAssetsPath: string; + private pendingEntriesPath: string; + private successAssetsPath: string; + private failedAssetsPath: string; + private successEntriesPath: string; + private failedEntriesPath: string; + private pendingVariantEntriesPath: string; + private successVariantEntriesPath: string; + private failedVariantEntriesPath: string; + private environments: Record = {}; + private successAssets: Array<{ oldUid: string; newUid: string }> = []; + private failedAssets: Array<{ oldUid: string; newUid: string; error?: string }> = []; + private successEntries: Record> = {}; + private failedEntries: Record> = {}; + private successVariantEntries: Array<{ + content_type: string; + old_entry_uid: string; + entry_uid: string; + locale: string; + old_variant_uid: string; + variant_uid: string; + }> = []; + private failedVariantEntries: Array<{ + content_type: string; + old_entry_uid: string; + entry_uid: string; + locale: string; + old_variant_uid: string; + variant_uid: string; + error?: string; + }> = []; + public publishConfig: PublishConfig; + + constructor({ importConfig, stackAPIClient }: ModuleClassParams) { + super({ importConfig, stackAPIClient }); + this.importConfig.context.module = 'publish'; + this.publishConfig = importConfig.modules.publish; + + const backupDir = sanitizePath(this.importConfig.backupDir); + this.publishDirPath = join(backupDir, 'mapper', this.publishConfig.dirName); + this.assetsPath = join(backupDir, 'assets'); + this.entriesPath = join(backupDir, this.importConfig.modules.entries.dirName); + + // Pending files (UID mappings only) + this.pendingAssetsPath = join(this.publishDirPath, this.publishConfig.pendingAssetsFileName); + this.pendingEntriesPath = join(this.publishDirPath, this.publishConfig.pendingEntriesFileName); + + // Success/Failed tracking files + this.successAssetsPath = join(this.publishDirPath, this.publishConfig.successAssetsFileName); + this.failedAssetsPath = join(this.publishDirPath, this.publishConfig.failedAssetsFileName); + this.successEntriesPath = join(this.publishDirPath, this.publishConfig.successEntriesFileName); + this.failedEntriesPath = join(this.publishDirPath, this.publishConfig.failedEntriesFileName); + this.pendingVariantEntriesPath = join(this.publishDirPath, this.publishConfig.pendingVariantEntriesFileName); + this.successVariantEntriesPath = join(this.publishDirPath, this.publishConfig.successVariantEntriesFileName); + this.failedVariantEntriesPath = join(this.publishDirPath, this.publishConfig.failedVariantEntriesFileName); + + // Load environments + this.environments = + (fsUtil.readFile(join(backupDir, 'environments', 'environments.json')) as Record) || {}; + } + + /** + * @method start + * @description Main entry point for the publish module + * @returns {Promise} Promise + */ + async start(): Promise { + try { + log.debug('Checking for publish data directory', this.importConfig.context); + + // Check if publish directory exists + if (!fileHelper.fileExistsSync(this.publishDirPath)) { + log.info('No publish data found, skipping publish process', this.importConfig.context); + return; + } + + // Step 1: Publish assets first (if not skipped) + if (this.importConfig.skipAssetsPublish) { + log.info('Skipping asset publishing as per configuration', this.importConfig.context); + } else { + log.debug('Starting asset publishing', this.importConfig.context); + await this.publishAssets(); + } + + // Step 2: Publish entries after assets (if not skipped) + if (this.importConfig.skipEntriesPublish) { + log.info('Skipping entry publishing as per configuration', this.importConfig.context); + } else { + log.debug('Starting entry publishing', this.importConfig.context); + await this.publishEntries(); + } + + // Step 3: Publish variant entries after base entries + if (this.importConfig.skipEntriesPublish) { + log.info('Skipping variant entry publishing as per configuration', this.importConfig.context); + } else { + log.debug('Starting variant entry publishing', this.importConfig.context); + await this.publishVariantEntries(); + } + + log.success('Deferred publish process completed successfully', this.importConfig.context); + } catch (error) { + handleAndLogError(error, { ...this.importConfig.context }); + } + } + + /** + * @method publishAssets + * @description Publishes all assets from the pending assets metadata file + * @returns {Promise} Promise + */ + async publishAssets(): Promise { + log.debug('Checking for pending assets file', this.importConfig.context); + + if (!fileHelper.fileExistsSync(this.pendingAssetsPath)) { + log.info('No pending assets found', this.importConfig.context); + return; + } + + // Load pending assets (array of { oldUid, newUid }) + const pendingAssets = fsUtil.readFile(this.pendingAssetsPath) as Array<{ oldUid: string; newUid: string }>; + if (!Array.isArray(pendingAssets) || pendingAssets.length === 0) { + log.info('Pending assets file is empty', this.importConfig.context); + return; + } + + const assetCount = pendingAssets.length; + log.debug(`Found ${assetCount} assets to publish`, this.importConfig.context); + + // Build asset data by reading publish_details from source + const apiContent = await this.buildAssetPublishData(pendingAssets); + if (apiContent.length === 0) { + log.info('No assets with valid publish details found', this.importConfig.context); + return; + } + + log.debug(`Prepared ${apiContent.length} assets with valid publish details`, this.importConfig.context); + + const onSuccess = ({ apiData: { oldUid, newUid, environments, locales } }: any) => { + this.successAssets.push({ oldUid, newUid }); + log.success( + `Published asset '${newUid}' to environments '${environments?.join(',')}' and locales '${locales?.join(',')}'`, + this.importConfig.context, + ); + }; + + const onReject = ({ error, apiData: { oldUid, newUid, environments, locales } }: any) => { + this.failedAssets.push({ oldUid, newUid, error: error?.message || String(error) }); + handleAndLogError( + error, + { ...this.importConfig.context, oldUid, newUid }, + `Failed to publish asset '${newUid}' to environments '${environments?.join(',')}' and locales '${locales?.join(',')}'`, + ); + }; + + const serializeData = (apiOptions: ApiOptions) => { + const { apiData: asset } = apiOptions; + + if (!asset.publish_details || asset.publish_details.length === 0) { + apiOptions.entity = undefined; + return apiOptions; + } + + const publishDetails = filter(asset.publish_details, ({ environment }: any) => + this.environments?.hasOwnProperty(environment), + ); + + if (publishDetails.length === 0) { + log.debug(`Skipping asset '${asset.newUid}': no valid environments`, this.importConfig.context); + apiOptions.entity = undefined; + return apiOptions; + } + + const environments = uniq(map(publishDetails, ({ environment }: any) => this.environments[environment].name)); + const locales = uniq(map(publishDetails, 'locale')); + + if (environments.length === 0 || locales.length === 0) { + log.debug(`Skipping asset '${asset.newUid}': no valid environments or locales`, this.importConfig.context); + apiOptions.entity = undefined; + return apiOptions; + } + + asset.locales = locales; + asset.environments = environments; + apiOptions.apiData.publishDetails = { locales, environments }; + apiOptions.uid = asset.newUid; + + return apiOptions; + }; + + await this.makeConcurrentCall({ + apiContent, + processName: 'publish assets', + apiParams: { + serializeData, + reject: onReject, + resolve: onSuccess, + entity: 'publish-assets', + includeParamOnCompletion: true, + }, + concurrencyLimit: this.modulesConfig.assets.uploadAssetsConcurrency, + }); + + // Write success/fail tracking files + this.writeTrackingFiles('assets'); + + log.success(`Completed publishing ${this.successAssets.length} of ${assetCount} assets`, this.importConfig.context); + } + + /** + * @method buildAssetPublishData + * @description Builds asset publish data by reading publish_details from source files + * @param {Array<{ oldUid: string; newUid: string }>} pendingAssets - Pending assets (array of UID mappings) + * @returns {Promise>} Array of asset data with publish_details + */ + async buildAssetPublishData(pendingAssets: Array<{ oldUid: string; newUid: string }>): Promise> { + const pendingMap = new Map(pendingAssets.map((a) => [a.oldUid, a.newUid])); + const fs = new FsUtility({ basePath: this.assetsPath, indexFileName: 'assets.json' }); + const indexer = fs.indexFileContent; + const apiContent: Array = []; + + const indexKeys = Object.keys(indexer); + for (let i = 0; i < indexKeys.length; i++) { + const chunk = await fs.readChunkFiles.next().catch((error) => { + handleAndLogError(error, { ...this.importConfig.context }); + }); + + if (chunk) { + const assets = values(chunk as Record[]); + for (const asset of assets) { + const newUid = pendingMap.get(asset.uid); + if (newUid && !isEmpty(asset.publish_details)) { + apiContent.push({ + oldUid: asset.uid, + newUid, + title: asset.title, + publish_details: asset.publish_details, + }); + } + } + } + } + + return apiContent; + } + + /** + * @method publishEntries + * @description Publishes all entries from the pending entries metadata file + * @returns {Promise} Promise + */ + async publishEntries(): Promise { + log.debug('Checking for pending entries file', this.importConfig.context); + + if (!fileHelper.fileExistsSync(this.pendingEntriesPath)) { + log.info('No pending entries found', this.importConfig.context); + return; + } + + // Load pending entries (Record>) + const pendingEntries = fsUtil.readFile(this.pendingEntriesPath) as Record< + string, + Array<{ locale: string; oldUid: string; newUid: string }> + >; + if (!pendingEntries || typeof pendingEntries !== 'object' || Object.keys(pendingEntries).length === 0) { + log.info('Pending entries file is empty', this.importConfig.context); + return; + } + + const contentTypeCount = Object.keys(pendingEntries).length; + log.debug(`Found entries to publish across ${contentTypeCount} content types`, this.importConfig.context); + + // Process each content type and locale + for (const [cTUid, entriesList] of Object.entries(pendingEntries)) { + const byLocale = this.groupEntriesByLocale(entriesList); + for (const [locale, localeEntries] of byLocale) { + const uidMappings = Object.fromEntries(localeEntries.map((e) => [e.oldUid, e.newUid])); + const entryCount = localeEntries.length; + + if (entryCount === 0) { + log.debug(`No entries found for '${cTUid}' in locale '${locale}'`, this.importConfig.context); + continue; + } + + log.debug(`Publishing ${entryCount} entries for '${cTUid}' in locale '${locale}'`, this.importConfig.context); + + // Build entry data by reading publish_details from source + const apiContent = await this.buildEntryPublishData(cTUid, locale, uidMappings); + if (apiContent.length === 0) { + log.debug( + `No entries with valid publish details for '${cTUid}' in locale '${locale}'`, + this.importConfig.context, + ); + continue; + } + + const onSuccess = ({ apiData: { oldUid, entryUid, environments, locales } }: any) => { + if (!this.successEntries[cTUid]) this.successEntries[cTUid] = []; + this.successEntries[cTUid].push({ locale, oldUid, newUid: entryUid }); + log.success( + `Published entry '${entryUid}' of '${cTUid}' to environments '${environments?.join(',')}' and locales '${locales?.join(',')}'`, + this.importConfig.context, + ); + }; + + const onReject = ({ error, apiData: { oldUid, entryUid, environments, locales } }: any) => { + if (!this.failedEntries[cTUid]) this.failedEntries[cTUid] = []; + this.failedEntries[cTUid].push({ + locale, + oldUid, + newUid: entryUid, + error: error?.message || String(error), + }); + handleAndLogError( + error, + { ...this.importConfig.context, cTUid, locale }, + `Failed to publish entry '${entryUid}' of '${cTUid}' to environments '${environments?.join(',')}' and locales '${locales?.join(',')}'`, + ); + }; + + const serializeData = (apiOptions: ApiOptions) => { + const { apiData: entry } = apiOptions; + const requestObject: { + environments: Array; + locales: Array; + entryUid: string; + oldUid: string; + } = { + environments: [], + locales: [], + entryUid: entry.newUid, + oldUid: entry.oldUid, + }; + + if (entry.publish_details && entry.publish_details.length > 0) { + forEach(entry.publish_details, (pubObject: any) => { + if ( + this.environments.hasOwnProperty(pubObject.environment) && + indexOf(requestObject.environments, this.environments[pubObject.environment].name) === -1 + ) { + requestObject.environments.push(this.environments[pubObject.environment].name); + } + if (pubObject.locale && indexOf(requestObject.locales, pubObject.locale) === -1) { + requestObject.locales.push(pubObject.locale); + } + }); + } else { + apiOptions.apiData = null; + return apiOptions; + } + + if (requestObject.environments.length === 0 || requestObject.locales.length === 0) { + apiOptions.apiData = null; + return apiOptions; + } + + apiOptions.apiData = requestObject; + apiOptions.additionalInfo = { cTUid }; + return apiOptions; + }; + + await this.makeConcurrentCall({ + apiContent, + processName: 'publish entries', + apiParams: { + serializeData, + reject: onReject, + resolve: onSuccess, + entity: 'publish-entries', + includeParamOnCompletion: true, + additionalInfo: { cTUid }, + }, + concurrencyLimit: this.modulesConfig.entries.importConcurrency || this.importConfig.importConcurrency, + }); + + log.success(`Completed publishing entries for '${cTUid}' in locale '${locale}'`, this.importConfig.context); + } + } + + // Write success/fail tracking files + this.writeTrackingFiles('entries'); + + const totalSuccessCount = Object.values(this.successEntries).reduce((sum, list) => sum + list.length, 0); + log.success( + `Completed publishing ${totalSuccessCount} entries across ${contentTypeCount} content types`, + this.importConfig.context, + ); + } + + /** + * @method groupEntriesByLocale + * @description Groups entry details by locale for processing + * @param {Array<{ locale: string; oldUid: string; newUid: string }>} entries - Entry details for one content type + * @returns {Map>} Map of locale → entries list + */ + groupEntriesByLocale( + entries: Array<{ locale: string; oldUid: string; newUid: string }>, + ): Map> { + const byLocale = new Map>(); + for (const entry of entries) { + if (!byLocale.has(entry.locale)) { + byLocale.set(entry.locale, []); + } + byLocale.get(entry.locale)!.push(entry); + } + return byLocale; + } + + /** + * @method buildEntryPublishData + * @description Builds entry publish data by reading publish_details from source files + * @param {string} cTUid - Content type UID + * @param {string} locale - Locale code + * @param {Record} uidMappings - Entry UID mappings (oldUid → newUid) + * @returns {Promise>} Array of entry data with publish_details + */ + async buildEntryPublishData(cTUid: string, locale: string, uidMappings: Record): Promise> { + const basePath = join(this.entriesPath, cTUid, locale); + const fs = new FsUtility({ basePath, indexFileName: 'index.json' }); + const indexer = fs.indexFileContent; + const apiContent: Array = []; + + const indexKeys = Object.keys(indexer); + for (let i = 0; i < indexKeys.length; i++) { + const chunk = await fs.readChunkFiles.next().catch((error) => { + handleAndLogError(error, { ...this.importConfig.context, cTUid, locale }); + }); + + if (chunk) { + const entries = values(chunk as Record[]); + for (const entry of entries) { + const newUid = uidMappings[entry.uid]; + if (newUid && !isEmpty(entry.publish_details)) { + apiContent.push({ + oldUid: entry.uid, + newUid, + title: entry.title, + publish_details: entry.publish_details, + }); + } + } + } + } + + return apiContent; + } + + /** + * @method publishVariantEntries + * @description Publishes all variant entries from the pending file + * @returns {Promise} Promise + */ + async publishVariantEntries(): Promise { + log.debug('Checking for pending variant entries file', this.importConfig.context); + + if (!fileHelper.fileExistsSync(this.pendingVariantEntriesPath)) { + log.info('No pending variant entries found', this.importConfig.context); + return; + } + + const pendingVariantEntries = fsUtil.readFile(this.pendingVariantEntriesPath) as Array<{ + content_type: string; + old_entry_uid: string; + entry_uid: string; + locale: string; + old_variant_uid: string; + variant_uid: string; + }>; + + if (!Array.isArray(pendingVariantEntries) || pendingVariantEntries.length === 0) { + log.info('Pending variant entries file is empty', this.importConfig.context); + return; + } + + const variantCount = pendingVariantEntries.length; + log.debug(`Found ${variantCount} variant entries to publish`, this.importConfig.context); + + const apiContent = await this.buildVariantEntryPublishData(pendingVariantEntries); + if (apiContent.length === 0) { + log.info('No variant entries with valid publish details found', this.importConfig.context); + return; + } + + const onSuccess = ({ apiData }: any) => { + const { content_type, entry_uid, locale, variant_uid, old_entry_uid, old_variant_uid } = apiData; + this.successVariantEntries.push({ + content_type, + old_entry_uid, + entry_uid, + locale, + old_variant_uid, + variant_uid, + }); + log.success( + `Published variant '${variant_uid}' of entry '${entry_uid}' to environments '${apiData.environments?.join(',')}' and locales '${apiData.locales?.join(',')}'`, + this.importConfig.context, + ); + }; + + const onReject = ({ error, apiData }: any) => { + const { content_type, entry_uid, locale, variant_uid, old_entry_uid, old_variant_uid } = apiData; + this.failedVariantEntries.push({ + content_type, + old_entry_uid, + entry_uid, + locale, + old_variant_uid, + variant_uid, + error: error?.message || String(error), + }); + handleAndLogError( + error, + { ...this.importConfig.context, content_type, entry_uid, variant_uid }, + `Failed to publish variant '${variant_uid}' of entry '${entry_uid}'`, + ); + }; + + const backupDir = sanitizePath(this.importConfig.backupDir); + const projectMapperPath = join( + backupDir, + 'mapper', + this.importConfig.modules.personalize.dirName, + 'projects', + 'projects.json', + ); + let projectId = this.importConfig.modules.personalize.project_id; + if (!projectId && fileHelper.fileExistsSync(projectMapperPath)) { + const project = fsUtil.readFile(projectMapperPath) as { uid?: string }; + projectId = project?.uid; + } + if (!projectId) { + log.warn('Personalize project ID not found, skipping variant entry publishing', this.importConfig.context); + return; + } + + const variantClient = new VariantHttpClient({ + config: this.importConfig, + baseURL: this.importConfig.host, + headers: { + api_key: this.importConfig.apiKey, + branch: this.importConfig.branchName, + organization_uid: this.importConfig.org_uid, + 'X-Project-Uid': projectId, + }, + } as any); + await variantClient.init(); + + const publishVariantEntryHandler = async ({ element, apiParams }: { element: any; apiParams: ApiOptions }) => { + const { resolve, reject } = apiParams; + const publishReq = { + entry: { + environments: element.environments, + locales: element.locales, + variants: [{ uid: element.variant_uid, version: 1 }], + }, + locale: element.locale, + }; + const options = { + entry_uid: element.entry_uid, + content_type_uid: element.content_type, + }; + try { + await variantClient.publishVariantEntry(publishReq, options, { + resolve: (val: any) => resolve({ ...val, apiData: element }), + reject: (val: any) => reject({ ...val, apiData: element }), + variantUid: element.variant_uid, + log, + }); + } catch (error: any) { + reject({ error, apiData: element }); + } + }; + + await this.makeConcurrentCall( + { + apiContent, + processName: 'publish variant entries', + apiParams: { + reject: onReject, + resolve: onSuccess, + entity: 'publish-variant-entries', + includeParamOnCompletion: true, + }, + concurrencyLimit: this.modulesConfig.entries?.importConcurrency || this.importConfig.importConcurrency, + }, + publishVariantEntryHandler as any, + ); + + this.writeTrackingFiles('variant-entries'); + + log.success( + `Completed publishing ${this.successVariantEntries.length} of ${variantCount} variant entries`, + this.importConfig.context, + ); + } + + /** + * @method buildVariantEntryPublishData + * @description Builds variant entry publish data by reading publish_details from source files + * @param {Array} pendingVariantEntries - Pending variant entries + * @returns {Promise>} Array of variant data with publish_details + */ + async buildVariantEntryPublishData( + pendingVariantEntries: Array<{ + content_type: string; + old_entry_uid: string; + entry_uid: string; + locale: string; + old_variant_uid: string; + variant_uid: string; + }>, + ): Promise> { + const variantEntryConfig = this.importConfig.modules.variantEntry; + const apiContent: Array = []; + + for (const pending of pendingVariantEntries) { + const { content_type, entry_uid, locale, variant_uid, old_entry_uid, old_variant_uid } = pending; + + const variantBasePath = join(this.entriesPath, content_type, locale, variantEntryConfig.dirName, old_entry_uid); + + if (!fileHelper.fileExistsSync(join(variantBasePath, 'index.json'))) { + log.debug(`No variant data found for ${content_type}/${locale}/${old_entry_uid}`, this.importConfig.context); + continue; + } + + const fs = new FsUtility({ basePath: variantBasePath, createDirIfNotExist: false }); + let found = false; + + for (const _ in fs.indexFileContent) { + if (found) break; + try { + const chunk = await fs.readChunkFiles.next(); + if (chunk) { + const variants = values(chunk as Record[]); + for (const variant of variants) { + if (variant._variant?._uid === old_variant_uid && !isEmpty(variant.publish_details)) { + const publishDetails = filter(variant.publish_details, (pd: any) => + this.environments?.hasOwnProperty(pd.environment), + ); + if (publishDetails.length > 0) { + const environments = uniq(map(publishDetails, (pd: any) => this.environments[pd.environment].name)); + const locales = uniq(map(publishDetails, 'locale')); + if (environments.length > 0 && locales.length > 0) { + apiContent.push({ + content_type, + old_entry_uid, + entry_uid, + locale, + old_variant_uid, + variant_uid, + environments, + locales, + }); + found = true; + break; + } + } + } + } + } + } catch (error) { + log.debug( + `Error reading variant data for ${content_type}/${locale}/${old_entry_uid}`, + this.importConfig.context, + ); + } + } + } + + return apiContent; + } + + /** + * @method writeTrackingFiles + * @description Writes success and failed tracking files for assets or entries + * @param {string} type - 'assets' or 'entries' or 'variant-entries' + */ + writeTrackingFiles(type: 'assets' | 'entries' | 'variant-entries'): void { + if (type === 'assets') { + if (this.successAssets.length > 0) { + fsUtil.writeFile(this.successAssetsPath, this.successAssets); + log.debug(`Written ${this.successAssets.length} successful asset publish records`, this.importConfig.context); + } + if (this.failedAssets.length > 0) { + fsUtil.writeFile(this.failedAssetsPath, this.failedAssets); + log.debug(`Written ${this.failedAssets.length} failed asset publish records`, this.importConfig.context); + } + } else if (type === 'entries') { + const successCount = Object.values(this.successEntries).reduce((sum, list) => sum + list.length, 0); + const failedCount = Object.values(this.failedEntries).reduce((sum, list) => sum + list.length, 0); + if (successCount > 0) { + fsUtil.writeFile(this.successEntriesPath, this.successEntries); + log.debug(`Written ${successCount} successful entry publish records`, this.importConfig.context); + } + if (failedCount > 0) { + fsUtil.writeFile(this.failedEntriesPath, this.failedEntries); + log.debug(`Written ${failedCount} failed entry publish records`, this.importConfig.context); + } + } else if (type === 'variant-entries') { + if (this.successVariantEntries.length > 0) { + fsUtil.writeFile(this.successVariantEntriesPath, this.successVariantEntries); + log.debug( + `Written ${this.successVariantEntries.length} successful variant entry publish records`, + this.importConfig.context, + ); + } + if (this.failedVariantEntries.length > 0) { + fsUtil.writeFile(this.failedVariantEntriesPath, this.failedVariantEntries); + log.debug( + `Written ${this.failedVariantEntries.length} failed variant entry publish records`, + this.importConfig.context, + ); + } + } + } +} diff --git a/packages/contentstack-import/src/types/default-config.ts b/packages/contentstack-import/src/types/default-config.ts index aa4867d293..47541ebe68 100644 --- a/packages/contentstack-import/src/types/default-config.ts +++ b/packages/contentstack-import/src/types/default-config.ts @@ -164,6 +164,18 @@ export default interface DefaultConfig { apiBaseUrl: string; apiVersion: string; }; + publish: { + dirName: string; + pendingAssetsFileName: string; + successAssetsFileName: string; + failedAssetsFileName: string; + pendingEntriesFileName: string; + successEntriesFileName: string; + failedEntriesFileName: string; + pendingVariantEntriesFileName: string; + successVariantEntriesFileName: string; + failedVariantEntriesFileName: string; + }; }; languagesCode: string[]; apis: { diff --git a/packages/contentstack-import/src/types/index.ts b/packages/contentstack-import/src/types/index.ts index ee9062465c..f24d415556 100644 --- a/packages/contentstack-import/src/types/index.ts +++ b/packages/contentstack-import/src/types/index.ts @@ -51,7 +51,8 @@ export type Modules = | 'taxonomies' | 'personalize' | 'variant-entries' - | 'composable-studio'; + | 'composable-studio' + | 'publish'; export type ModuleClassParams = { stackAPIClient: ReturnType; @@ -113,6 +114,19 @@ export interface ComposableStudioConfig { apiVersion: string; } +export interface PublishConfig { + dirName: string; + pendingAssetsFileName: string; + successAssetsFileName: string; + failedAssetsFileName: string; + pendingEntriesFileName: string; + successEntriesFileName: string; + failedEntriesFileName: string; + pendingVariantEntriesFileName: string; + successVariantEntriesFileName: string; + failedVariantEntriesFileName: string; +} + export interface ComposableStudioProject { name: string; description: string; diff --git a/packages/contentstack-import/test/tsconfig.json b/packages/contentstack-import/test/tsconfig.json new file mode 100644 index 0000000000..01981bc44e --- /dev/null +++ b/packages/contentstack-import/test/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "noEmit": true, + "resolveJsonModule": true, + "esModuleInterop": true + } +} diff --git a/packages/contentstack-import/test/unit/import/modules/assets.test.ts b/packages/contentstack-import/test/unit/import/modules/assets.test.ts index bd48261fe7..cc22685daf 100644 --- a/packages/contentstack-import/test/unit/import/modules/assets.test.ts +++ b/packages/contentstack-import/test/unit/import/modules/assets.test.ts @@ -26,11 +26,11 @@ describe('ImportAssets', () => { asset: sinon.stub().returns({ create: sinon.stub().resolves({ uid: 'asset-123', url: 'https://example.com/asset.jpg' }), folder: sinon.stub().returns({ - create: sinon.stub().resolves({ uid: 'folder-123' }) + create: sinon.stub().resolves({ uid: 'folder-123' }), }), replace: sinon.stub().resolves({ uid: 'asset-123', url: 'https://example.com/asset.jpg' }), - publish: sinon.stub().resolves({ uid: 'asset-123' }) - }) + publish: sinon.stub().resolves({ uid: 'asset-123' }), + }), }; mockImportConfig = { @@ -49,11 +49,11 @@ describe('ImportAssets', () => { sessionId: 'session-123', apiKey: 'test', orgId: 'org-123', - authenticationMethod: 'Basic Auth' + authenticationMethod: 'Basic Auth', }, modules: { types: ['assets'], - assets: { + assets: { dirName: 'assets', validKeys: ['title', 'filename', 'content_type', 'parent_uid', 'description', 'tags'], folderValidKeys: ['name', 'parent_uid'], @@ -62,8 +62,20 @@ describe('ImportAssets', () => { uploadAssetsConcurrency: 5, includeVersionedAssets: true, importSameStructure: false, - displayExecutionTime: false - } + displayExecutionTime: false, + }, + publish: { + dirName: 'publish', + pendingAssetsFileName: 'pending-assets.json', + successAssetsFileName: 'success-assets.json', + failedAssetsFileName: 'failed-assets.json', + pendingEntriesFileName: 'pending-entries.json', + successEntriesFileName: 'success-entries.json', + failedEntriesFileName: 'failed-entries.json', + pendingVariantEntriesFileName: 'pending-variant-entries.json', + successVariantEntriesFileName: 'success-variant-entries.json', + failedVariantEntriesFileName: 'failed-variant-entries.json', + }, }, backupDir: '/test/backup', cliLogsPath: '/test/logs', @@ -76,13 +88,13 @@ describe('ImportAssets', () => { skipAudit: false, skipAssetsPublish: false, 'exclude-global-modules': false, - replaceExisting: false + replaceExisting: false, } as any; importAssets = new ImportAssets({ importConfig: mockImportConfig as any, stackAPIClient: mockStackClient, - moduleName: 'assets' + moduleName: 'assets', }); }); @@ -91,20 +103,20 @@ describe('ImportAssets', () => { }); describe('Constructor', () => { - it('should initialize with correct parameters', () => { - expect(importAssets).to.be.instanceOf(ImportAssets); - expect(importAssets['importConfig']).to.equal(mockImportConfig); - expect((importAssets as any)['client']).to.equal(mockStackClient); - }); + it('should initialize with correct parameters', () => { + expect(importAssets).to.be.instanceOf(ImportAssets); + expect(importAssets['importConfig']).to.equal(mockImportConfig); + expect((importAssets as any)['client']).to.equal(mockStackClient); + }); - it('should have assetConfig property', () => { - expect(importAssets.assetConfig).to.be.an('object'); - expect(importAssets.assetConfig).to.have.property('dirName', 'assets'); - }); + it('should have assetConfig property', () => { + expect(importAssets.assetConfig).to.be.an('object'); + expect(importAssets.assetConfig).to.have.property('dirName', 'assets'); + }); - it('should set context module to assets', () => { - expect(importAssets['importConfig'].context.module).to.equal('assets'); - }); + it('should set context module to assets', () => { + expect(importAssets['importConfig'].context.module).to.equal('assets'); + }); it('should initialize paths correctly', () => { expect(importAssets['assetsPath']).to.include('assets'); @@ -128,13 +140,13 @@ describe('ImportAssets', () => { describe('start() method', () => { let importFoldersStub: sinon.SinonStub; let importAssetsStub: sinon.SinonStub; - let publishStub: sinon.SinonStub; + let savePublishDetailsStub: sinon.SinonStub; let existsSyncStub: sinon.SinonStub; beforeEach(() => { importFoldersStub = sinon.stub(importAssets as any, 'importFolders').resolves(); importAssetsStub = sinon.stub(importAssets as any, 'importAssets').resolves(); - publishStub = sinon.stub(importAssets as any, 'publish').resolves(); + savePublishDetailsStub = sinon.stub(importAssets as any, 'savePublishDetails').resolves(); existsSyncStub = sinon.stub().returns(true); sinon.replace(require('node:fs'), 'existsSync', existsSyncStub); }); @@ -155,7 +167,7 @@ describe('ImportAssets', () => { expect(importAssetsStub.calledTwice).to.be.true; expect(importAssetsStub.firstCall.calledWith(true)).to.be.true; expect(importAssetsStub.secondCall.calledWith()).to.be.true; - expect(publishStub.calledOnce).to.be.true; + expect(savePublishDetailsStub.calledOnce).to.be.true; // Restore original value importAssets.assetConfig.includeVersionedAssets = originalValue; @@ -180,19 +192,11 @@ describe('ImportAssets', () => { expect(importAssetsStub.calledWith(true)).to.be.false; }); - it('should call publish after importing assets', async () => { + it('should call savePublishDetails after importing assets', async () => { await importAssets.start(); - expect(publishStub.calledOnce).to.be.true; - expect(publishStub.calledAfter(importAssetsStub)).to.be.true; - }); - - it('should skip publish when skipAssetsPublish is true', async () => { - mockImportConfig.skipAssetsPublish = true; - - await importAssets.start(); - - expect(publishStub.called).to.be.false; + expect(savePublishDetailsStub.calledOnce).to.be.true; + expect(savePublishDetailsStub.calledAfter(importAssetsStub)).to.be.true; }); it('should log success message on completion', async () => { @@ -230,7 +234,7 @@ describe('ImportAssets', () => { it('should import folders successfully', async () => { const mockFolders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: null, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; fsUtilityReadFileStub.returns(mockFolders); @@ -242,7 +246,7 @@ describe('ImportAssets', () => { it('should construct folder import order', async () => { const mockFolders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: null, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; fsUtilityReadFileStub.returns(mockFolders); const constructStub = sinon.stub(importAssets as any, 'constructFolderImportOrder').returns(mockFolders); @@ -254,17 +258,15 @@ describe('ImportAssets', () => { }); it('should write folder mappings after import', async () => { - const mockFolders = [ - { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' } - ]; + const mockFolders = [{ uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }]; fsUtilityReadFileStub.returns(mockFolders); - + // Simulate successful folder creation makeConcurrentCallStub.callsFake(async (options) => { const onSuccess = options.apiParams.resolve; onSuccess({ response: { uid: 'new-folder-1' }, - apiData: { uid: 'folder-1', name: 'Folder 1' } + apiData: { uid: 'folder-1', name: 'Folder 1' }, }); }); @@ -274,16 +276,14 @@ describe('ImportAssets', () => { }); it('should handle onSuccess callback correctly', async () => { - const mockFolders = [ - { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' } - ]; + const mockFolders = [{ uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }]; fsUtilityReadFileStub.returns(mockFolders); makeConcurrentCallStub.callsFake(async (options) => { const onSuccess = options.apiParams.resolve; onSuccess({ response: { uid: 'new-folder-1' }, - apiData: { uid: 'folder-1', name: 'Folder 1' } + apiData: { uid: 'folder-1', name: 'Folder 1' }, }); }); @@ -293,16 +293,14 @@ describe('ImportAssets', () => { }); it('should handle onReject callback correctly', async () => { - const mockFolders = [ - { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' } - ]; + const mockFolders = [{ uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }]; fsUtilityReadFileStub.returns(mockFolders); makeConcurrentCallStub.callsFake(async (options) => { const onReject = options.apiParams.reject; onReject({ error: new Error('Failed to create folder'), - apiData: { name: 'Folder 1' } + apiData: { name: 'Folder 1' }, }); }); @@ -314,7 +312,7 @@ describe('ImportAssets', () => { it('should map parent folder UIDs in serializeData', async () => { const mockFolders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: null, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; fsUtilityReadFileStub.returns(mockFolders); importAssets['assetsFolderMap'] = { 'folder-1': 'new-folder-1' }; @@ -323,7 +321,7 @@ describe('ImportAssets', () => { makeConcurrentCallStub.callsFake(async (options) => { const serializeData = options.apiParams.serializeData; capturedApiOptions = serializeData({ - apiData: { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1' } + apiData: { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1' }, }); }); @@ -339,19 +337,19 @@ describe('ImportAssets', () => { beforeEach(() => { makeConcurrentCallStub = sinon.stub(importAssets as any, 'makeConcurrentCall').resolves(); - + fsUtilityStub = sinon.stub(FsUtility.prototype, 'constructor' as any); Object.defineProperty(FsUtility.prototype, 'indexFileContent', { get: sinon.stub().returns({ '0': 'chunk-0' }), - configurable: true + configurable: true, }); Object.defineProperty(FsUtility.prototype, 'readChunkFiles', { get: sinon.stub().returns({ next: sinon.stub().resolves({ - 'asset-1': { uid: 'asset-1', title: 'Asset 1', url: 'url-1', filename: 'file1.jpg', _version: 1 } - }) + 'asset-1': { uid: 'asset-1', title: 'Asset 1', url: 'url-1', filename: 'file1.jpg', _version: 1 }, + }), }), - configurable: true + configurable: true, }); }); @@ -380,10 +378,10 @@ describe('ImportAssets', () => { get: sinon.stub().returns({ next: sinon.stub().resolves({ 'asset-1': { uid: 'asset-1', title: 'Asset 1', _version: 1 }, - 'asset-2': { uid: 'asset-2', title: 'Asset 2', _version: 2 } - }) + 'asset-2': { uid: 'asset-2', title: 'Asset 2', _version: 2 }, + }), }), - configurable: true + configurable: true, }); await (importAssets as any).importAssets(true); @@ -422,7 +420,7 @@ describe('ImportAssets', () => { const onSuccess = options.apiParams.resolve; onSuccess({ response: { uid: 'new-asset-1', url: 'new-url-1' }, - apiData: { uid: 'asset-1', url: 'url-1', title: 'Asset 1' } + apiData: { uid: 'asset-1', url: 'url-1', title: 'Asset 1' }, }); }); @@ -437,7 +435,7 @@ describe('ImportAssets', () => { const onReject = options.apiParams.reject; onReject({ error: new Error('Upload failed'), - apiData: { title: 'Asset 1' } + apiData: { title: 'Asset 1' }, }); }); @@ -449,9 +447,9 @@ describe('ImportAssets', () => { it('should handle chunk read errors', async () => { Object.defineProperty(FsUtility.prototype, 'readChunkFiles', { get: sinon.stub().returns({ - next: sinon.stub().rejects(new Error('Read failed')) + next: sinon.stub().rejects(new Error('Read failed')), }), - configurable: true + configurable: true, }); await (importAssets as any).importAssets(false); @@ -467,7 +465,7 @@ describe('ImportAssets', () => { const testImportAssets = new ImportAssets({ importConfig: mockImportConfig as any, stackAPIClient: mockStackClient, - moduleName: 'assets' + moduleName: 'assets', }); testImportAssets['assetConfig'].importSameStructure = false; testImportAssets['assetConfig'].includeVersionedAssets = false; @@ -475,7 +473,7 @@ describe('ImportAssets', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (testImportAssets as any).serializeAssets(apiOptions); @@ -486,7 +484,7 @@ describe('ImportAssets', () => { it('should set upload path for asset', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -500,7 +498,7 @@ describe('ImportAssets', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg', parent_uid: 'folder-1' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg', parent_uid: 'folder-1' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -515,7 +513,7 @@ describe('ImportAssets', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -531,7 +529,7 @@ describe('ImportAssets', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -549,7 +547,7 @@ describe('ImportAssets', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -566,11 +564,11 @@ describe('ImportAssets', () => { makeConcurrentCallStub = sinon.stub(importAssets as any, 'makeConcurrentCall').resolves(); importAssets['assetsUidMap'] = { 'asset-1': 'new-asset-1' }; importAssets['environments'] = { 'env-1': { name: 'production' } }; - + // Mock FsUtility for publish method Object.defineProperty(FsUtility.prototype, 'indexFileContent', { get: sinon.stub().returns({ '0': 'chunk-0' }), - configurable: true + configurable: true, }); Object.defineProperty(FsUtility.prototype, 'readChunkFiles', { get: sinon.stub().returns({ @@ -578,13 +576,11 @@ describe('ImportAssets', () => { { uid: 'asset-1', title: 'Asset 1', - publish_details: [ - { environment: 'env-1', locale: 'en-us' } - ] - } - ]) + publish_details: [{ environment: 'env-1', locale: 'en-us' }], + }, + ]), }), - configurable: true + configurable: true, }); }); @@ -605,11 +601,9 @@ describe('ImportAssets', () => { it('should skip assets without publish_details', async () => { Object.defineProperty(FsUtility.prototype, 'readChunkFiles', { get: sinon.stub().returns({ - next: sinon.stub().resolves([ - { uid: 'asset-1', title: 'Asset 1', publish_details: [] } - ]) + next: sinon.stub().resolves([{ uid: 'asset-1', title: 'Asset 1', publish_details: [] }]), }), - configurable: true + configurable: true, }); await (importAssets as any).publish(); @@ -627,7 +621,7 @@ describe('ImportAssets', () => { makeConcurrentCallStub.callsFake(async (options) => { const onSuccess = options.apiParams.resolve; onSuccess({ - apiData: { uid: 'asset-1', title: 'Asset 1' } + apiData: { uid: 'asset-1', title: 'Asset 1' }, }); }); @@ -641,7 +635,7 @@ describe('ImportAssets', () => { const onReject = options.apiParams.reject; onReject({ error: new Error('Publish failed'), - apiData: { uid: 'asset-1', title: 'Asset 1' } + apiData: { uid: 'asset-1', title: 'Asset 1' }, }); }); @@ -660,11 +654,11 @@ describe('ImportAssets', () => { uid: 'asset-1', publish_details: [ { environment: 'env-1', locale: 'en-us' }, - { environment: 'env-invalid', locale: 'en-us' } - ] - } + { environment: 'env-invalid', locale: 'en-us' }, + ], + }, }); - + expect(result.apiData.environments).to.deep.equal(['production']); expect(result.apiData.locales).to.deep.equal(['en-us']); }); @@ -678,12 +672,10 @@ describe('ImportAssets', () => { const result = serializeData({ apiData: { uid: 'asset-1', - publish_details: [ - { environment: 'env-invalid', locale: 'en-us' } - ] - } + publish_details: [{ environment: 'env-invalid', locale: 'en-us' }], + }, }); - + expect(result.entity).to.be.undefined; }); @@ -698,10 +690,10 @@ describe('ImportAssets', () => { const result = serializeData({ apiData: { uid: 'asset-unknown', - publish_details: [{ environment: 'env-1', locale: 'en-us' }] - } + publish_details: [{ environment: 'env-1', locale: 'en-us' }], + }, }); - + expect(result.entity).to.be.undefined; }); @@ -716,10 +708,10 @@ describe('ImportAssets', () => { const result = serializeData({ apiData: { uid: 'asset-1', - publish_details: [{ environment: 'env-1', locale: 'en-us' }] - } + publish_details: [{ environment: 'env-1', locale: 'en-us' }], + }, }); - + expect(result.uid).to.equal('mapped-asset-1'); }); @@ -735,11 +727,11 @@ describe('ImportAssets', () => { publish_details: [ { environment: 'env-1', locale: 'en-us' }, { environment: 'env-1', locale: 'en-us' }, - { environment: 'env-1', locale: 'fr-fr' } - ] - } + { environment: 'env-1', locale: 'fr-fr' }, + ], + }, }); - + expect(result.apiData.locales).to.have.lengthOf(2); expect(result.apiData.locales).to.include.members(['en-us', 'fr-fr']); }); @@ -752,7 +744,7 @@ describe('ImportAssets', () => { it('should order folders with null parent_uid first', () => { const folders = [ { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, - { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' } + { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -765,7 +757,7 @@ describe('ImportAssets', () => { const folders = [ { uid: 'folder-3', name: 'Folder 3', parent_uid: 'folder-2', created_at: '2023-01-03' }, { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -778,7 +770,7 @@ describe('ImportAssets', () => { it('should handle multiple root folders', () => { const folders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: null as any, created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: null as any, created_at: '2023-01-02' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -793,7 +785,7 @@ describe('ImportAssets', () => { { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }, { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, { uid: 'folder-3', name: 'Folder 3', parent_uid: 'folder-2', created_at: '2023-01-03' }, - { uid: 'folder-4', name: 'Folder 4', parent_uid: 'folder-3', created_at: '2023-01-04' } + { uid: 'folder-4', name: 'Folder 4', parent_uid: 'folder-3', created_at: '2023-01-04' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -804,9 +796,7 @@ describe('ImportAssets', () => { it('should add root folder when replaceExisting is true', () => { mockImportConfig.replaceExisting = true; - const folders = [ - { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' } - ]; + const folders = [{ uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -817,9 +807,7 @@ describe('ImportAssets', () => { it('should update root folder parent_uid when replaceExisting', () => { mockImportConfig.replaceExisting = true; - const folders = [ - { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' } - ]; + const folders = [{ uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -831,7 +819,7 @@ describe('ImportAssets', () => { mockImportConfig.replaceExisting = true; const folders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -853,7 +841,7 @@ describe('ImportAssets', () => { it('should maintain created_at timestamps', () => { const folders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: null as any, created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -867,14 +855,14 @@ describe('ImportAssets', () => { it('should complete full asset import flow', async () => { const importFoldersStub = sinon.stub(importAssets as any, 'importFolders').resolves(); const importAssetsStub = sinon.stub(importAssets as any, 'importAssets').resolves(); - const publishStub = sinon.stub(importAssets as any, 'publish').resolves(); + const savePublishDetailsStub = sinon.stub(importAssets as any, 'savePublishDetails').resolves(); await importAssets.start(); expect(importFoldersStub.calledOnce).to.be.true; expect(importAssetsStub.called).to.be.true; - expect(publishStub.calledOnce).to.be.true; - expect(publishStub.calledAfter(importAssetsStub)).to.be.true; + expect(savePublishDetailsStub.calledOnce).to.be.true; + expect(savePublishDetailsStub.calledAfter(importAssetsStub)).to.be.true; }); it('should handle complete versioned assets flow', async () => { @@ -886,31 +874,17 @@ describe('ImportAssets', () => { const testImportFoldersStub = sinon.stub(importAssets as any, 'importFolders').resolves(); const testImportAssetsStub = sinon.stub(importAssets as any, 'importAssets').resolves(); - const testPublishStub = sinon.stub(importAssets as any, 'publish').resolves(); + const testSavePublishDetailsStub = sinon.stub(importAssets as any, 'savePublishDetails').resolves(); await importAssets.start(); expect(testImportFoldersStub.calledOnce).to.be.true; expect(testImportAssetsStub.calledTwice).to.be.true; - expect(testPublishStub.calledOnce).to.be.true; + expect(testSavePublishDetailsStub.calledOnce).to.be.true; // Restore original value importAssets.assetConfig.includeVersionedAssets = originalValue; }); - - it('should skip publish when skipAssetsPublish is true', async () => { - mockImportConfig.skipAssetsPublish = true; - - const importFoldersStub = sinon.stub(importAssets as any, 'importFolders').resolves(); - const importAssetsStub = sinon.stub(importAssets as any, 'importAssets').resolves(); - const publishStub = sinon.stub(importAssets as any, 'publish').resolves(); - - await importAssets.start(); - - expect(importFoldersStub.calledOnce).to.be.true; - expect(importAssetsStub.called).to.be.true; - expect(publishStub.called).to.be.false; - }); }); describe('Edge Cases and Error Handling', () => { @@ -926,10 +900,10 @@ describe('ImportAssets', () => { it('should handle empty environments object', () => { importAssets['environments'] = {}; - + const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -939,7 +913,7 @@ describe('ImportAssets', () => { it('should handle assets without parent_uid', () => { const apiOptions = { entity: 'create-assets' as const, - apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' } + apiData: { uid: 'asset-1', title: 'Asset 1', filename: 'file1.jpg' }, }; const result = (importAssets as any).serializeAssets(apiOptions); @@ -948,9 +922,7 @@ describe('ImportAssets', () => { }); it('should handle malformed folder structure', () => { - const folders = [ - { uid: 'folder-1', name: 'Folder 1', parent_uid: 'non-existent', created_at: '2023-01-01' } - ]; + const folders = [{ uid: 'folder-1', name: 'Folder 1', parent_uid: 'non-existent', created_at: '2023-01-01' }]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -961,7 +933,7 @@ describe('ImportAssets', () => { it('should handle circular folder references', () => { const folders = [ { uid: 'folder-1', name: 'Folder 1', parent_uid: 'folder-2', created_at: '2023-01-01' }, - { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' } + { uid: 'folder-2', name: 'Folder 2', parent_uid: 'folder-1', created_at: '2023-01-02' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -973,21 +945,21 @@ describe('ImportAssets', () => { it('should handle assets with empty publish_details array', async () => { Object.defineProperty(FsUtility.prototype, 'indexFileContent', { get: sinon.stub().returns({ '0': 'chunk-0' }), - configurable: true + configurable: true, }); Object.defineProperty(FsUtility.prototype, 'readChunkFiles', { get: sinon.stub().returns({ - next: sinon.stub().resolves([ - { uid: 'asset-1', title: 'Asset 1', publish_details: [] } - ]) + next: sinon.stub().resolves([{ uid: 'asset-1', title: 'Asset 1', publish_details: [] }]), }), - configurable: true + configurable: true, }); - const makeConcurrentStub = sinon.stub(importAssets as any, 'makeConcurrentCall').callsFake(async (options: any) => { - // When publish_details is empty, the asset should be filtered out - expect(options.apiContent).to.have.lengthOf(0); - }); + const makeConcurrentStub = sinon + .stub(importAssets as any, 'makeConcurrentCall') + .callsFake(async (options: any) => { + // When publish_details is empty, the asset should be filtered out + expect(options.apiContent).to.have.lengthOf(0); + }); await (importAssets as any).publish(); expect(makeConcurrentStub.called).to.be.true; @@ -995,7 +967,7 @@ describe('ImportAssets', () => { it('should handle special characters in folder names', () => { const folders = [ - { uid: 'folder-1', name: 'Folder & Special "Chars"', parent_uid: null as any, created_at: '2023-01-01' } + { uid: 'folder-1', name: 'Folder & Special "Chars"', parent_uid: null as any, created_at: '2023-01-01' }, ]; const result = (importAssets as any).constructFolderImportOrder(folders); @@ -1010,7 +982,7 @@ describe('ImportAssets', () => { uid: `folder-${i}`, name: `Folder ${i}`, parent_uid: i === 0 ? null : `folder-${i - 1}`, - created_at: `2023-01-${String(i + 1).padStart(2, '0')}` + created_at: `2023-01-${String(i + 1).padStart(2, '0')}`, }); } @@ -1020,4 +992,30 @@ describe('ImportAssets', () => { expect(result[99].parent_uid).to.equal('folder-98'); }); }); + + describe('savePublishDetails() method', () => { + it('should skip when no pending assets', async () => { + importAssets['pendingPublishAssets'] = []; + fsUtilityWriteFileStub.resetHistory(); + + await (importAssets as any).savePublishDetails(); + + // Should not write file when no pending assets + expect(fsUtilityWriteFileStub.called).to.be.false; + }); + + it('should log correct count of pending assets', () => { + importAssets['pendingPublishAssets'] = [ + { oldUid: 'old-asset-1', newUid: 'new-asset-1' }, + { oldUid: 'old-asset-2', newUid: 'new-asset-2' }, + ]; + + const assetCount = importAssets['pendingPublishAssets'].length; + expect(assetCount).to.equal(2); + }); + + it('should have correct publish config file name', () => { + expect(importAssets['importConfig'].modules.publish.pendingAssetsFileName).to.equal('pending-assets.json'); + }); + }); }); diff --git a/packages/contentstack-import/test/unit/import/modules/entries.test.ts b/packages/contentstack-import/test/unit/import/modules/entries.test.ts index eaaa2ba6f1..f4dcebc91a 100644 --- a/packages/contentstack-import/test/unit/import/modules/entries.test.ts +++ b/packages/contentstack-import/test/unit/import/modules/entries.test.ts @@ -93,6 +93,18 @@ describe('EntriesImport', () => { dirName: 'composable_studio', fileName: 'composable_studio.json', }, + publish: { + dirName: 'publish', + pendingAssetsFileName: 'pending-assets.json', + successAssetsFileName: 'success-assets.json', + failedAssetsFileName: 'failed-assets.json', + pendingEntriesFileName: 'pending-entries.json', + successEntriesFileName: 'success-entries.json', + failedEntriesFileName: 'failed-entries.json', + pendingVariantEntriesFileName: 'pending-variant-entries.json', + successVariantEntriesFileName: 'success-variant-entries.json', + failedVariantEntriesFileName: 'failed-variant-entries.json', + }, }, backupDir: '/test/backup', cliLogsPath: '/test/logs', @@ -2597,7 +2609,7 @@ describe('EntriesImport', () => { const updateEntriesWithReferencesStub = sinon.stub(entriesImport, 'updateEntriesWithReferences').resolves(); const enableMandatoryCTReferencesStub = sinon.stub(entriesImport, 'enableMandatoryCTReferences').resolves(); const updateFieldRulesStub = sinon.stub(entriesImport, 'updateFieldRules').resolves(); - const publishEntriesStub = sinon.stub(entriesImport, 'publishEntries').resolves(); + const savePublishDetailsStub = sinon.stub(entriesImport, 'savePublishDetails').resolves(); const createEntryDataForVariantEntryStub = sinon.stub(entriesImport, 'createEntryDataForVariantEntry').returns(); await entriesImport.start(); @@ -2608,7 +2620,7 @@ describe('EntriesImport', () => { expect(updateEntriesWithReferencesStub.called).to.be.true; expect(enableMandatoryCTReferencesStub.called).to.be.true; expect(updateFieldRulesStub.called).to.be.true; - expect(publishEntriesStub.calledTwice).to.be.true; + expect(savePublishDetailsStub.calledOnce).to.be.true; expect(createEntryDataForVariantEntryStub.called).to.be.true; }); @@ -2827,13 +2839,13 @@ describe('EntriesImport', () => { const updateEntriesWithReferencesStub = sinon.stub(entriesImport, 'updateEntriesWithReferences').resolves(); const enableMandatoryCTReferencesStub = sinon.stub(entriesImport, 'enableMandatoryCTReferences').resolves(); const updateFieldRulesStub = sinon.stub(entriesImport, 'updateFieldRules').resolves(); - const publishEntriesStub = sinon.stub(entriesImport, 'publishEntries').resolves(); + const savePublishDetailsStub = sinon.stub(entriesImport, 'savePublishDetails').resolves(); const createEntryDataForVariantEntryStub = sinon.stub(entriesImport, 'createEntryDataForVariantEntry').returns(); await entriesImport.start(); - // Verify publishEntries was NOT called - expect(publishEntriesStub.called).to.be.false; + // savePublishDetails is NOT called when environments are empty (skipEntriesPublish is handled in publish module) + expect(savePublishDetailsStub.called).to.be.false; }); it('should handle no environments found for publishing', async () => { @@ -2880,13 +2892,13 @@ describe('EntriesImport', () => { const updateEntriesWithReferencesStub = sinon.stub(entriesImport, 'updateEntriesWithReferences').resolves(); const enableMandatoryCTReferencesStub = sinon.stub(entriesImport, 'enableMandatoryCTReferences').resolves(); const updateFieldRulesStub = sinon.stub(entriesImport, 'updateFieldRules').resolves(); - const publishEntriesStub = sinon.stub(entriesImport, 'publishEntries').resolves(); + const savePublishDetailsStub = sinon.stub(entriesImport, 'savePublishDetails').resolves(); const createEntryDataForVariantEntryStub = sinon.stub(entriesImport, 'createEntryDataForVariantEntry').returns(); await entriesImport.start(); - // Verify publishEntries was NOT called due to empty environments - expect(publishEntriesStub.called).to.be.false; + // savePublishDetails is NOT called due to empty environments + expect(savePublishDetailsStub.called).to.be.false; }); it('should handle errors in replaceEntries', async () => { @@ -3159,7 +3171,7 @@ describe('EntriesImport', () => { expect(updateFieldRulesStub.called).to.be.true; }); - it('should handle errors in publishEntries', async () => { + it('should handle errors in savePublishDetails', async () => { // Mock file system operations const mockFsUtil = { readFile: sinon @@ -3203,13 +3215,13 @@ describe('EntriesImport', () => { const updateEntriesWithReferencesStub = sinon.stub(entriesImport, 'updateEntriesWithReferences').resolves(); const enableMandatoryCTReferencesStub = sinon.stub(entriesImport, 'enableMandatoryCTReferences').resolves(); const updateFieldRulesStub = sinon.stub(entriesImport, 'updateFieldRules').resolves(); - const publishEntriesStub = sinon.stub(entriesImport, 'publishEntries').rejects(new Error('Publish failed')); + const savePublishDetailsStub = sinon.stub(entriesImport, 'savePublishDetails').rejects(new Error('Save failed')); const createEntryDataForVariantEntryStub = sinon.stub(entriesImport, 'createEntryDataForVariantEntry').returns(); await entriesImport.start(); - // Verify publishEntries was called and error was handled - expect(publishEntriesStub.called).to.be.true; + // Verify savePublishDetails was called and error was handled + expect(savePublishDetailsStub.called).to.be.true; }); it('should handle general errors in try-catch', async () => { @@ -3715,4 +3727,163 @@ describe('EntriesImport', () => { }); }); }); + + describe('savePublishDetails() method', () => { + it('should skip when no pending entries', async () => { + entriesImport['pendingPublishEntries'] = {}; + + await (entriesImport as any).savePublishDetails(); + + // Should not write file when no pending entries + expect(fsUtilityWriteFileStub.called).to.be.false; + }); + + it('should create publish directory if not exists', async () => { + entriesImport['pendingPublishEntries'] = { + profiles: [{ locale: 'en-us', oldUid: 'old-entry-1', newUid: 'new-entry-1' }], + }; + + await (entriesImport as any).savePublishDetails(); + + expect(fsUtilityMakeDirectoryStub.called).to.be.true; + }); + + it('should organize by content type with array of entry details', async () => { + entriesImport['pendingPublishEntries'] = { + profiles: [ + { locale: 'en-us', oldUid: 'old-entry-1', newUid: 'new-entry-1' }, + { locale: 'fr-fr', oldUid: 'old-entry-2', newUid: 'new-entry-2' }, + ], + articles: [{ locale: 'en-us', oldUid: 'old-entry-3', newUid: 'new-entry-3' }], + }; + + await (entriesImport as any).savePublishDetails(); + + expect(fsUtilityMakeDirectoryStub.called).to.be.true; + expect(fsUtilityWriteFileStub.called).to.be.true; + + const writeCall = fsUtilityWriteFileStub.getCall(fsUtilityWriteFileStub.callCount - 1); + const writtenData = writeCall.args[1]; + expect(writtenData).to.be.an('object'); + expect(writtenData).to.have.property('profiles'); + expect(writtenData.profiles).to.be.an('array'); + expect(writtenData.profiles).to.have.lengthOf(2); + expect(writtenData.profiles[0]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-entry-1', + newUid: 'new-entry-1', + }); + expect(writtenData.profiles[1]).to.deep.equal({ + locale: 'fr-fr', + oldUid: 'old-entry-2', + newUid: 'new-entry-2', + }); + expect(writtenData).to.have.property('articles'); + expect(writtenData.articles).to.have.lengthOf(1); + expect(writtenData.articles[0]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-entry-3', + newUid: 'new-entry-3', + }); + }); + + it('should write pending entries file with UID mappings', async () => { + entriesImport['pendingPublishEntries'] = { + profiles: [ + { locale: 'en-us', oldUid: 'old-entry-1', newUid: 'new-entry-1' }, + { locale: 'en-us', oldUid: 'old-entry-2', newUid: 'new-entry-2' }, + ], + }; + + await (entriesImport as any).savePublishDetails(); + + expect(fsUtilityWriteFileStub.called).to.be.true; + + const writeCall = fsUtilityWriteFileStub.getCall(fsUtilityWriteFileStub.callCount - 1); + const writtenData = writeCall.args[1]; + expect(writtenData).to.have.property('profiles'); + expect(writtenData.profiles).to.have.lengthOf(2); + expect(writtenData.profiles[0]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-entry-1', + newUid: 'new-entry-1', + }); + expect(writtenData.profiles[1]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-entry-2', + newUid: 'new-entry-2', + }); + }); + + it('should write to correct file path', async () => { + entriesImport['pendingPublishEntries'] = { + profiles: [{ locale: 'en-us', oldUid: 'old-entry-1', newUid: 'new-entry-1' }], + }; + + await (entriesImport as any).savePublishDetails(); + + const writeCall = fsUtilityWriteFileStub.getCall(fsUtilityWriteFileStub.callCount - 1); + const filePath = writeCall.args[0]; + expect(filePath).to.include('pending-entries.json'); + }); + }); + + describe('trackPendingPublishEntry() method', () => { + beforeEach(() => { + entriesImport['pendingPublishEntries'] = {}; + }); + + it('should push entry to content type array', () => { + (entriesImport as any).trackPendingPublishEntry('profiles', 'en-us', 'old-1', 'new-1'); + + expect(entriesImport['pendingPublishEntries']).to.have.property('profiles'); + expect(entriesImport['pendingPublishEntries'].profiles).to.be.an('array'); + expect(entriesImport['pendingPublishEntries'].profiles).to.have.lengthOf(1); + expect(entriesImport['pendingPublishEntries'].profiles[0]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-1', + newUid: 'new-1', + }); + }); + + it('should add to existing content type array', () => { + entriesImport['pendingPublishEntries'] = { + profiles: [{ locale: 'en-us', oldUid: 'old-1', newUid: 'new-1' }], + }; + + (entriesImport as any).trackPendingPublishEntry('profiles', 'fr-fr', 'old-2', 'new-2'); + + expect(entriesImport['pendingPublishEntries'].profiles).to.have.lengthOf(2); + expect(entriesImport['pendingPublishEntries'].profiles[0]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-1', + newUid: 'new-1', + }); + expect(entriesImport['pendingPublishEntries'].profiles[1]).to.deep.equal({ + locale: 'fr-fr', + oldUid: 'old-2', + newUid: 'new-2', + }); + }); + + it('should add to same locale in content type array', () => { + entriesImport['pendingPublishEntries'] = { + profiles: [{ locale: 'en-us', oldUid: 'old-1', newUid: 'new-1' }], + }; + + (entriesImport as any).trackPendingPublishEntry('profiles', 'en-us', 'old-2', 'new-2'); + + expect(entriesImport['pendingPublishEntries'].profiles).to.have.lengthOf(2); + expect(entriesImport['pendingPublishEntries'].profiles[0]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-1', + newUid: 'new-1', + }); + expect(entriesImport['pendingPublishEntries'].profiles[1]).to.deep.equal({ + locale: 'en-us', + oldUid: 'old-2', + newUid: 'new-2', + }); + }); + }); }); 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 fc3631e810..44d78edb99 100644 --- a/packages/contentstack-import/test/unit/import/modules/locales.test.ts +++ b/packages/contentstack-import/test/unit/import/modules/locales.test.ts @@ -136,6 +136,18 @@ describe('ImportLocales', () => { apiConcurrency: 1, query: { locale: 'en-us' }, }, + publish: { + dirName: 'publish', + pendingAssetsFileName: 'pending-assets.json', + successAssetsFileName: 'success-assets.json', + failedAssetsFileName: 'failed-assets.json', + pendingEntriesFileName: 'pending-entries.json', + successEntriesFileName: 'success-entries.json', + failedEntriesFileName: 'failed-entries.json', + pendingVariantEntriesFileName: 'pending-variant-entries.json', + successVariantEntriesFileName: 'success-variant-entries.json', + failedVariantEntriesFileName: 'failed-variant-entries.json', + }, }, branches: [{ uid: 'main', source: 'main' }], isAuthenticated: true, diff --git a/packages/contentstack-import/test/unit/import/modules/publish.test.ts b/packages/contentstack-import/test/unit/import/modules/publish.test.ts new file mode 100644 index 0000000000..e778b80869 --- /dev/null +++ b/packages/contentstack-import/test/unit/import/modules/publish.test.ts @@ -0,0 +1,495 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import ImportPublish from '../../../../src/import/modules/publish'; +import { ImportConfig } from '../../../../src/types'; +import { fsUtil, fileHelper } from '../../../../src/utils'; + +describe('ImportPublish', () => { + let importPublish: ImportPublish; + let mockStackClient: any; + let mockImportConfig: ImportConfig; + let fileExistsSyncStub: sinon.SinonStub; + let fsUtilReadFileStub: sinon.SinonStub; + let fsUtilWriteFileStub: sinon.SinonStub; + + beforeEach(() => { + fileExistsSyncStub = sinon.stub(fileHelper, 'fileExistsSync').returns(true); + fsUtilReadFileStub = sinon.stub(fsUtil, 'readFile').returns({}); + fsUtilWriteFileStub = sinon.stub(fsUtil, 'writeFile').returns(); + + mockStackClient = { + asset: sinon.stub().returns({ + publish: sinon.stub().resolves({ uid: 'asset-123' }), + }), + contentType: sinon.stub().returns({ + entry: sinon.stub().returns({ + publish: sinon.stub().resolves({ uid: 'entry-123' }), + }), + }), + }; + + mockImportConfig = { + apiKey: 'test', + contentDir: '/test/content', + data: '/test/content', + contentVersion: 1, + region: 'us', + master_locale: { code: 'en-us' }, + masterLocale: { code: 'en-us' }, + context: { + command: 'cm:stacks:import', + module: 'publish', + userId: 'user-123', + email: 'test@example.com', + sessionId: 'session-123', + apiKey: 'test', + orgId: 'org-123', + authenticationMethod: 'Basic Auth', + }, + modules: { + types: ['publish'], + apiConcurrency: 5, + assets: { + dirName: 'assets', + validKeys: ['title', 'filename'], + folderValidKeys: ['name', 'parent_uid'], + apiConcurrency: 5, + importFoldersConcurrency: 3, + uploadAssetsConcurrency: 5, + includeVersionedAssets: false, + importSameStructure: false, + displayExecutionTime: false, + }, + entries: { + dirName: 'entries', + importConcurrency: 5, + }, + publish: { + dirName: 'publish', + pendingAssetsFileName: 'pending-assets.json', + successAssetsFileName: 'success-assets.json', + failedAssetsFileName: 'failed-assets.json', + pendingEntriesFileName: 'pending-entries.json', + successEntriesFileName: 'success-entries.json', + failedEntriesFileName: 'failed-entries.json', + pendingVariantEntriesFileName: 'pending-variant-entries.json', + successVariantEntriesFileName: 'success-variant-entries.json', + failedVariantEntriesFileName: 'failed-variant-entries.json', + }, + variantEntry: { + dirName: 'variants', + }, + personalize: { + dirName: 'personalize', + project_id: 'project-123', + projects: { + dirName: 'projects', + fileName: 'projects.json', + }, + }, + }, + backupDir: '/test/backup', + cliLogsPath: '/test/logs', + canCreatePrivateApp: true, + forceStopMarketplaceAppsPrompt: false, + skipPrivateAppRecreationIfExist: true, + isAuthenticated: true, + auth_token: 'auth-token', + selectedModules: ['publish'], + skipAudit: false, + skipAssetsPublish: false, + skipEntriesPublish: false, + 'exclude-global-modules': false, + replaceExisting: false, + importConcurrency: 5, + fetchConcurrency: 2, + } as any; + + importPublish = new ImportPublish({ + importConfig: mockImportConfig as any, + stackAPIClient: mockStackClient, + moduleName: 'publish', + }); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('Constructor', () => { + it('should initialize with correct parameters', () => { + expect(importPublish).to.be.instanceOf(ImportPublish); + expect(importPublish['importConfig']).to.equal(mockImportConfig); + expect((importPublish as any)['client']).to.equal(mockStackClient); + }); + + it('should have publishConfig property with new file names', () => { + expect(importPublish.publishConfig).to.be.an('object'); + expect(importPublish.publishConfig).to.have.property('dirName', 'publish'); + expect(importPublish.publishConfig).to.have.property('pendingAssetsFileName', 'pending-assets.json'); + expect(importPublish.publishConfig).to.have.property('successAssetsFileName', 'success-assets.json'); + expect(importPublish.publishConfig).to.have.property('failedAssetsFileName', 'failed-assets.json'); + expect(importPublish.publishConfig).to.have.property('pendingEntriesFileName', 'pending-entries.json'); + expect(importPublish.publishConfig).to.have.property('successEntriesFileName', 'success-entries.json'); + expect(importPublish.publishConfig).to.have.property('failedEntriesFileName', 'failed-entries.json'); + expect(importPublish.publishConfig).to.have.property( + 'pendingVariantEntriesFileName', + 'pending-variant-entries.json', + ); + expect(importPublish.publishConfig).to.have.property( + 'successVariantEntriesFileName', + 'success-variant-entries.json', + ); + expect(importPublish.publishConfig).to.have.property( + 'failedVariantEntriesFileName', + 'failed-variant-entries.json', + ); + }); + + it('should set context module to publish', () => { + expect(importPublish['importConfig'].context.module).to.equal('publish'); + }); + + it('should initialize paths correctly', () => { + expect(importPublish['publishDirPath']).to.include('mapper/publish'); + expect(importPublish['pendingAssetsPath']).to.include('pending-assets.json'); + expect(importPublish['pendingEntriesPath']).to.include('pending-entries.json'); + expect(importPublish['successAssetsPath']).to.include('success-assets.json'); + expect(importPublish['failedAssetsPath']).to.include('failed-assets.json'); + expect(importPublish['successEntriesPath']).to.include('success-entries.json'); + expect(importPublish['failedEntriesPath']).to.include('failed-entries.json'); + expect(importPublish['pendingVariantEntriesPath']).to.include('pending-variant-entries.json'); + expect(importPublish['successVariantEntriesPath']).to.include('success-variant-entries.json'); + expect(importPublish['failedVariantEntriesPath']).to.include('failed-variant-entries.json'); + }); + + it('should initialize empty tracking arrays', () => { + expect(importPublish['successAssets']).to.deep.equal([]); + expect(importPublish['failedAssets']).to.deep.equal([]); + expect(importPublish['successEntries']).to.deep.equal({}); + expect(importPublish['failedEntries']).to.deep.equal({}); + expect(importPublish['successVariantEntries']).to.deep.equal([]); + expect(importPublish['failedVariantEntries']).to.deep.equal([]); + }); + + it('should read environments file', () => { + expect(fsUtilReadFileStub.called).to.be.true; + }); + }); + + describe('start() method', () => { + let publishAssetsStub: sinon.SinonStub; + let publishEntriesStub: sinon.SinonStub; + let publishVariantEntriesStub: sinon.SinonStub; + + beforeEach(() => { + publishAssetsStub = sinon.stub(importPublish as any, 'publishAssets').resolves(); + publishEntriesStub = sinon.stub(importPublish as any, 'publishEntries').resolves(); + publishVariantEntriesStub = sinon.stub(importPublish as any, 'publishVariantEntries').resolves(); + }); + + it('should skip when no publish directory exists', async () => { + fileExistsSyncStub.returns(false); + + await importPublish.start(); + + expect(publishAssetsStub.called).to.be.false; + expect(publishEntriesStub.called).to.be.false; + expect(publishVariantEntriesStub.called).to.be.false; + }); + + it('should publish assets first, then entries, then variant entries', async () => { + await importPublish.start(); + + expect(publishAssetsStub.calledOnce).to.be.true; + expect(publishEntriesStub.calledOnce).to.be.true; + expect(publishVariantEntriesStub.calledOnce).to.be.true; + expect(publishAssetsStub.calledBefore(publishEntriesStub)).to.be.true; + expect(publishEntriesStub.calledBefore(publishVariantEntriesStub)).to.be.true; + }); + + it('should skip asset publishing when skipAssetsPublish is true', async () => { + mockImportConfig.skipAssetsPublish = true; + + await importPublish.start(); + + expect(publishAssetsStub.called).to.be.false; + expect(publishEntriesStub.calledOnce).to.be.true; + expect(publishVariantEntriesStub.calledOnce).to.be.true; + }); + + it('should skip entry and variant entry publishing when skipEntriesPublish is true', async () => { + mockImportConfig.skipEntriesPublish = true; + + await importPublish.start(); + + expect(publishAssetsStub.calledOnce).to.be.true; + expect(publishEntriesStub.called).to.be.false; + expect(publishVariantEntriesStub.called).to.be.false; + }); + + it('should skip both when both flags are true', async () => { + mockImportConfig.skipAssetsPublish = true; + mockImportConfig.skipEntriesPublish = true; + + await importPublish.start(); + + expect(publishAssetsStub.called).to.be.false; + expect(publishEntriesStub.called).to.be.false; + expect(publishVariantEntriesStub.called).to.be.false; + }); + + it('should handle errors gracefully', async () => { + publishAssetsStub.rejects(new Error('Publish failed')); + + await importPublish.start(); + + expect(publishAssetsStub.calledOnce).to.be.true; + }); + }); + + describe('publishAssets() method', () => { + let makeConcurrentCallStub: sinon.SinonStub; + let buildAssetPublishDataStub: sinon.SinonStub; + + beforeEach(() => { + makeConcurrentCallStub = sinon.stub(importPublish as any, 'makeConcurrentCall').resolves(); + buildAssetPublishDataStub = sinon.stub(importPublish as any, 'buildAssetPublishData').resolves([]); + importPublish['environments'] = { 'env-1': { name: 'production' } }; + }); + + it('should skip when no pending assets file exists', async () => { + fileExistsSyncStub.withArgs(importPublish['pendingAssetsPath']).returns(false); + + await (importPublish as any).publishAssets(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should skip when pending assets file is empty', async () => { + fsUtilReadFileStub.returns({}); + + await (importPublish as any).publishAssets(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should skip when no assets with valid publish details', async () => { + fsUtilReadFileStub.returns({ + 'old-asset-1': 'new-asset-1', + }); + buildAssetPublishDataStub.resolves([]); + + await (importPublish as any).publishAssets(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should publish assets with valid publish details', async () => { + fsUtilReadFileStub.returns([{ oldUid: 'old-asset-1', newUid: 'new-asset-1' }]); + buildAssetPublishDataStub.resolves([ + { + oldUid: 'old-asset-1', + newUid: 'new-asset-1', + title: 'Asset 1', + publish_details: [{ environment: 'env-1', locale: 'en-us' }], + }, + ]); + + await (importPublish as any).publishAssets(); + + expect(makeConcurrentCallStub.called).to.be.true; + }); + }); + + describe('publishEntries() method', () => { + let makeConcurrentCallStub: sinon.SinonStub; + let buildEntryPublishDataStub: sinon.SinonStub; + + beforeEach(() => { + makeConcurrentCallStub = sinon.stub(importPublish as any, 'makeConcurrentCall').resolves(); + buildEntryPublishDataStub = sinon.stub(importPublish as any, 'buildEntryPublishData').resolves([]); + importPublish['environments'] = { 'env-1': { name: 'production' } }; + }); + + it('should skip when no pending entries file exists', async () => { + fileExistsSyncStub.withArgs(importPublish['pendingEntriesPath']).returns(false); + + await (importPublish as any).publishEntries(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should skip when pending entries file is empty', async () => { + fsUtilReadFileStub.returns({}); + + await (importPublish as any).publishEntries(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should publish entries for each content type and locale', async () => { + fsUtilReadFileStub.returns({ + profiles: [{ locale: 'en-us', oldUid: 'old-entry-1', newUid: 'new-entry-1' }], + }); + buildEntryPublishDataStub.resolves([ + { + oldUid: 'old-entry-1', + newUid: 'new-entry-1', + title: 'Entry 1', + publish_details: [{ environment: 'env-1', locale: 'en-us' }], + }, + ]); + + await (importPublish as any).publishEntries(); + + expect(makeConcurrentCallStub.called).to.be.true; + }); + }); + + describe('writeTrackingFiles() method', () => { + it('should write success assets file when successAssets is not empty', () => { + importPublish['successAssets'] = [{ oldUid: 'old-1', newUid: 'new-1' }]; + + (importPublish as any).writeTrackingFiles('assets'); + + expect(fsUtilWriteFileStub.calledWith(importPublish['successAssetsPath'], importPublish['successAssets'])).to.be + .true; + }); + + it('should write failed assets file when failedAssets is not empty', () => { + importPublish['failedAssets'] = [{ oldUid: 'old-1', newUid: 'new-1', error: 'Error' }]; + + (importPublish as any).writeTrackingFiles('assets'); + + expect(fsUtilWriteFileStub.calledWith(importPublish['failedAssetsPath'], importPublish['failedAssets'])).to.be + .true; + }); + + it('should write success entries file when successEntries is not empty', () => { + importPublish['successEntries'] = { + profiles: [{ locale: 'en-us', oldUid: 'old-1', newUid: 'new-1' }], + }; + + (importPublish as any).writeTrackingFiles('entries'); + + expect(fsUtilWriteFileStub.calledWith(importPublish['successEntriesPath'], importPublish['successEntries'])).to.be + .true; + }); + + it('should write failed entries file when failedEntries is not empty', () => { + importPublish['failedEntries'] = { + profiles: [{ locale: 'en-us', oldUid: 'old-1', newUid: 'new-1', error: 'Error' }], + }; + + (importPublish as any).writeTrackingFiles('entries'); + + expect(fsUtilWriteFileStub.calledWith(importPublish['failedEntriesPath'], importPublish['failedEntries'])).to.be + .true; + }); + + it('should not write files when tracking arrays are empty', () => { + (importPublish as any).writeTrackingFiles('assets'); + + expect(fsUtilWriteFileStub.called).to.be.false; + }); + + it('should write variant entry tracking files when type is variant-entries', () => { + importPublish['successVariantEntries'] = [ + { + content_type: 'profiles', + old_entry_uid: 'old-1', + entry_uid: 'new-1', + locale: 'en-us', + old_variant_uid: 'v-old-1', + variant_uid: 'v-new-1', + }, + ]; + importPublish['failedVariantEntries'] = []; + + (importPublish as any).writeTrackingFiles('variant-entries'); + + expect( + fsUtilWriteFileStub.calledWith( + importPublish['successVariantEntriesPath'], + importPublish['successVariantEntries'], + ), + ).to.be.true; + }); + }); + + describe('publishVariantEntries() method', () => { + let makeConcurrentCallStub: sinon.SinonStub; + let buildVariantEntryPublishDataStub: sinon.SinonStub; + + beforeEach(() => { + makeConcurrentCallStub = sinon.stub(importPublish as any, 'makeConcurrentCall').resolves(); + buildVariantEntryPublishDataStub = sinon.stub(importPublish as any, 'buildVariantEntryPublishData').resolves([]); + }); + + it('should skip when no pending variant entries file exists', async () => { + fileExistsSyncStub.withArgs(importPublish['pendingVariantEntriesPath']).returns(false); + + await (importPublish as any).publishVariantEntries(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should skip when pending variant entries file is empty', async () => { + fsUtilReadFileStub.returns([]); + + await (importPublish as any).publishVariantEntries(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + + it('should skip when no variant entries with valid publish details', async () => { + fsUtilReadFileStub.returns([ + { + content_type: 'profiles', + old_entry_uid: 'old-1', + entry_uid: 'new-1', + locale: 'en-us', + old_variant_uid: 'v-old-1', + variant_uid: 'v-new-1', + }, + ]); + buildVariantEntryPublishDataStub.resolves([]); + + await (importPublish as any).publishVariantEntries(); + + expect(makeConcurrentCallStub.called).to.be.false; + }); + }); + + describe('Integration Tests', () => { + it('should complete full publish flow', async () => { + const publishAssetsStub = sinon.stub(importPublish as any, 'publishAssets').resolves(); + const publishEntriesStub = sinon.stub(importPublish as any, 'publishEntries').resolves(); + const publishVariantEntriesStub = sinon.stub(importPublish as any, 'publishVariantEntries').resolves(); + + await importPublish.start(); + + expect(publishAssetsStub.calledOnce).to.be.true; + expect(publishEntriesStub.calledOnce).to.be.true; + expect(publishVariantEntriesStub.calledOnce).to.be.true; + expect(publishAssetsStub.calledBefore(publishEntriesStub)).to.be.true; + expect(publishEntriesStub.calledBefore(publishVariantEntriesStub)).to.be.true; + }); + + it('should respect skip flags in full flow', async () => { + mockImportConfig.skipAssetsPublish = true; + mockImportConfig.skipEntriesPublish = true; + + const publishAssetsStub = sinon.stub(importPublish as any, 'publishAssets').resolves(); + const publishEntriesStub = sinon.stub(importPublish as any, 'publishEntries').resolves(); + const publishVariantEntriesStub = sinon.stub(importPublish as any, 'publishVariantEntries').resolves(); + + await importPublish.start(); + + expect(publishAssetsStub.called).to.be.false; + expect(publishEntriesStub.called).to.be.false; + expect(publishVariantEntriesStub.called).to.be.false; + }); + }); +}); 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 c9b5672182..6ff36fdecc 100644 --- a/packages/contentstack-import/test/unit/utils/extension-helper.test.ts +++ b/packages/contentstack-import/test/unit/utils/extension-helper.test.ts @@ -123,6 +123,18 @@ describe('Extension Helper', () => { apiConcurrency: 1, query: { locale: 'en-us' }, }, + publish: { + dirName: 'publish', + pendingAssetsFileName: 'pending-assets.json', + successAssetsFileName: 'success-assets.json', + failedAssetsFileName: 'failed-assets.json', + pendingEntriesFileName: 'pending-entries.json', + successEntriesFileName: 'success-entries.json', + failedEntriesFileName: 'failed-entries.json', + pendingVariantEntriesFileName: 'pending-variant-entries.json', + successVariantEntriesFileName: 'success-variant-entries.json', + failedVariantEntriesFileName: 'failed-variant-entries.json', + }, }, branches: [{ uid: 'main', source: 'main' }], isAuthenticated: true, diff --git a/packages/contentstack-migration/README.md b/packages/contentstack-migration/README.md index bc918ec3c4..4ee5ac5051 100644 --- a/packages/contentstack-migration/README.md +++ b/packages/contentstack-migration/README.md @@ -21,7 +21,7 @@ $ npm install -g @contentstack/cli-migration $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-migration/1.10.3 darwin-arm64 node-v24.13.0 +@contentstack/cli-migration/1.11.0 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -121,7 +121,7 @@ EXAMPLES $ csdx cm:migration --alias --file-path -k ``` -_See code: [src/commands/cm/stacks/migration.js](https://github.com/contentstack/cli/blob/main/packages/contentstack-migration/src/commands/cm/stacks/migration.js)_ +_See code: [src/commands/cm/stacks/migration.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-migration/src/commands/cm/stacks/migration.ts)_ ### Points to remember diff --git a/packages/contentstack-variants/package.json b/packages/contentstack-variants/package.json index e1cd826da4..fe311601f4 100644 --- a/packages/contentstack-variants/package.json +++ b/packages/contentstack-variants/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/cli-variants", - "version": "1.3.7", + "version": "1.4.0", "description": "Variants plugin", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/packages/contentstack-variants/src/import/variant-entries.ts b/packages/contentstack-variants/src/import/variant-entries.ts index c4e474827c..87ce48b26d 100644 --- a/packages/contentstack-variants/src/import/variant-entries.ts +++ b/packages/contentstack-variants/src/import/variant-entries.ts @@ -39,6 +39,14 @@ export default class VariantEntries extends VariantAdapter; private environments!: Record; + private pendingVariantEntries: Array<{ + content_type: string; + old_entry_uid: string; + entry_uid: string; + locale: string; + old_variant_uid: string; + variant_uid: string; + }> = []; constructor(readonly config: ImportConfig & { helpers?: ImportHelperMethodsConfig }) { const conf: APIConfig & AdapterType, APIConfig> = { @@ -153,7 +161,9 @@ export default class VariantEntries extends VariantAdapter + this.environments?.hasOwnProperty(pd.environment), + ); + if (validPublishDetails.length > 0) { + this.pendingVariantEntries.push({ + content_type, + old_entry_uid: oldEntryUid, + entry_uid: entryUid, + locale, + old_variant_uid: oldVariantUid, + variant_uid: newVariantUid, + }); + } + } + } + } + + /** + * Saves pending variant entry UID mappings for deferred publishing. + */ + async savePublishDetails(): Promise { + if (this.pendingVariantEntries.length === 0) { + log.info('No variant entries with publish details to track', this.config.context); + return; + } + + const publishConfig = this.config.modules.publish; + if (!publishConfig) { + log.warn('Publish config not found, skipping save', this.config.context); + return; + } + + const publishDirPath = resolve(sanitizePath(this.config.backupDir), 'mapper', publishConfig.dirName); + const pendingFilePath = resolve(publishDirPath, publishConfig.pendingVariantEntriesFileName); + + await fsUtil.makeDirectory(publishDirPath); + fsUtil.writeFile(pendingFilePath, this.pendingVariantEntries); + + log.success( + `Saved ${this.pendingVariantEntries.length} variant entries for deferred publishing`, + this.config.context, + ); + } + /** * Serializes the change set of a entry variant. * @param variantEntry - The entry variant to serialize. @@ -488,7 +565,7 @@ export default class VariantEntries extends VariantAdapter { expect(entryVariantInstace.taxonomies).to.contain({}); }); + + test + .stub(Import.VariantEntries.prototype, 'importVariantEntries', async () => {}) + .stub(Import.VariantEntries.prototype, 'savePublishDetails', async () => {}) + .spy(Import.VariantEntries.prototype, 'savePublishDetails') + .it('should call savePublishDetails after importing variant entries', async ({ spy }) => { + let entryVariantInstace = new Import.VariantEntries(config); + await entryVariantInstace.import(); + + expect(spy.savePublishDetails.called).to.be.true; + }); }); describe('importVariantEntries method', () => { @@ -151,6 +162,18 @@ describe('Variant Entries Import', () => { expect(ctx.stdout).to.be.includes(entryVariantInstace.messages.VARIANT_ID_NOT_FOUND); }); + + test + .stub(VariantHttpClient.prototype, 'createVariantEntry', async () => {}) + .stub(Import.VariantEntries.prototype, 'handleVariantEntryRelationalData', () => variantEntries[0]) + .spy(VariantHttpClient.prototype, 'publishVariantEntry') + .it('should not call publishVariantEntry (deferred to publish module)', async ({ spy }) => { + let entryVariantInstace = new Import.VariantEntries(config); + entryVariantInstace.variantIdList = { 'VARIANT-ID-1': 'VARIANT-ID-2' }; + await entryVariantInstace.handleConcurrency(ContentType, variantEntries, variantEntryData[0]); + + expect(spy.publishVariantEntry.called).to.be.false; + }); }); describe('handleVariantEntryRelationalData method', () => { diff --git a/packages/contentstack/README.md b/packages/contentstack/README.md index 3121de5259..97dbdff836 100644 --- a/packages/contentstack/README.md +++ b/packages/contentstack/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli $ csdx COMMAND running command... $ csdx (--version|-v) -@contentstack/cli/1.56.0 darwin-arm64 node-v24.13.0 +@contentstack/cli/1.58.1 darwin-arm64 node-v24.13.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -3060,7 +3060,7 @@ EXAMPLES $ csdx cm:migration --alias --file-path -k ``` -_See code: [@contentstack/cli-migration](https://github.com/contentstack/cli/blob/main/packages/contentstack-migration/src/commands/cm/stacks/migration.js)_ +_See code: [@contentstack/cli-migration](https://github.com/contentstack/cli/blob/main/packages/contentstack-migration/src/commands/cm/stacks/migration.ts)_ ## `csdx cm:stacks:publish` @@ -3972,8 +3972,7 @@ USAGE $ csdx launch:functions [-p ] [-d ] FLAGS - -d, --data-dir= [default: /Users/netraj.patel/projects/contentstack/cli/packages/contentstack] Current working - directory + -d, --data-dir= Current working directory -p, --port= [default: 3000] Port number DESCRIPTION @@ -4149,7 +4148,7 @@ EXAMPLES $ csdx plugins ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/index.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/index.ts)_ ## `csdx plugins:add PLUGIN` @@ -4223,7 +4222,7 @@ EXAMPLES $ csdx plugins:inspect myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/inspect.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/inspect.ts)_ ## `csdx plugins:install PLUGIN` @@ -4272,7 +4271,7 @@ EXAMPLES $ csdx plugins:install someuser/someplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/install.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/install.ts)_ ## `csdx plugins:link PATH` @@ -4303,7 +4302,7 @@ EXAMPLES $ csdx plugins:link myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/link.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/link.ts)_ ## `csdx plugins:remove [PLUGIN]` @@ -4344,7 +4343,7 @@ FLAGS --reinstall Reinstall all plugins after uninstalling. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/reset.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/reset.ts)_ ## `csdx plugins:uninstall [PLUGIN]` @@ -4372,7 +4371,7 @@ EXAMPLES $ csdx plugins:uninstall myplugin ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/uninstall.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/uninstall.ts)_ ## `csdx plugins:unlink [PLUGIN]` @@ -4416,7 +4415,7 @@ DESCRIPTION Update installed plugins. ``` -_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.55/src/commands/plugins/update.ts)_ +_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.56/src/commands/plugins/update.ts)_ ## `csdx tokens` diff --git a/packages/contentstack/package.json b/packages/contentstack/package.json index 710e4af967..a23436dbfd 100755 --- a/packages/contentstack/package.json +++ b/packages/contentstack/package.json @@ -24,7 +24,7 @@ "dependencies": { "@contentstack/cli-audit": "~1.17.1", "@contentstack/cli-cm-export": "~1.23.2", - "@contentstack/cli-cm-import": "~1.31.3", + "@contentstack/cli-cm-import": "~1.32.0", "@contentstack/cli-auth": "~1.7.3", "@contentstack/cli-cm-bootstrap": "~1.18.4", "@contentstack/cli-cm-branches": "~1.6.3", @@ -39,7 +39,7 @@ "@contentstack/cli-launch": "^1.9.6", "@contentstack/cli-migration": "~1.11.0", "@contentstack/cli-utilities": "~1.17.2", - "@contentstack/cli-variants": "~1.3.7", + "@contentstack/cli-variants": "~1.4.0", "@contentstack/management": "~1.27.5", "@oclif/core": "^4.3.0", "@oclif/plugin-help": "^6.2.28", @@ -167,4 +167,4 @@ } }, "repository": "https://github.com/contentstack/cli" -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 313c945c33..4b307c80a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,7 +20,7 @@ importers: '@contentstack/cli-cm-clone': ~1.20.1 '@contentstack/cli-cm-export': ~1.23.2 '@contentstack/cli-cm-export-to-csv': ~1.11.0 - '@contentstack/cli-cm-import': ~1.31.3 + '@contentstack/cli-cm-import': ~1.32.0 '@contentstack/cli-cm-import-setup': ~1.7.3 '@contentstack/cli-cm-migrate-rte': ~1.6.4 '@contentstack/cli-cm-seed': ~1.14.3 @@ -29,7 +29,7 @@ importers: '@contentstack/cli-launch': ^1.9.6 '@contentstack/cli-migration': ~1.11.0 '@contentstack/cli-utilities': ~1.17.2 - '@contentstack/cli-variants': ~1.3.7 + '@contentstack/cli-variants': ~1.4.0 '@contentstack/management': ~1.27.5 '@oclif/core': ^4.3.0 '@oclif/plugin-help': ^6.2.28 @@ -412,7 +412,7 @@ importers: dependencies: '@colors/colors': 1.6.0 '@contentstack/cli-cm-export': link:../contentstack-export - '@contentstack/cli-cm-import': link:../contentstack-import + '@contentstack/cli-cm-import': 1.31.3_@types+node@14.18.63 '@contentstack/cli-command': link:../contentstack-command '@contentstack/cli-utilities': link:../contentstack-utilities '@oclif/core': 4.8.0 @@ -590,7 +590,7 @@ importers: dependencies: '@contentstack/cli-command': link:../contentstack-command '@contentstack/cli-utilities': link:../contentstack-utilities - '@contentstack/cli-variants': link:../contentstack-variants + '@contentstack/cli-variants': 1.3.7 '@oclif/core': 4.8.0 async: 3.2.6 big-json: 3.2.0 @@ -687,7 +687,8 @@ importers: '@contentstack/cli-audit': ~1.17.1 '@contentstack/cli-command': ~1.7.2 '@contentstack/cli-utilities': ~1.17.2 - '@contentstack/cli-variants': ~1.3.7 + '@contentstack/cli-variants': ~1.4.0 + '@contentstack/management': ~1.27.3 '@oclif/core': ^4.3.0 '@oclif/test': ^4.1.16 '@types/big-json': ^3.2.5 @@ -725,6 +726,7 @@ importers: '@contentstack/cli-command': link:../contentstack-command '@contentstack/cli-utilities': link:../contentstack-utilities '@contentstack/cli-variants': link:../contentstack-variants + '@contentstack/management': 1.27.5_debug@4.4.3 '@oclif/core': 4.8.0 big-json: 3.2.0 bluebird: 3.7.2 @@ -953,7 +955,7 @@ importers: ts-node: ^8.10.2 typescript: ^4.9.5 dependencies: - '@contentstack/cli-cm-import': link:../contentstack-import + '@contentstack/cli-cm-import': 1.31.3_@types+node@14.18.63 '@contentstack/cli-command': link:../contentstack-command '@contentstack/cli-utilities': link:../contentstack-utilities inquirer: 8.2.7_@types+node@14.18.63 @@ -2144,6 +2146,54 @@ packages: engines: {node: '>=0.1.90'} dev: false + /@contentstack/cli-audit/1.17.1_lxq42tdpoxpye5tb7w3htdbbdq: + resolution: {integrity: sha512-xJCA+oPqj5mmOkkK5+ElCEPLnbzlA/p1/HYnX3JLDJ8FvFEinVicUiTtH2xWdXXCQuBVnA/XgA/5ntkIzvxMWQ==} + engines: {node: '>=16'} + hasBin: true + dependencies: + '@contentstack/cli-command': 1.7.2_lxq42tdpoxpye5tb7w3htdbbdq + '@contentstack/cli-utilities': 1.17.2_lxq42tdpoxpye5tb7w3htdbbdq + '@oclif/core': 4.8.0 + '@oclif/plugin-help': 6.2.37 + '@oclif/plugin-plugins': 5.4.56 + chalk: 4.1.2 + fast-csv: 4.3.6 + fs-extra: 11.3.3 + lodash: 4.17.23 + uuid: 9.0.1 + winston: 3.19.0 + transitivePeerDependencies: + - '@types/node' + - debug + - supports-color + dev: false + + /@contentstack/cli-cm-import/1.31.3_@types+node@14.18.63: + resolution: {integrity: sha512-s/vPCKQigZNmXQ0B5RpKHLypNVWT/Rk7KJIPp3Ua2jUrAG9hXQnbbG9/ySNeQZRFMPcosbgvRp7xUfysQXCouw==} + engines: {node: '>=14.0.0'} + dependencies: + '@contentstack/cli-audit': 1.17.1_lxq42tdpoxpye5tb7w3htdbbdq + '@contentstack/cli-command': 1.7.2_lxq42tdpoxpye5tb7w3htdbbdq + '@contentstack/cli-utilities': 1.17.2_lxq42tdpoxpye5tb7w3htdbbdq + '@contentstack/cli-variants': 1.3.7_lxq42tdpoxpye5tb7w3htdbbdq + '@oclif/core': 4.8.0 + big-json: 3.2.0 + bluebird: 3.7.2 + chalk: 4.1.2 + debug: 4.4.3 + fs-extra: 11.3.3 + lodash: 4.17.23 + marked: 4.3.0 + merge: 2.1.1 + mkdirp: 1.0.4 + promise-limit: 2.7.0 + uuid: 9.0.1 + winston: 3.19.0 + transitivePeerDependencies: + - '@types/node' + - supports-color + dev: false + /@contentstack/cli-command/1.7.2_lxq42tdpoxpye5tb7w3htdbbdq: resolution: {integrity: sha512-dtXc3gIcnivfLegADy5/PZb+1x/esZ65H2E1CjO/pg50UC8Vy1U+U0ozS0hJZTFoaVjeG+1VJRoxf5MrtUGnNA==} engines: {node: '>=14.0.0'} @@ -2199,6 +2249,43 @@ packages: - typescript dev: false + /@contentstack/cli-utilities/1.17.2: + resolution: {integrity: sha512-lnh6iI3SPoT04QFHIBs7hqkwTcsFjHt1kaWdRBozU8j6on28N3OlmObUcvuyx4vg704hHfL17CSnGxsNNwhnvA==} + dependencies: + '@contentstack/management': 1.27.5 + '@contentstack/marketplace-sdk': 1.5.0 + '@oclif/core': 4.8.0 + axios: 1.13.5 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-progress: 3.12.0 + cli-table: 0.3.11 + conf: 10.2.0 + dotenv: 16.6.1 + figures: 3.2.0 + inquirer: 8.2.7 + inquirer-search-checkbox: 1.0.0 + inquirer-search-list: 1.2.6 + js-yaml: 4.1.1 + klona: 2.0.6 + lodash: 4.17.23 + mkdirp: 1.0.4 + open: 8.4.2 + ora: 5.4.1 + papaparse: 5.5.3 + recheck: 4.4.5 + rxjs: 6.6.7 + traverse: 0.6.11 + tty-table: 4.2.3 + unique-string: 2.0.0 + uuid: 9.0.1 + winston: 3.19.0 + xdg-basedir: 4.0.0 + transitivePeerDependencies: + - '@types/node' + - debug + dev: false + /@contentstack/cli-utilities/1.17.2_lxq42tdpoxpye5tb7w3htdbbdq: resolution: {integrity: sha512-lnh6iI3SPoT04QFHIBs7hqkwTcsFjHt1kaWdRBozU8j6on28N3OlmObUcvuyx4vg704hHfL17CSnGxsNNwhnvA==} dependencies: @@ -2236,6 +2323,34 @@ packages: - debug dev: false + /@contentstack/cli-variants/1.3.7: + resolution: {integrity: sha512-MrOCjU1sJpgHmTmTNrRuOiJFwwoDp4uLvZebO2K9UHiMwkgPv7vGDcqTTAFXedDp+CA16YKX0OAA+nc9EcX7OQ==} + dependencies: + '@contentstack/cli-utilities': 1.17.2 + '@oclif/core': 4.8.0 + '@oclif/plugin-help': 6.2.37 + lodash: 4.17.23 + mkdirp: 1.0.4 + winston: 3.19.0 + transitivePeerDependencies: + - '@types/node' + - debug + dev: false + + /@contentstack/cli-variants/1.3.7_lxq42tdpoxpye5tb7w3htdbbdq: + resolution: {integrity: sha512-MrOCjU1sJpgHmTmTNrRuOiJFwwoDp4uLvZebO2K9UHiMwkgPv7vGDcqTTAFXedDp+CA16YKX0OAA+nc9EcX7OQ==} + dependencies: + '@contentstack/cli-utilities': 1.17.2_lxq42tdpoxpye5tb7w3htdbbdq + '@oclif/core': 4.8.0 + '@oclif/plugin-help': 6.2.37 + lodash: 4.17.23 + mkdirp: 1.0.4 + winston: 3.19.0 + transitivePeerDependencies: + - '@types/node' + - debug + dev: false + /@contentstack/json-rte-serializer/2.1.0: resolution: {integrity: sha512-klw+0kH5UtL4mHGDP7A8olZIaA4CoyAVzveYqso8uxeDXKkTvwF8D5HBhCqQLr0NXwhofl+FF431cbzGZ3TNCg==} dependencies: