&
Record<`${Property}Any`, boolean>
>;
/*
* @example
* ```ts
* DerivedPropertiesWithInferenceOf<'clientFramework', 'angular', 'angular', 'no'> =
* { clientFrameworkAngular: true; clientFrameworkNo: false; clientFramework: 'angular'; clientFrameworkAny: true; }
* ```
*/
type DerivedPropertiesWithInferenceOf = Simplify<
{
[K in C as `${P}${Capitalize}`]: K extends V ? true : false;
} & Record &
Record<`${P}Any`, V extends 'no' ? false : true>
>;
/**
* ```ts
* type ExplodedConfigChoices = ExplodeDerivedPropertiesWithInference<['angular', 'no'], 'clientFramework'>;
* type ExplodedConfigChoices =
* | { clientFrameworkAngular: true; clientFrameworkNo: false; clientFramework: 'angular'; clientFrameworkAny: true; }
* | { clientFrameworkAngular: false; clientFrameworkNo: true; clientFramework: 'no'; clientFrameworkAny: true; }
* ```
*/
export type DerivedPropertiesWithInferenceUnion = ValueOf<{
[Index in Exclude]: Choices[Index] extends infer Choice
? Choice extends string
? DerivedPropertiesWithInferenceOf
: never
: never;
}>;
type CommandConfigScope = 'storage' | 'blueprint' | 'generator' | 'context' | 'none';
type ScopedConfig = {
/**
* Command configuration scope
* - `storage`: Used for storing configuration in `jhipsterConfig`.
* - `blueprint`: Used for storing blueprint-specific configurations in `blueprintConfig`.
* - `generator`: Used for generator options, will be inserted as a generator property, may conflict with existing properties.
* - `context`: Used for options that are specific to the template context, will be inserted in `context`.
* - `none`: Used for options that will be handled manually, such as options that are stored differently than they are received.
*/
readonly scope: CommandConfigScope;
};
export type CommandConfigType = typeof String | typeof Boolean | typeof Number | typeof Object | ((opt: string) => any);
export type CommandConfigDefault =
| string
| boolean
| number
| readonly string[]
| ((this: ConfigContext | void, ctx: any) => string | boolean | number | readonly string[]);
type CliSpecType = CliOptionSpec['type'] | typeof Object;
export type JHipsterChoices = readonly [...(string | JHipsterNamedChoice)[]];
export type PromptSpec = {
readonly type: 'input' | 'select' | 'confirm' | 'checkbox';
readonly message: string | ((arg: any) => string);
readonly when?: boolean | ((arg: any) => boolean);
readonly default?: any;
readonly filter?: any;
readonly transformer?: any;
readonly validate?: any;
};
type JHipsterArgumentConfig = SetOptional & Partial;
export type CliSpec = Omit, 'storage'> & {
env?: string;
/**
* Imply other options.
*/
implies?: Record;
};
export type ConfigSpec = {
readonly description?: string;
readonly choices?: JHipsterChoices;
readonly cli?: CliSpec;
readonly argument?: JHipsterArgumentConfig;
readonly internal?: { type: CommandConfigType };
readonly prompt?: PromptSpec | ((gen: ConfigContext, config: ConfigSpec) => PromptSpec);
readonly jdl?: Omit;
/**
* The callback receives the generator as input for 'generator' scope.
* The callback receives jhipsterConfigWithDefaults as input for 'storage' (default) scope.
* The callback receives blueprintStorage contents as input for 'blueprint' scope.
*
* Default value will not be applied to generator (using 'generator' scope) in initializing priority. Use cli.default instead.
* Default value will be application to templates context object (application) in loading priority.
*/
readonly default?: CommandConfigDefault;
/**
* Configure the generator according to the selected configuration.
*/
readonly configure?: (gen: ConfigContext, value: any) => void;
} & ScopedConfig;
export type JHipsterArguments = Record;
export type JHipsterArgumentsWithChoices = Record;
export type JHipsterConfig = RequireAtLeastOne<
ConfigSpec,
'argument' | 'cli' | 'prompt' | 'jdl' | 'internal'
>;
export type JHipsterConfigs = Record>;
export type JHipsterCommandDefinition = {
readonly arguments?: JHipsterArguments;
readonly configs?: JHipsterConfigs;
/**
* Import options from a generator.
* @example ['server', 'jhipster-blueprint:server']
*/
readonly import?: readonly (keyof GeneratorsByNamespace | 'base')[];
/**
* @experimental
* Compose with generator.
* @example ['server', 'jhipster-blueprint:server']
*/
readonly compose?: readonly (keyof GeneratorsByNamespace | 'base')[];
/**
* Override options from the generator been blueprinted.
*/
readonly override?: boolean;
};
/**
* A simplified version of the `JHipsterCommandDefinition` type for types parsing.
*/
type ParsableConfig = {
readonly type?: CliSpecType;
readonly cli?: {
readonly type: CliSpecType;
};
readonly choices?: JHipsterChoices;
} & ScopedConfig;
type ParsableConfigs = Record;
export type ParsableCommand = {
readonly options?: ParsableConfigs;
readonly configs?: ParsableConfigs;
};
/** Extract constructor return type, eg: Boolean, String */
type ConstructorReturn = T extends new () => infer R ? R : undefined;
type FilteredConfigScope = CommandConfigScope | undefined;
/** Filter Options/Config by scope */
type FilterScope = D extends Record<'scope', S> ? D : never;
type FilterCommandScope = {
[K in keyof D as IsNever> extends true ? never : K]: D[K];
};
/**
* @example
* ```ts
* type MergedConfigsOptions = MergeConfigsOptions<{
* configs: { clientFramework: { type: 'string'; scope: 'storage'; choices: ['angular', 'no'] } };
* options: { clientTestFramework: { type: 'string'; scope: 'storage'; choices: ['cypress', 'no'] } };
* }>
* ```
*/
type MergeConfigsOptions = Simplify<
D extends { configs: ParsableConfigs } ? { [K in keyof FilterCommandScope]: D['configs'][K] } : object
>;
type GetType =
C extends Record<'type', CliSpecType>
? C['type']
: C extends Record<'cli', Record<'type', CliSpecType>>
? C['cli']['type']
: C extends Record<'internal', Record<'type', CliSpecType>>
? C['internal']['type']
: undefined;
type WrapperToPrimitive = T extends Boolean ? boolean : T extends String ? string : T extends Number ? number : T;
type GetChoiceValue = Choice extends string
? Choice
: Choice extends { value: string }
? Choice['value']
: never;
/**
* @example
* type Normalized = NormalizeChoices<['angular', { value: 'no' }]>;
* type Normalized = ['angular', 'no'];
*/
type NormalizeChoices = {
[Index in keyof Choices]: GetChoiceValue;
};
/**
* @example
* ```ts
* type ExplodedCommandChoices = ExplodeCommandChoicesNoInference<{ clientFramework: { choices: ['angular', 'no'], scope: 'storage' }, clientTestFramework: { choices: ['cypress', 'no'], scope: 'storage' } }>
* ```
*/
type ExplodeCommandChoicesNoInference = {
[K in keyof U]: U[K] extends infer RequiredChoices
? RequiredChoices extends { choices: any }
? K extends infer StringKey
? StringKey extends string
? NormalizeChoices extends infer NormalizedChoices
? // @ts-expect-error Mapped tuple type is loose https://github.com/microsoft/TypeScript/issues/27995
Simplify>
: never
: never
: never
: never
: never;
};
type PrepareConfigsWithType = Simplify<{
-readonly [K in keyof U]?: U[K] extends Record<'choices', JHipsterChoices>
? TupleToUnion>
: WrapperToPrimitive>> extends infer T
? T extends undefined
? unknown
: T
: never;
}>;
/** Keep Options/Config filtered by choices */
type OnlyChoices = D extends { choices: JHipsterChoices } ? (C extends true ? D : never) : C extends true ? never : D;
/**
* Keep Options/Config filtered by choices
*
* @example
* ```ts
* type ConfigsWithChoice = OnlyConfigsWithChoice<{ clientFramework: { choices: ['angular', 'no'], scope: 'storage' }, clientTestFramework: { choices: ['cypress', 'no'], scope: 'storage' } }>
* ```
*/
type OnlyConfigsWithChoice = {
[K in keyof D as OnlyChoices extends never ? never : K]: D[K];
};
/**
* @example
* ```
* type Prop = ExportApplicationPropertiesFromCommand<{ configs: { clientFramework: { choices: ['angular', 'no'], scope: 'storage' }, bar: { scope: 'storage' } } }>;
* ```
*/
export type ExportApplicationPropertiesFromCommand =
MergeConfigsOptions extends infer Merged
? Merged extends ParsableConfigs
? // Add value inference to properties with choices
// ? PrepareConfigsWithType> & ValueOf>>
Simplify<
PrepareConfigsWithType> &
MergeUnion>>>
>
: never
: never;
type ExportScopedPropertiesFromCommand =
MergeConfigsOptions extends infer Merged
? Merged extends ParsableConfigs
? PrepareConfigsWithType
: Record
: Record;
export type ExportStoragePropertiesFromCommand = ExportScopedPropertiesFromCommand;
export type ExportGeneratorOptionsFromCommand = ExportScopedPropertiesFromCommand;
export type ExportGeneratorPropertiesFromCommand = Readonly>;
export type HandleCommandTypes = Record<'Config', ExportStoragePropertiesFromCommand> &
Record<'Options', ExportGeneratorOptionsFromCommand> &
Record<'Generator', ExportGeneratorPropertiesFromCommand> &
Record<'Application', ExportApplicationPropertiesFromCommand>;