diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 09d5f9b..a18285e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - node: [14, 16] + node: [18, 20, 22] os: [ubuntu-latest] steps: diff --git a/cli.js b/cli.js index c192490..ee1fd48 100755 --- a/cli.js +++ b/cli.js @@ -23,7 +23,7 @@ const parseArgs = (cmd) => { const directory = cmd.path || parent.path; return { ...cmd, - configFile: cmd.configFile, + configFile: cmd.config, environment: cmd.env || parent.env, directory: directory ? path.resolve(directory) : undefined, sourceEnvironmentId: cmd.sourceEnvironmentId || parent.sourceEnvironmentId, @@ -107,7 +107,7 @@ program .action( actionRunner(async (cmd) => { const config = await getConfig(parseArgs(cmd || {})); - const verified = await askMissing(config); + const verified = await askMissing(config, ['accessToken', 'spaceId', 'environmentId', 'directory']); await fetchMigration({ ...verified, contentType: cmd.contentType }); }) ); @@ -124,7 +124,7 @@ program .action( actionRunner(async (cmd) => { const config = await getConfig(parseArgs(cmd || {})); - const verified = await askMissing(config); + const verified = await askMissing(config, ['accessToken', 'spaceId', 'environmentId', 'directory']); await createMigration(verified); }) ); diff --git a/lib/config.js b/lib/config.js index 74360fd..9e40130 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,5 +1,6 @@ const path = require('path'); const inquirer = require('inquirer'); +const { createJiti } = require('jiti'); const mergeOptions = require('merge-options').bind({ ignoreUndefined: true }); const { cosmiconfig } = require('cosmiconfig'); @@ -11,6 +12,8 @@ const STORAGE_CONTENT = 'content'; const STATE_SUCCESS = 'success'; const STATE_FAILURE = 'failure'; +const jiti = createJiti(__filename); + /** * Get configuration * @param {Object} args @@ -26,7 +29,7 @@ const getConfig = async (args) => { const environmentOptions = { spaceId: process.env.CONTENTFUL_SPACE_ID, environmentId: process.env.CONTENTFUL_ENVIRONMENT_ID, - accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN, + managementToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN, host: process.env.CONTENTFUL_HOST, }; @@ -40,7 +43,7 @@ const getConfig = async (args) => { const { managementToken, activeSpaceId, activeEnvironmentId, host } = config || {}; contentfulCliOptions = { spaceId: activeSpaceId, - accessToken: managementToken, + managementToken: managementToken, host, }; } @@ -52,7 +55,7 @@ const getConfig = async (args) => { try { // get configuration from migrations rc file const explorer = cosmiconfig('migrations'); - const explorerResult = args.config ? await explorer.load(args.config) : await explorer.search(); + const explorerResult = await explorer.search(); if (explorerResult !== null) { const { config, filepath } = explorerResult || {}; @@ -69,7 +72,53 @@ const getConfig = async (args) => { console.log('Error:', error.message); } - return mergeOptions(defaultOptions, contentfulCliOptions, environmentOptions, configFileOptions, args || {}); + let userConfigFileOptions = {}; + if (args.config) { + try { + let config = {}; + let filepath = ''; + if (args.config.endsWith('.js') || args.config.endsWith('.ts')) { + config = await jiti.import(path.resolve(args.config)); + filepath = jiti.esmResolve(path.resolve(args.config)); + } else { + const explorer = cosmiconfig('migrations'); + const explorerResult = await explorer.load(args.config); + config = explorerResult.config; + filepath = explorerResult.filepath; + } + if (config) { + userConfigFileOptions = { + directory: path.resolve(path.dirname(filepath || ''), args.directory || 'migrations'), + ...(config || {}), + }; + + if (userConfigFileOptions.directory && !path.isAbsolute(userConfigFileOptions.directory)) { + userConfigFileOptions.directory = path.resolve(path.dirname(filepath || ''), userConfigFileOptions.directory); + } + + if (configFileOptions.directory) { + delete userConfigFileOptions.directory; + } + } + } catch (error) { + console.log('Error:', error.message); + } + } + + const result = mergeOptions( + defaultOptions, + contentfulCliOptions, + environmentOptions, + configFileOptions, + userConfigFileOptions, + args || {} + ); + + if (result.managementToken) { + result.accessToken = result.managementToken; + } + + return result; }; const getPromts = (data) => { diff --git a/package-lock.json b/package-lock.json index dfad943..0eead8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "fs-extra": "^10.1.0", "globby": "^12.0.2", "inquirer": "^8.2.0", + "jiti": "^2.4.2", "markdown-table": "^3.0.4", "merge-options": "^3.0.4", "mustache": "^4.2.0", @@ -7277,6 +7278,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/joi": { "version": "17.13.3", "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", @@ -17102,6 +17112,11 @@ } } }, + "jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==" + }, "joi": { "version": "17.13.3", "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", diff --git a/package.json b/package.json index 35c53d5..c36a718 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "author": "Ben Zörb ", "license": "MIT", "engines": { - "node": ">=14" + "node": ">=18" }, "keywords": [ "contentful", @@ -51,6 +51,7 @@ "fs-extra": "^10.1.0", "globby": "^12.0.2", "inquirer": "^8.2.0", + "jiti": "^2.4.2", "markdown-table": "^3.0.4", "merge-options": "^3.0.4", "mustache": "^4.2.0",