in experimental/generation/generator/packages/library/src/dialogGenerator.ts [418:558]
async function processTemplate(
templateName: string,
templateDirs: string[],
transforms: Transform[],
globalTransforms: Transform[],
outDir: string,
scope: any,
force: boolean,
feedback: Feedback,
ignorable: boolean): Promise<string> {
let outPath = ''
const oldDir = process.cwd()
try {
const ref = existingRef(templateName, scope.templates)
if (ref) {
// Simple file already existed
feedback(FeedbackType.debug, `Reusing ${templateName}`)
outPath = ppath.join(outDir, ref.relative)
} else {
const foundTemplate = await findTemplate(templateName, templateDirs)
if (foundTemplate !== undefined) {
const lgTemplate: lg.Templates | undefined = foundTemplate instanceof lg.Templates ? foundTemplate as lg.Templates : undefined
const plainTemplate: Plain | undefined = !lgTemplate ? foundTemplate as Plain : undefined
// Ignore templates that are defined, but are empty
if (plainTemplate?.source || lgTemplate?.allTemplates.some(f => f.name === 'generator')) {
// Constant file or .lg template so output
feedback(FeedbackType.debug, `Using template ${plainTemplate ? plainTemplate.source : lgTemplate?.id}`)
let filename = addPrefix(scope.prefix, templateName)
if (lgTemplate?.allTemplates.some(t => t.name === 'filename')) {
try {
filename = lgTemplate.evaluate('filename', scope) as string
} catch (e) {
throw new Error(`${templateName}: ${(e as Error).message}`)
}
} else {
// Infer name
const locale = filename.includes(scope.locale) ? `${scope.locale}/` : ''
filename = `${assetDirectory(ppath.extname(filename))}${locale}${scope.property ?? 'form'}/${ppath.basename(filename)}`
}
outPath = ppath.join(outDir, filename)
const ref = addFileRef(outPath, outDir, scope.prefix, scope.templates)
if (ref) {
// This is a new file
if (force || !await fs.pathExists(outPath)) {
feedback(FeedbackType.info, `Generating ${outPath}`)
// Add prefix to constant imports
let result = plainTemplate ? addPrefixToImports(plainTemplate.template, scope) : undefined
if (lgTemplate) {
process.chdir(ppath.dirname(lgTemplate.allTemplates[0].sourceRange.source))
result = lgTemplate.evaluate('generator', scope) as string
process.chdir(oldDir)
if (Array.isArray(result)) {
result = result.join(os.EOL)
}
}
// See if generated file has been overridden in templates
const existing = await findTemplate(filename, templateDirs) as Plain
if (existing && existing.source.endsWith(ppath.normalize(filename))) {
feedback(FeedbackType.info, ` Overridden by ${existing.source}`)
result = existing.template
}
// Ignore empty templates
if (result) {
if (transforms.length > 0 || globalTransforms.length > 0) {
// Apply transforms
let body = result
let converted = false
try {
body = JSON.parse(result)
converted = true
} catch (e) {
}
for (const transform of [...transforms, ...globalTransforms]) {
const newBody = transform.template.evaluate(transform.name, {...scope, ref, body})
if (!compareObjects(newBody, body)) {
feedback(FeedbackType.debug, `${transform.name} changed ${outPath}`)
body = newBody
}
}
result = converted ? stringify(body) : body
}
const resultString = result as string
if (resultString.includes('**MISSING**')) {
feedback(FeedbackType.error, `${outPath} has **MISSING** data`)
} else {
const match = resultString.match(/\*\*([^0-9\s]+)[0-9]+\*\*/)
if (match) {
feedback(FeedbackType.warning, `Replace **${match[1]}<N>** with values in ${outPath}`)
}
}
await writeFile(outPath, resultString, feedback)
scope.templates[ref.extension].push(ref)
}
} else {
feedback(FeedbackType.warning, `Skipping already existing ${outPath}`)
}
}
} else if (lgTemplate) {
// Pick up # transforms
if (lgTemplate.allTemplates.some(f => f.name == 'transforms')) {
let newTransforms = lgTemplate.evaluate('transforms', scope)
if (!Array.isArray(newTransforms)) {
newTransforms = [newTransforms]
}
for (const transform of newTransforms) {
feedback(FeedbackType.debug, `Adding transform ${transform}`)
transforms.push({name: transform, template: lgTemplate})
}
}
// Expand # generators
if (lgTemplate.allTemplates.some(f => f.name === 'generators')) {
feedback(FeedbackType.debug, `Expanding template ${lgTemplate.id}`)
let generated = lgTemplate.evaluate('generators', scope)
if (!Array.isArray(generated)) {
generated = [generated]
}
for (const generate of generated as any as string[]) {
feedback(FeedbackType.debug, ` ${generate}`)
}
for (const generate of generated as any as string[]) {
await processTemplate(generate, templateDirs, transforms, globalTransforms, outDir, scope, force, feedback, false)
}
}
}
} else if (!ignorable) {
feedback(FeedbackType.error, `Missing template ${templateName}`)
}
}
} catch (e) {
feedback(FeedbackType.error, (e as Error).message)
} finally {
process.chdir(oldDir)
}
return outPath
}