diff --git a/packages/cli/src/lib/new/createNewPackage.ts b/packages/cli/src/lib/new/createNewPackage.ts index b5cc85f1ec..19208f4c6b 100644 --- a/packages/cli/src/lib/new/createNewPackage.ts +++ b/packages/cli/src/lib/new/createNewPackage.ts @@ -23,7 +23,6 @@ import { paths } from '../paths'; import { Task } from '../tasks'; import { addCodeownersEntry, getCodeownersFilePath } from '../codeowners'; -import { verifyTemplate } from './templateSelector'; import { promptOptions } from './prompts'; import { populateOptions, createDirName, resolvePackageName } from './utils'; import { runAdditionalActions } from './additionalActions'; @@ -47,12 +46,11 @@ export type CreateNewPackageOptions = { export async function createNewPackage(options: CreateNewPackageOptions) { const newConfig = await loadNewConfig(); - const template = verifyTemplate( - await NewTemplateLoader.selectTemplateInteractively( - newConfig, - options.preselectedTemplateId, - ), + const selectedTemplate = await NewTemplateLoader.selectTemplateInteractively( + newConfig, + options.preselectedTemplateId, ); + const template = await NewTemplateLoader.loadTemplate(selectedTemplate); const codeOwnersFilePath = await getCodeownersFilePath(paths.targetRoot); diff --git a/packages/cli/src/lib/new/loader/NewTemplateLoader.ts b/packages/cli/src/lib/new/loader/NewTemplateLoader.ts index 27a250ed84..c4bb873971 100644 --- a/packages/cli/src/lib/new/loader/NewTemplateLoader.ts +++ b/packages/cli/src/lib/new/loader/NewTemplateLoader.ts @@ -14,8 +14,41 @@ * limitations under the License. */ +import { z } from 'zod'; +import fs from 'fs-extra'; import inquirer from 'inquirer'; +import { dirname } from 'node:path'; +import { parse as parseYaml } from 'yaml'; +import { paths } from '../../paths'; import { NewConfig, NewTemplatePointer } from '../config/types'; +import { Template } from '../types'; +import { ForwardedError } from '@backstage/errors'; +import { fromZodError } from 'zod-validation-error'; + +const templateDefinitionSchema = z + .object({ + description: z.string().optional(), + template: z.string(), + targetPath: z.string(), + plugin: z.boolean().optional(), + backendModulePrefix: z.boolean().optional(), + suffix: z.string().optional(), + prompts: z + .array( + z.union([ + z.string(), + z.object({ + id: z.string(), + prompt: z.string(), + validate: z.string().optional(), + default: z.union([z.string(), z.boolean(), z.number()]).optional(), + }), + ]), + ) + .optional(), + additionalActions: z.array(z.string()).optional(), + }) + .strict(); export class NewTemplateLoader { static async selectTemplateInteractively( @@ -49,4 +82,40 @@ export class NewTemplateLoader { } return template; } + + static async loadTemplate({ + id, + target, + }: NewTemplatePointer): Promise