UNPKG

@constructor-io/constructorio-connect-cli

Version:

CLI tool to enable users to interface with the Constructor Connect Ecosystem

207 lines (206 loc) • 9.83 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path = __importStar(require("path")); const child_process_1 = require("child_process"); const prompts_1 = require("@inquirer/prompts"); const fs_extra_1 = __importDefault(require("fs-extra")); const replace_in_file_1 = __importDefault(require("replace-in-file")); const core_1 = require("@oclif/core"); const kleur_1 = __importDefault(require("kleur")); const get_connections_request_1 = require("../http/get-connections-request"); const build_config_file_1 = require("../helpers/build-config-file"); const ux_action_1 = require("../helpers/ux-action"); const get_connect_token_1 = require("../customer/get-connect-token"); const render_tip_1 = require("../rendering/render-tip"); const is_git_repo_initialized_1 = require("../helpers/is-git-repo-initialized"); const is_git_installed_1 = require("../helpers/is-git-installed"); const BOILERPLATE_REPO_PATH = "../../boilerplate-repo"; /** * This ensures that the path will be fixed in Windows, since we're using `path.join()` to build the path. * @see https://github.com/adamreisnz/replace-in-file/pull/169 */ const globConfig = { windowsPathsNoEscape: true, }; class Init extends core_1.Command { static description = "Bootstrap a new Constructor.io Connect CLI repository."; static examples = [ "<%= config.bin %> <%= command.id %>", "<%= config.bin %> <%= command.id %> new-repo-name", ]; static args = { name: core_1.Args.string({ description: "name of the new folder", required: true, }), }; async run() { const { args } = await this.parse(Init); const repoPath = path.join(process.cwd(), args.name); this.log([`šŸ‘‹ Welcome to the ${kleur_1.default.bold("Constructor.io Connect CLI")}!\n`].join("\n")); const hasGit = (0, is_git_installed_1.isGitInstalled)(); if (!hasGit) { this.log(kleur_1.default.red("āš ļø Git is not installed"), kleur_1.default.bold("Please install Git and try again."), kleur_1.default.dim("\nYou can download it from:"), kleur_1.default.blue("https://git-scm.com/downloads")); return; } const connectAuthToken = await (0, get_connect_token_1.getConnectToken)(false); const newDirExists = fs_extra_1.default.existsSync(repoPath); if (!newDirExists) { await this.createRepo({ repoName: args.name, connectAuthToken, repoPath, }); } else { await this.updateRepo({ repoName: args.name, connectAuthToken, repoPath, }); } } async createRepo(args) { await this.generateRepositoryFiles(args); fs_extra_1.default.appendFileSync(path.join(args.repoPath, ".env"), `CONNECT_AUTH_TOKEN=${args.connectAuthToken}\n`); if (!(0, is_git_repo_initialized_1.isGitRepoInitialized)()) { this.initGitRepoAndCommit(args); } else { this.log(`\nšŸ’” Git repository already exists at this path, skipping initialization.`); } this.printSuccessfulInitMessage(args.repoName); } initGitRepoAndCommit(args) { (0, child_process_1.execSync)(`git init ${args.repoPath} --initial-branch=main`); (0, ux_action_1.uxAction)("šŸ Finishing installation", () => { (0, child_process_1.execSync)(`(cd ${args.repoPath} && git add . && git commit -m "Initialize new Constructor.io Connect CLI repository")`); })(); } async updateRepo(args) { this.log(`\nYou are trying to initialize a new repo that already exists.`); const shouldRefresh = await (0, prompts_1.confirm)({ message: "Do you want to regenerate the base repository files?", }); if (shouldRefresh) { // Remove node_modules to avoid any file operation conflicts fs_extra_1.default.removeSync(path.join(args.repoPath, "node_modules")); await this.generateRepositoryFiles(args); this.printSuccessfulInitMessage(args.repoName); return; } this.log(`\nšŸ™… Constructor.io Connect CLI repository not updated! šŸ™… `); } async generateRepositoryFiles(args) { const connections = await (0, get_connections_request_1.getConnections)({ showLogs: true }); const shouldCreateMappingTemplates = connections.some((connection) => connection.partner === "omni"); const connectionsDict = (0, build_config_file_1.buildConnectionsDictFromList)(connections); const config = (0, build_config_file_1.buildConfigFromConnections)(connections, shouldCreateMappingTemplates); (0, ux_action_1.uxAction)("šŸš€ Creating new Constructor.io Connect CLI repository", () => { Init.createNewRepository(args.repoPath, shouldCreateMappingTemplates); Init.replacePackageName(args.repoName, args.repoPath); })(); (0, ux_action_1.uxAction)("šŸ“¦ Installing dependencies", () => { (0, child_process_1.execSync)(`(cd ${args.repoPath} && npm install --loglevel=error)`); // Install the CLI package in the new repo to get the latest version (0, child_process_1.execSync)(`(cd ${args.repoPath} && npm install @constructor-io/constructorio-connect-cli --loglevel=error)`); })(); Init.replaceConfigValues(config, connectionsDict, args.repoPath); } static createNewRepository(newDir, shouldCreateMappingTemplates) { const repoDir = path.join(__dirname, BOILERPLATE_REPO_PATH); fs_extra_1.default.copySync(repoDir, newDir, { filter: (file) => { if (shouldCreateMappingTemplates) { return true; } // Exclude mapping templates if the user doesn't have an Omni connector connection return !file.includes("mapping"); }, }); } static replacePackageName(name, repoPath) { const packageJsonPath = path.join(repoPath, "package.json"); replace_in_file_1.default.sync({ files: packageJsonPath, from: "{{REPLACE_REPO_NAME}}", to: name, glob: globConfig, }); } static replaceConfigValues(config, connections, repoPath) { replace_in_file_1.default.replaceInFileSync({ files: path.join(repoPath, "connectrc.js"), from: '"{{REPLACE_CONFIG}}"', to: (0, build_config_file_1.buildConfigString)(config, connections), glob: globConfig, }); replace_in_file_1.default.replaceInFileSync({ files: path.join(repoPath, "connectrc.js"), from: '"{{REPLACE_CONNECTIONS}}"', to: JSON.stringify(connections, null, 2), glob: globConfig, }); // Run `lint:fix` to ensure the generated files are properly linted & formatted (0, child_process_1.execSync)(`(cd ${repoPath} && npm run lint:fix)`); } printSuccessfulInitMessage(repoName) { this.log(kleur_1.default.bold([ "\n", `šŸŽ‰ Constructor.io Connect CLI repository initialized at ./${repoName}! šŸŽ‰`, `\n`, ].join(""))); (0, render_tip_1.renderTip)([ `You can already execute templates using the ${kleur_1.default.bold("execute")} command.`, "The repo ships with some example templates and fixtures already mapped to your connections.", "You can execute those templates to see the result data and modify them to your needs.", ]); (0, render_tip_1.renderTip)([ `If you don't intend to use a certain template (e.g. ${kleur_1.default.bold("item_groups.jsonata")}),`, `you can just delete the file and remove the mention from ${kleur_1.default.bold("connectrc.js")}.`, ]); (0, render_tip_1.renderTip)([ `Check out the ${kleur_1.default.bold("README")} in the new repository for more information on how to get started`, "with developing templates for the Constructor Connect platform.", `Link: ${repoName}/README.md`, ]); } } exports.default = Init;