import { resolve, basename } from 'path'; import { mergeFiles } from './io'; import { getAssetsSource } from './assets'; import { configure, ExecutionDetails } from './parent'; import { getFileFromTemplate, normalizeData } from './template'; import { getLanguageExtension, getPackageJsonWithSource, getPlugins } from './utils'; import type { PiralTemplateArgs, PiletTemplateArgs, TemplateFile, PiletTemplateSource, PiralTemplateSource, } from './types'; const mergePackageJson = [/package\.json$/]; export interface GetAllSources { (projectRoot: string, args: TArgs, details: ExecutionDetails): Array; } export function createPiletTemplateFactory( templateRoot: string, getAllSources: GetAllSources, PiletTemplateSource>, defaultArgs: Partial = {}, deepMerged: Array = mergePackageJson, ) { const sourceDir = resolve(templateRoot, 'templates'); return async ( projectRoot: string, args: PiletTemplateArgs, details: ExecutionDetails, ): Promise> => { configure(templateRoot, details); const allArgs = { ...defaultArgs, ...args }; const { language = 'ts', sourceName, src = '/src', plugins = getPlugins(projectRoot, sourceName), mocks = '/mocks', } = allArgs; const allSources = getAllSources(projectRoot, allArgs, details); const data = normalizeData({ ...allArgs, language, plugins, projectRoot, root: '.', piletName: basename(projectRoot), sourceName, extension: getLanguageExtension(language), src, mocks, }); const defaultSources = [ getAssetsSource(), getPackageJsonWithSource(data.projectRoot, data.src, `index${data.extension}`), ]; const sources = [...allSources, ...defaultSources].filter((m) => m.languages.includes(language)); const files = await Promise.all(sources.map((source) => getFileFromTemplate(sourceDir, source, data))); return mergeFiles(files, deepMerged); }; } export function createPiralTemplateFactory( templateRoot: string, getAllSources: GetAllSources, PiralTemplateSource>, defaultArgs: Partial = {}, deepMerged: Array = mergePackageJson, ) { const sourceDir = resolve(templateRoot, 'templates'); return async ( projectRoot: string, args: PiralTemplateArgs, details: ExecutionDetails, ): Promise> => { configure(templateRoot, details); const allArgs = { ...defaultArgs, ...args }; const { language = 'ts', packageName = 'piral', mocks = '/mocks', src = '/src', title = 'My Piral Instance', reactVersion = 17, plugins = [], } = allArgs; const allSources = getAllSources(projectRoot, allArgs, details); const data = normalizeData({ ...allArgs, title, language, plugins, projectRoot, root: '.', reactVersion, packageName, extension: getLanguageExtension(language, packageName !== 'piral-base'), src, mocks, }); const defaultSources = [getAssetsSource()]; const customSources = allSources.filter((m) => m.frameworks.includes(packageName)); const sources = [...customSources, ...defaultSources].filter((m) => m.languages.includes(language)); const files = await Promise.all(sources.map((source) => getFileFromTemplate(sourceDir, source, data))); return mergeFiles(files, deepMerged); }; }