UNPKG

@coveo/create-atomic

Version:
209 lines (206 loc) • 9.21 kB
import { spawn } from 'node:child_process'; import { writeFileSync } from 'node:fs'; import { join } from 'node:path'; import { createPlatformClient } from './client.js'; import { defaultPageManifest } from './default/default-page.js'; import { fetchPageManifest } from './fetch-page.js'; import { listSearchPagesOptions } from './list-pages.js'; import { getPackageManager } from './utils.js'; export default function (plop) { const currentPath = process.cwd(); let platformClientInstance; function initPlatformClient(answers) { if (platformClientInstance) { return platformClientInstance; } platformClientInstance = createPlatformClient(answers['platform-url'], answers['org-id'], answers['api-key']); return platformClientInstance; } async function createSearchApiKey(name, searchHub, platformClient) { return await platformClient.apiKey.create({ displayName: `cli-${name}`, description: 'Generated by the Coveo CLI', ...(searchHub && { additionalConfiguration: { search: { enforcedQueryPipelineConfiguration: { searchHub, }, }, }, }), }, { apiKeyTemplateId: 'AnonymousSearch', }); } plop.setHelper('inc', (value) => parseInt(value) + 1); plop.setGenerator('@coveo/atomic', { description: 'A Coveo Atomic Generator', prompts: [ { type: 'input', name: 'project', message: 'Name of the project', validate: (input) => { // Taken from http://json.schemastore.org/package const npmPackageRegex = /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*/; if (!npmPackageRegex.test(input)) { return 'Project name is invalid, please follow the guidelines: https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name)'; } return true; }, }, { type: 'input', name: 'platform-url', message: 'The Plaform URL to use. See https://docs.coveo.com/en/2976/coveo-solutions/deployment-regions-and-strategies', default: 'https://platform.cloud.coveo.com', }, { type: 'input', name: 'platform-environment', message: 'The Plaform Environment to use. See https://docs.coveo.com/en/mcc80216', default: 'prod', }, { type: 'input', name: 'org-id', message: 'The unique identifier of the organization in which to generate a search token. See https://docs.coveo.com/en/148/manage-an-organization/retrieve-the-organization-id', }, { type: 'input', name: 'api-key', message: 'An API key granting the impersonate privilege in your organization. The API key should have the impersonate privilege. See https://docs.coveo.com/en/1718/manage-an-organization/manage-api-keys#add-an-api-key', }, { type: 'input', name: 'user', message: 'The name of the security identity to impersonate, e.g. "alicesmith@example.com". See https://docs.coveo.com/en/56/#name-string-required.', }, { type: 'input', name: 'search-hub', message: 'The search hub to use', }, { // Custom type necessary to allow bypassing async choices type: 'customList', name: 'page-id', default: undefined, loop: false, pageSize: 10, message: 'Use an existing hosted search page as a template, or start from scratch?', choices: async (answers) => [ { value: undefined, name: 'Start from scratch' }, { type: 'separator' }, ...(await listSearchPagesOptions(initPlatformClient(answers))), ], validate: async (input, answers) => { try { return !!(await fetchPageManifest(initPlatformClient(answers), input, 'unknown')); } catch (_) { return `The search page with the id "${input}" does not exist.`; } }, }, ], actions: () => [ async function download(data) { const answers = data; if (answers['page-id']) { answers.page = await fetchPageManifest(initPlatformClient(answers), answers['page-id'], 'unknown'); return `Hosted search page named "${answers.page.config.name}" has been downloaded`; } answers.page = defaultPageManifest; return 'Using the default search page template.'; }, async function generateSearchApiKey(data) { const answers = data; const platformClient = initPlatformClient(answers); const apiKeyModel = await createSearchApiKey(answers.project, answers['search-hub'], platformClient); answers['api-key'] = apiKeyModel.value; return 'A search API key has been created for this project'; }, { type: 'add', path: `${currentPath}/{{project}}/.env`, templateFile: '../template/.env.hbs', }, { type: 'add', path: `${currentPath}/{{project}}/.gitignore`, templateFile: '../template/.gitignore.hbs', }, { type: 'add', path: `${currentPath}/{{project}}/package.json`, templateFile: '../template/package.json.hbs', }, { type: 'addMany', destination: `${currentPath}/{{project}}/`, base: '../template', templateFiles: [ '../template/src/**', '../template/scripts/*', '../template/.env.example', '../template/tsconfig.json', '../template/stencil.config.ts', '../template/README.md', '../template/coveo.deploy.json', '../template/deployment.esbuild.mjs', ], }, function generateTemplates(data) { const { project, page } = data; page.results.templates.forEach((resultTemplate, index) => { const filePath = join(currentPath, project, 'src', 'components', 'results-manager', `template-${index + 1}.html`); writeFileSync(filePath, plop.renderString('{{{markup}}}', resultTemplate)); }); return `${page.results.templates.length} result template(s) generated`; }, function installPackagesPrompt() { return 'Installing packages...'; }, function installPackages(data) { return new Promise((resolve, reject) => { const { project } = data; const installProcess = spawn(getPackageManager(), ['install'], { stdio: ['ignore', 'pipe', 'pipe'], shell: process.platform === 'win32' ? 'powershell' : undefined, cwd: join(currentPath, project), }); let output = ''; installProcess.stdout.on('data', (chunk) => { output += chunk.toString(); }); installProcess.stderr.on('data', (chunk) => { output += chunk.toString(); }); installProcess.on('close', (code, signal) => { if (code === 0) { resolve('Installation complete'); } else { const codeMsg = `Installation exited with code "${code}"`; const signalMsg = signal ? ` & signal:${signal} ` : ''; reject(`${codeMsg}${signalMsg} ${output}`); } }); }); }, function getStarted(data) { const { project } = data; return ` To get started: > cd ${project} > npm start To share your site with the world, make sure you are logged in to the Coveo CLI and: > npm run deploy Happy hacking! `; }, ], }); }