UNPKG

@strapi/typescript-utils

Version:

Typescript support for Strapi

123 lines (94 loc) 3.86 kB
'use strict'; const path = require('path'); const chalk = require('chalk'); const { TYPES_ROOT_DIR, GENERATED_OUT_DIR } = require('./constants'); const { saveDefinitionToFileSystem, createLogger, timer } = require('./utils'); const generateContentTypesDefinitions = require('./content-types'); const generateComponentsDefinitions = require('./components'); const GENERATORS = { contentTypes: generateContentTypesDefinitions, components: generateComponentsDefinitions, }; /** * @typedef GenerateConfig * * @property {object} strapi * @property {boolean} pwd * @property {object} [artifacts] * @property {boolean} [artifacts.contentTypes] * @property {boolean} [artifacts.components] * @property {boolean} [artifacts.services] * @property {boolean} [artifacts.controllers] * @property {boolean} [artifacts.policies] * @property {boolean} [artifacts.middlewares] * @property {object} [logger] * @property {boolean} [logger.silent] * @property {boolean} [logger.debug] * @property {boolean} [logger.verbose] */ /** * Generate types definitions based on the given configuration * * @param {GenerateConfig} [config] */ const generate = async (config = {}) => { const { pwd, rootDir = TYPES_ROOT_DIR, strapi, artifacts = {}, logger: loggerConfig } = config; const reports = {}; const logger = createLogger(loggerConfig); const psTimer = timer().start(); const registryPwd = path.join(pwd, rootDir, GENERATED_OUT_DIR); const generatorConfig = { strapi, pwd: registryPwd, logger }; const returnWithMessage = () => { const nbWarnings = chalk.yellow(`${logger.warnings} warning(s)`); const nbErrors = chalk.red(`${logger.errors} error(s)`); const status = logger.errors > 0 ? chalk.red('errored') : chalk.green('completed successfully'); psTimer.end(); logger.info(`The task ${status} with ${nbWarnings} and ${nbErrors} in ${psTimer.duration}s.`); return reports; }; const enabledArtifacts = Object.keys(artifacts).filter((p) => artifacts[p] === true); logger.info('Starting the type generation process'); logger.debug(`Enabled artifacts: ${enabledArtifacts.join(', ')}`); for (const artifact of enabledArtifacts) { const boldArtifact = chalk.bold(artifact); // used for log messages logger.info(`Generating types for ${boldArtifact}`); if (artifact in GENERATORS) { const generator = GENERATORS[artifact]; try { const artifactGenTimer = timer().start(); reports[artifact] = await generator(generatorConfig); artifactGenTimer.end(); logger.debug(`Generated ${boldArtifact} in ${artifactGenTimer.duration}s`); } catch (e) { logger.error( `Failed to generate types for ${boldArtifact}: ${e.message ?? e.toString()}. Exiting` ); return returnWithMessage(); } } else { logger.warn(`The types generator for ${boldArtifact} is not implemented, skipping`); } } for (const artifact of Object.keys(reports)) { const boldArtifact = chalk.bold(artifact); // used for log messages const artifactFsTimer = timer().start(); const report = reports[artifact]; const filename = `${artifact}.d.ts`; try { const outPath = await saveDefinitionToFileSystem(registryPwd, filename, report.output); const relativeOutPath = path.relative(process.cwd(), outPath); artifactFsTimer.end(); logger.info(`Saved ${boldArtifact} types in ${chalk.bold(relativeOutPath)}`); logger.debug(`Saved ${boldArtifact} in ${artifactFsTimer.duration}s`); } catch (e) { logger.error( `An error occurred while saving ${boldArtifact} types to the filesystem: ${ e.message ?? e.toString() }. Exiting` ); return returnWithMessage(); } } return returnWithMessage(); }; module.exports = { generate };