diff --git a/packages/create-gen-app/__tests__/create-gen.test.ts b/packages/create-gen-app/__tests__/create-gen.test.ts index 6429471..06a3fa1 100644 --- a/packages/create-gen-app/__tests__/create-gen.test.ts +++ b/packages/create-gen-app/__tests__/create-gen.test.ts @@ -18,6 +18,7 @@ jest.mock('inquirerer', () => { prompt: jest.fn().mockResolvedValue({}), }; }), + registerDefaultResolver: jest.fn(), }; }); diff --git a/packages/create-gen-app/src/index.ts b/packages/create-gen-app/src/index.ts index 156b75c..e725b16 100644 --- a/packages/create-gen-app/src/index.ts +++ b/packages/create-gen-app/src/index.ts @@ -1,11 +1,18 @@ import * as fs from 'fs'; import * as path from 'path'; +import { registerDefaultResolver } from 'inquirerer'; + import { extractVariables } from './template/extract'; import { promptUser } from './template/prompt'; import { replaceVariables } from './template/replace'; +import { listSupportedLicenses } from './licenses'; import { CreateGenOptions } from './types'; +// Register the 'licenses' resolver for optionsFrom support +// This allows boilerplate templates to use: "optionsFrom": "licenses" +registerDefaultResolver('licenses', () => listSupportedLicenses()); + // Export new modular classes export * from './cache/cache-manager'; export * from './cache/types'; diff --git a/packages/inquirerer/src/prompt.ts b/packages/inquirerer/src/prompt.ts index c335956..7d85e7a 100644 --- a/packages/inquirerer/src/prompt.ts +++ b/packages/inquirerer/src/prompt.ts @@ -469,6 +469,9 @@ export class Inquirerer { // Resolve dynamic defaults before processing questions await this.resolveDynamicDefaults(questions); + // Resolve dynamic options before processing questions + await this.resolveOptionsFrom(questions); + // Resolve setFrom values - these bypass prompting entirely await this.resolveSetValues(questions, obj); @@ -609,6 +612,22 @@ export class Inquirerer { } } + /** + * Resolves optionsFrom values for all questions that have optionsFrom specified. + * Updates the question.options property with the resolved array. + */ + private async resolveOptionsFrom(questions: Question[]): Promise { + for (const question of questions) { + if ('optionsFrom' in question && question.optionsFrom) { + const resolved = await this.resolverRegistry.resolve(question.optionsFrom); + if (resolved !== undefined && Array.isArray(resolved)) { + // Update question.options with resolved array + (question as any).options = resolved; + } + } + } + } + private applyDefaultValues(questions: Question[], obj: any): void { questions.forEach(question => { if ('default' in question) { @@ -1192,4 +1211,4 @@ export class Inquirerer { this.keypress.destroy(); } } -} \ No newline at end of file +} diff --git a/packages/inquirerer/src/question/types.ts b/packages/inquirerer/src/question/types.ts index a37b914..350d76b 100644 --- a/packages/inquirerer/src/question/types.ts +++ b/packages/inquirerer/src/question/types.ts @@ -20,6 +20,7 @@ export interface BaseQuestion { default?: any; defaultFrom?: string; setFrom?: string; + optionsFrom?: string; useDefault?: boolean; required?: boolean; message?: string; @@ -69,4 +70,4 @@ export interface BaseQuestion { default?: number; } - export type Question = ConfirmQuestion | ListQuestion | AutocompleteQuestion | CheckboxQuestion | TextQuestion | NumberQuestion; \ No newline at end of file + export type Question = ConfirmQuestion | ListQuestion | AutocompleteQuestion | CheckboxQuestion | TextQuestion | NumberQuestion;