diff --git a/package-lock.json b/package-lock.json index 5203d1bc2e..f5522f5671 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23530,10 +23530,10 @@ "@contentstack/cli-cm-bootstrap": "~1.7.1", "@contentstack/cli-cm-branches": "~1.0.22", "@contentstack/cli-cm-bulk-publish": "~1.4.0", - "@contentstack/cli-cm-clone": "~1.9.0", + "@contentstack/cli-cm-clone": "~1.10.0", "@contentstack/cli-cm-export": "~1.10.4", "@contentstack/cli-cm-export-to-csv": "~1.6.2", - "@contentstack/cli-cm-import": "~1.13.2", + "@contentstack/cli-cm-import": "~1.13.3", "@contentstack/cli-cm-migrate-rte": "~1.4.15", "@contentstack/cli-cm-seed": "~1.7.1", "@contentstack/cli-command": "~1.2.17", @@ -24225,12 +24225,12 @@ }, "packages/contentstack-clone": { "name": "@contentstack/cli-cm-clone", - "version": "1.9.0", + "version": "1.10.0", "license": "MIT", "dependencies": { "@colors/colors": "^1.5.0", "@contentstack/cli-cm-export": "~1.10.4", - "@contentstack/cli-cm-import": "~1.13.2", + "@contentstack/cli-cm-import": "~1.13.3", "@contentstack/cli-command": "~1.2.16", "@contentstack/cli-utilities": "~1.5.11", "async": "^3.2.4", @@ -24238,6 +24238,7 @@ "child_process": "^1.0.2", "fancy-test": "^1.4.10", "inquirer": "8.2.4", + "merge": "^2.1.1", "ora": "^5.1.0", "prompt": "^1.3.0", "rimraf": "^3.0.2", @@ -25268,7 +25269,7 @@ }, "packages/contentstack-import": { "name": "@contentstack/cli-cm-import", - "version": "1.13.2", + "version": "1.13.3", "license": "MIT", "dependencies": { "@contentstack/cli-audit": "^1.3.3", @@ -25843,7 +25844,7 @@ "version": "1.7.1", "license": "MIT", "dependencies": { - "@contentstack/cli-cm-import": "~1.13.2", + "@contentstack/cli-cm-import": "~1.13.3", "@contentstack/cli-command": "~1.2.16", "@contentstack/cli-utilities": "~1.5.11", "inquirer": "8.2.4", @@ -26026,31 +26027,23 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "packages/contentstack/node_modules/@contentstack/cli-cm-clone/node_modules/@contentstack/cli-cm-import": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@contentstack/cli-cm-import/-/cli-cm-import-1.10.0.tgz", - "integrity": "sha512-Jn9grDE2J1c4iGBcPv24Q8lj/ozgfD9QNbJcn+1a6oGjA6OE+a39agQwi04nByBw4xRtbLUmHa4nfFRaF7qkvQ==", + "packages/contentstack/node_modules/@contentstack/cli-cm-clone/node_modules/fancy-test": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/fancy-test/-/fancy-test-1.4.10.tgz", + "integrity": "sha512-AaUX6wKS7D5OP2YK2q5G7c8PGx2lgoyLUD7Bbg8z323sb9aebBqzb9UN6phzI73UgO/ViihmNfOxF3kdfZLhew==", "extraneous": true, "dependencies": { - "@contentstack/cli-command": "~1.2.14", - "@contentstack/cli-utilities": "~1.5.4", - "@contentstack/management": "~1.10.2", - "@oclif/core": "^2.9.3", - "big-json": "^3.2.0", - "bluebird": "^3.7.2", - "chalk": "^4.1.2", - "debug": "^4.1.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.20", - "marked": "^4.0.17", - "merge": "^2.1.1", - "mkdirp": "^1.0.4", - "promise-limit": "^2.7.0", - "tslib": "^2.4.1", - "winston": "^3.7.2" + "@types/chai": "*", + "@types/lodash": "*", + "@types/node": "*", + "@types/sinon": "*", + "lodash": "^4.17.13", + "mock-stdin": "^1.0.0", + "nock": "^13.0.0", + "stdout-stderr": "^0.1.9" }, "engines": { - "node": ">=14.0.0" + "node": ">=8.0.0" } }, "packages/contentstack/node_modules/@contentstack/cli-cm-clone/node_modules/rimraf": { diff --git a/packages/contentstack-audit/README.md b/packages/contentstack-audit/README.md index 65dddb78a5..a9766ba649 100644 --- a/packages/contentstack-audit/README.md +++ b/packages/contentstack-audit/README.md @@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit $ csdx COMMAND running command... $ csdx (--version|-v) -@contentstack/cli-audit/1.3.4 darwin-arm64 node-v18.12.1 +@contentstack/cli-audit/1.3.4 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-branches/README.md b/packages/contentstack-branches/README.md index d0ae021d5d..74abddd444 100755 --- a/packages/contentstack-branches/README.md +++ b/packages/contentstack-branches/README.md @@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-branches/1.0.21 darwin-arm64 node-v20.8.0 +@contentstack/cli-cm-branches/1.0.22 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-bulk-publish/README.md b/packages/contentstack-bulk-publish/README.md index d7f25b559d..2518496f86 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.4.0 darwin-arm64 node-v20.10.0 +@contentstack/cli-cm-bulk-publish/1.4.0 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-clone/README.md b/packages/contentstack-clone/README.md index df030887f0..85de4211c1 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.9.0 darwin-arm64 node-v20.8.0 +@contentstack/cli-cm-clone/1.10.0 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -51,6 +51,7 @@ USAGE [--destination-stack-api-key ] [--import-webhook-status disable|current] FLAGS + -c, --config= Path for the external configuration -n, --stack-name= Name for the new stack to store the cloned content. -y, --yes [Optional] Override marketplace prompts --destination-management-token-alias= Source API key of the target stack token alias. @@ -101,6 +102,7 @@ USAGE [--destination-stack-api-key ] [--import-webhook-status disable|current] FLAGS + -c, --config= Path for the external configuration -n, --stack-name= Name for the new stack to store the cloned content. -y, --yes [Optional] Override marketplace prompts --destination-management-token-alias= Source API key of the target stack token alias. diff --git a/packages/contentstack-clone/package.json b/packages/contentstack-clone/package.json index e7a9b9a29e..63bac73592 100644 --- a/packages/contentstack-clone/package.json +++ b/packages/contentstack-clone/package.json @@ -1,12 +1,12 @@ { "name": "@contentstack/cli-cm-clone", "description": "Contentstack stack clone plugin", - "version": "1.9.0", + "version": "1.10.0", "author": "Contentstack", "bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues", "dependencies": { "@contentstack/cli-cm-export": "~1.10.4", - "@contentstack/cli-cm-import": "~1.13.2", + "@contentstack/cli-cm-import": "~1.13.3", "@contentstack/cli-command": "~1.2.16", "@contentstack/cli-utilities": "~1.5.11", "@colors/colors": "^1.5.0", @@ -18,7 +18,9 @@ "ora": "^5.1.0", "prompt": "^1.3.0", "rimraf": "^3.0.2", - "winston": "^3.7.2" + "winston": "^3.7.2", + "merge": "^2.1.1", + "lodash": "^4.17.20" }, "devDependencies": { "@oclif/test": "^1.2.7", diff --git a/packages/contentstack-clone/src/commands/cm/stacks/clone.js b/packages/contentstack-clone/src/commands/cm/stacks/clone.js index 6f0e1d8766..9f2e0bb919 100644 --- a/packages/contentstack-clone/src/commands/cm/stacks/clone.js +++ b/packages/contentstack-clone/src/commands/cm/stacks/clone.js @@ -3,8 +3,9 @@ const { configHandler, flags, isAuthenticated, managementSDKClient } = require(' const { CloneHandler } = require('../../../lib/util/clone-handler'); const path = require('path'); const rimraf = require('rimraf'); +const merge = require("merge") let pathdir = path.join(__dirname.split('src')[0], 'contents'); -const { readdirSync } = require('fs'); +const { readdirSync, readFileSync } = require('fs'); let config = {}; class StackCloneCommand extends Command { @@ -23,11 +24,17 @@ class StackCloneCommand extends Command { 'source-management-token-alias': sourceManagementTokenAlias, 'destination-management-token-alias': destinationManagementTokenAlias, 'import-webhook-status': importWebhookStatus, + 'config': externalConfigPath } = cloneCommandFlags; const handleClone = async () => { const listOfTokens = configHandler.get('tokens'); + if (externalConfigPath) { + let externalConfig = readFileSync(externalConfigPath, 'utf-8') + externalConfig = JSON.parse(externalConfig); + config = merge.recursive(config, externalConfig); + } config.forceStopMarketplaceAppsPrompt = yes; config.skipAudit = cloneCommandFlags['skip-audit']; @@ -249,6 +256,11 @@ b) Structure with content (all modules including entries & assets) 'skip-audit': flags.boolean({ description: 'Skips the audit fix.', }), + 'config': flags.string({ + char: 'c', + required: false, + description: 'Path for the external configuration', + }), }; StackCloneCommand.usage = diff --git a/packages/contentstack-clone/src/lib/util/clone-handler.js b/packages/contentstack-clone/src/lib/util/clone-handler.js index e471e29b26..adb0a10ffc 100644 --- a/packages/contentstack-clone/src/lib/util/clone-handler.js +++ b/packages/contentstack-clone/src/lib/util/clone-handler.js @@ -8,6 +8,7 @@ let { default: importCmd } = require('@contentstack/cli-cm-import'); const { CustomAbortController } = require('./abort-controller'); const prompt = require('prompt'); const colors = require('@colors/colors/safe'); +const cloneDeep = require("lodash/cloneDeep") const { HandleOrgCommand, @@ -616,23 +617,29 @@ class CloneHandler { async cmdExport() { return new Promise((resolve, reject) => { - const cmd = ['-k', config.source_stack, '-d', __dirname.split('src')[0] + 'contents']; - if (config.cloneType === 'a') { - config.filteredModules = ['stack'].concat(structureList); - cmd.push('-c'); - cmd.push(path.join(__dirname, 'dummyConfig.json')); + // Creating export specific config by merging external configurations + let exportConfig = Object.assign({}, cloneDeep(config), {...config?.export}); + delete exportConfig.import; + delete exportConfig.export; + + const cmd = ['-k', exportConfig.source_stack, '-d', __dirname.split('src')[0] + 'contents']; + if (exportConfig.cloneType === 'a') { + exportConfig.filteredModules = ['stack'].concat(structureList); } - if (config.source_alias) { - cmd.push('-a', config.source_alias); + if (exportConfig.source_alias) { + cmd.push('-a', exportConfig.source_alias); } - if (config.sourceStackBranch) { - cmd.push('--branch', config.sourceStackBranch); + if (exportConfig.sourceStackBranch) { + cmd.push('--branch', exportConfig.sourceStackBranch); } - if (config.forceStopMarketplaceAppsPrompt) cmd.push('-y'); + if (exportConfig.forceStopMarketplaceAppsPrompt) cmd.push('-y'); - fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify(config)); + cmd.push('-c'); + cmd.push(path.join(__dirname, 'dummyConfig.json')); + + fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify(exportConfig)); let exportData = exportCmd.run(cmd); exportData.then(() => resolve(true)).catch(reject); }); @@ -640,27 +647,33 @@ class CloneHandler { async cmdImport() { return new Promise(async (resolve, _reject) => { + // Creating export specific config by merging external configurations + let importConfig = Object.assign({}, cloneDeep(config), {...config?.import}); + delete importConfig.import; + delete importConfig.export; + const cmd = ['-c', path.join(__dirname, 'dummyConfig.json')]; - if (config.destination_alias) { - cmd.push('-a', config.destination_alias); + if (importConfig.destination_alias) { + cmd.push('-a', importConfig.destination_alias); } - if (!config.data && config.sourceStackBranch) { - cmd.push('-d', path.join(config.pathDir, config.sourceStackBranch)); + if (!importConfig.data && importConfig.sourceStackBranch) { + cmd.push('-d', path.join(importConfig.pathDir, importConfig.sourceStackBranch)); } - if (config.targetStackBranch) { - cmd.push('--branch', config.targetStackBranch); + if (importConfig.targetStackBranch) { + cmd.push('--branch', importConfig.targetStackBranch); } - if (config.importWebhookStatus) { - cmd.push('--import-webhook-status', config.importWebhookStatus); + if (importConfig.importWebhookStatus) { + cmd.push('--import-webhook-status', importConfig.importWebhookStatus); } - if (config.skipAudit) cmd.push('--skip-audit'); + if (importConfig.skipAudit) cmd.push('--skip-audit'); - if (config.forceStopMarketplaceAppsPrompt) cmd.push('-y'); + if (importConfig.forceStopMarketplaceAppsPrompt) cmd.push('-y'); - fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify(config)); + fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify(importConfig)); await importCmd.run(cmd); + fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify({})) return resolve(); }); } diff --git a/packages/contentstack-config/README.md b/packages/contentstack-config/README.md index bf4b65c8d6..85326a1899 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.5.1 darwin-arm64 node-v20.8.0 +@contentstack/cli-config/1.6.0 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-export/README.md b/packages/contentstack-export/README.md index 8642692eee..08d60884f0 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.10.3 darwin-arm64 node-v20.8.0 +@contentstack/cli-cm-export/1.10.4 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-import/README.md b/packages/contentstack-import/README.md index 668ba8bb24..067cb318e0 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.13.0 darwin-arm64 node-v20.8.0 +@contentstack/cli-cm-import/1.13.2 darwin-arm64 node-v20.8.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-import/package.json b/packages/contentstack-import/package.json index 22a6d0dee9..517df7977f 100644 --- a/packages/contentstack-import/package.json +++ b/packages/contentstack-import/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-import", "description": "Contentstack CLI plugin to import content into stack", - "version": "1.13.2", + "version": "1.13.3", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { diff --git a/packages/contentstack-import/src/commands/cm/stacks/import.ts b/packages/contentstack-import/src/commands/cm/stacks/import.ts index 047a528453..eba9275aff 100644 --- a/packages/contentstack-import/src/commands/cm/stacks/import.ts +++ b/packages/contentstack-import/src/commands/cm/stacks/import.ts @@ -141,7 +141,7 @@ export default class ImportCommand extends Command { 'success', ); } catch (error) { - log({ data: backupDir } as ImportConfig, `Failed to import stack content - ${formatError(error)}`, 'error'); + log({ data: backupDir ?? path.join(backupDir || __dirname, 'logs', 'import') } as ImportConfig, `Failed to import stack content - ${formatError(error)}`, 'error'); log( { data: backupDir } as ImportConfig, `The log has been stored at ${ diff --git a/packages/contentstack-import/src/utils/import-config-handler.ts b/packages/contentstack-import/src/utils/import-config-handler.ts index 1421a3e5c6..233a47ff00 100644 --- a/packages/contentstack-import/src/utils/import-config-handler.ts +++ b/packages/contentstack-import/src/utils/import-config-handler.ts @@ -35,7 +35,7 @@ const setupConfig = async (importCmdFlags: any): Promise => { const managementTokenAlias = importCmdFlags['management-token-alias'] || importCmdFlags['alias']; if (managementTokenAlias) { - const { token, apiKey } = configHandler.get(`tokens.${managementTokenAlias}`); + const { token, apiKey } = configHandler.get(`tokens.${managementTokenAlias}`) ?? {}; config.management_token = token; config.apiKey = apiKey; if (!config.management_token) { diff --git a/packages/contentstack-seed/package.json b/packages/contentstack-seed/package.json index 044e5f36b2..2322efead6 100644 --- a/packages/contentstack-seed/package.json +++ b/packages/contentstack-seed/package.json @@ -5,7 +5,7 @@ "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { - "@contentstack/cli-cm-import": "~1.13.2", + "@contentstack/cli-cm-import": "~1.13.3", "@contentstack/cli-command": "~1.2.16", "@contentstack/cli-utilities": "~1.5.11", "inquirer": "8.2.4", diff --git a/packages/contentstack/README.md b/packages/contentstack/README.md index 05d029fec7..0da4df967a 100644 --- a/packages/contentstack/README.md +++ b/packages/contentstack/README.md @@ -2332,6 +2332,7 @@ USAGE [--destination-stack-api-key ] [--import-webhook-status disable|current] FLAGS + -c, --config= Path for the external configuration -n, --stack-name= Name for the new stack to store the cloned content. -y, --yes [Optional] Override marketplace prompts --destination-management-token-alias= Source API key of the target stack token alias. @@ -2483,6 +2484,7 @@ USAGE [--destination-stack-api-key ] [--import-webhook-status disable|current] FLAGS + -c, --config= Path for the external configuration -n, --stack-name= Name for the new stack to store the cloned content. -y, --yes [Optional] Override marketplace prompts --destination-management-token-alias= Source API key of the target stack token alias. diff --git a/packages/contentstack/package.json b/packages/contentstack/package.json index 0ce39a0d37..fc9e6bd59c 100755 --- a/packages/contentstack/package.json +++ b/packages/contentstack/package.json @@ -27,10 +27,10 @@ "@contentstack/cli-cm-bootstrap": "~1.7.1", "@contentstack/cli-cm-branches": "~1.0.22", "@contentstack/cli-cm-bulk-publish": "~1.4.0", - "@contentstack/cli-cm-clone": "~1.9.0", + "@contentstack/cli-cm-clone": "~1.10.0", "@contentstack/cli-cm-export": "~1.10.4", "@contentstack/cli-cm-export-to-csv": "~1.6.2", - "@contentstack/cli-cm-import": "~1.13.2", + "@contentstack/cli-cm-import": "~1.13.3", "@contentstack/cli-cm-migrate-rte": "~1.4.15", "@contentstack/cli-cm-seed": "~1.7.1", "@contentstack/cli-command": "~1.2.17", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d08035c340..9cfe1c5dab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,10 +15,10 @@ importers: '@contentstack/cli-cm-bootstrap': ~1.7.1 '@contentstack/cli-cm-branches': ~1.0.22 '@contentstack/cli-cm-bulk-publish': ~1.4.0 - '@contentstack/cli-cm-clone': ~1.9.0 + '@contentstack/cli-cm-clone': ~1.10.0 '@contentstack/cli-cm-export': ~1.10.4 '@contentstack/cli-cm-export-to-csv': ~1.6.2 - '@contentstack/cli-cm-import': ~1.13.2 + '@contentstack/cli-cm-import': ~1.13.3 '@contentstack/cli-cm-migrate-rte': ~1.4.15 '@contentstack/cli-cm-seed': ~1.7.1 '@contentstack/cli-command': ~1.2.17 @@ -424,7 +424,7 @@ importers: specifiers: '@colors/colors': ^1.5.0 '@contentstack/cli-cm-export': ~1.10.4 - '@contentstack/cli-cm-import': ~1.13.2 + '@contentstack/cli-cm-import': ~1.13.3 '@contentstack/cli-command': ~1.2.16 '@contentstack/cli-utilities': ~1.5.11 '@oclif/test': ^1.2.7 @@ -438,6 +438,7 @@ importers: globby: ^10.0.2 inquirer: 8.2.4 jest: ^29.4.2 + merge: ^2.1.1 mocha: ^10.0.0 nyc: ^15.1.0 oclif: ^3.8.1 @@ -457,6 +458,7 @@ importers: child_process: 1.0.2 fancy-test: 1.4.10 inquirer: 8.2.4 + merge: 2.1.1 ora: 5.4.1 prompt: 1.3.0 rimraf: 3.0.2 @@ -986,7 +988,7 @@ importers: packages/contentstack-seed: specifiers: - '@contentstack/cli-cm-import': ~1.13.2 + '@contentstack/cli-cm-import': ~1.13.3 '@contentstack/cli-command': ~1.2.16 '@contentstack/cli-utilities': ~1.5.11 '@oclif/plugin-help': ^5.1.19 @@ -6444,7 +6446,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.13.2_sjjl3gun7puonkp27uqtyjm5b4 + '@typescript-eslint/parser': 6.13.2_7hj7rehet5x3fvq7nqub5sammm debug: 3.2.7 eslint: 8.55.0 eslint-import-resolver-node: 0.3.9 @@ -6474,7 +6476,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.13.2_sjjl3gun7puonkp27uqtyjm5b4 + '@typescript-eslint/parser': 6.13.2_7hj7rehet5x3fvq7nqub5sammm debug: 3.2.7 eslint: 8.55.0 eslint-import-resolver-typescript: 3.6.1_hdscurta55xxypqxbdhu44qa6e @@ -6579,7 +6581,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.13.2_sjjl3gun7puonkp27uqtyjm5b4 + '@typescript-eslint/parser': 6.13.2_7hj7rehet5x3fvq7nqub5sammm array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2