UNPKG

7.35 kBTypeScriptView Raw
1import inquirer from "inquirer";
2// @types/globby doesn't export types for GlobOptions, so we have to work a little bit to extract them:
3// GlobOptions is the second parameter of the sync function, which can be extracted with the Parameters<T> type
4import { globbySync } from "globby";
5
6type GlobOptions = Parameters<typeof globbySync>[1];
7import { HelperDelegate as HelperFunction } from "handlebars";
8
9export interface IncludeDefinitionConfig {
10 generators?: boolean;
11 helpers?: boolean;
12 partials?: boolean;
13 actionTypes?: boolean;
14}
15
16export type IncludeDefinition = boolean | string[] | IncludeDefinitionConfig;
17
18export interface NodePlopAPI {
19 setGenerator(
20 name: string,
21 config: Partial<PlopGeneratorConfig>
22 ): PlopGenerator;
23
24 setPrompt(name: string, prompt: inquirer.prompts.PromptConstructor): void;
25
26 setWelcomeMessage(message: string): void;
27
28 getWelcomeMessage(): string;
29
30 getGenerator(name: string): PlopGenerator;
31
32 getGeneratorList(): { name: string; description: string }[];
33
34 setPartial(name: string, str: string): void;
35
36 getPartial(name: string): string;
37
38 getPartialList(): string[];
39
40 setHelper(name: string, fn: HelperFunction): void;
41
42 // eslint-disable-next-line @typescript-eslint/ban-types
43 getHelper(name: string): Function;
44
45 getHelperList(): string[];
46
47 setActionType(name: string, fn: CustomActionFunction): void;
48
49 /**
50 * This does not include a `CustomActionConfig` for the same reasons
51 * Listed in the `ActionType` declaration. Please see that JSDoc for more
52 */
53 getActionType(name: string): ActionType;
54
55 getActionTypeList(): string[];
56
57 setPlopfilePath(filePath: string): void;
58
59 getPlopfilePath(): string;
60
61 getDestBasePath(): string;
62
63 // plop.load functionality
64 load(
65 target: string[] | string,
66 loadCfg?: Partial<PlopCfg> | null,
67 includeOverride?: IncludeDefinition
68 ): Promise<void>;
69
70 setDefaultInclude(inc: object): void;
71
72 getDefaultInclude(): object;
73
74 renderString(template: string, data: any): string; //set to any matching handlebars declaration
75
76 // passthroughs for backward compatibility
77 /**
78 * @deprecated Use "setPrompt" instead. This will be removed in the next major release
79 */
80 addPrompt(name: string, prompt: inquirer.PromptModule): void;
81
82 /**
83 * @deprecated Use "setPartial" instead. This will be removed in the next major release
84 */
85 addPartial(name: string, str: string): void;
86
87 /**
88 * @deprecated Use "setHelper" instead. This will be removed in the next major release
89 */
90 // eslint-disable-next-line @typescript-eslint/ban-types
91 addHelper(name: string, fn: Function): void;
92}
93
94interface PlopActionHooksFailures {
95 type: string;
96 path: string;
97 error: string;
98 message: string;
99}
100
101interface PlopActionHooksChanges {
102 type: string;
103 path: string;
104}
105
106interface PlopActionHooks {
107 onComment?: (msg: string) => void;
108 onSuccess?: (change: PlopActionHooksChanges) => void;
109 onFailure?: (failure: PlopActionHooksFailures) => void;
110}
111
112export interface PlopGeneratorConfig {
113 description: string;
114 prompts: Prompts;
115 actions: Actions;
116}
117
118export interface PlopGenerator extends PlopGeneratorConfig {
119 runPrompts: (bypassArr?: string[]) => Promise<any>;
120 runActions: (
121 answers: inquirer.Answers,
122 hooks?: PlopActionHooks
123 ) => Promise<{
124 changes: PlopActionHooksChanges[];
125 failures: PlopActionHooksFailures[];
126 }>;
127}
128
129export type PromptQuestion =
130 | inquirer.Question
131 | inquirer.CheckboxQuestion
132 | inquirer.ListQuestion
133 | inquirer.ExpandQuestion
134 | inquirer.ConfirmQuestion
135 | inquirer.EditorQuestion
136 | inquirer.RawListQuestion
137 | inquirer.PasswordQuestion
138 | inquirer.NumberQuestion
139 | inquirer.InputQuestion;
140
141export type DynamicPromptsFunction = (
142 inquirer: inquirer.Inquirer
143) => Promise<inquirer.Answers>;
144export type DynamicActionsFunction = (data?: inquirer.Answers) => ActionType[];
145
146export type Prompts = DynamicPromptsFunction | PromptQuestion[];
147export type Actions = DynamicActionsFunction | ActionType[];
148
149interface Template {
150 template: string;
151 templateFile?: never;
152}
153
154interface TemplateFile {
155 template?: never;
156 templateFile: string;
157}
158
159type TemplateStrOrFile = Template | TemplateFile;
160
161/**
162 * "TypeString" is a type generic of what type is present. It allows us
163 * to pass arbitrary keys to a field alongside any type name that doesn't
164 * intersect with built-ins. This is an unfortunate limitation of TypeScript
165 *
166 * We strongly suggest you actually use a const type (so, 'customActionName' instead of `string`),
167 * that way, you can make sure that your custom action doesn't interfere with built-ins in
168 * the future.
169 *
170 * However, keep in mind that by doing so it means your config object MUST have the same `type` value
171 * as the generic input string.
172 *
173 * To ignore this limitation, simply pass "string"
174 */
175export interface CustomActionConfig<TypeString extends string>
176 extends Omit<ActionConfig, "type"> {
177 type: TypeString extends "addMany" | "modify" | "append" ? never : TypeString;
178
179 [key: string]: any;
180}
181
182export type CustomActionFunction = (
183 answers: inquirer.Answers,
184 config: CustomActionConfig<string>,
185 plopfileApi: NodePlopAPI
186) => Promise<string> | string;
187
188/**
189 * Ideally, we'd have `CustomActionConfig` here,
190 * but if we do, we lose the ability to strictly type an action,
191 * since "type: 'append'" is now considered a custom action config
192 * and not an append action config.
193 *
194 * See `CustomActionConfig` declaration for more usage instructions
195 *
196 * If you know of a solution, please open a GitHub issue to discuss
197 */
198export type ActionType =
199 | string
200 | ActionConfig
201 | AddActionConfig
202 | AddManyActionConfig
203 | ModifyActionConfig
204 | AppendActionConfig
205 | CustomActionFunction;
206
207export interface ActionConfig {
208 type: string;
209 force?: boolean;
210 data?: object;
211 abortOnFail?: boolean;
212 // eslint-disable-next-line @typescript-eslint/ban-types
213 skip?: Function;
214}
215
216type TransformFn<T> = (
217 template: string,
218 data: any,
219 cfg: T
220) => string | Promise<string>;
221
222interface AddActionConfigBase extends ActionConfig {
223 type: "add";
224 path: string;
225 skipIfExists?: boolean;
226 transform?: TransformFn<AddActionConfig>;
227}
228
229export type AddActionConfig = AddActionConfigBase & TemplateStrOrFile;
230
231export interface AddManyActionConfig
232 extends Pick<
233 AddActionConfig,
234 Exclude<
235 keyof AddActionConfig,
236 "type" | "templateFile" | "template" | "transform"
237 >
238 > {
239 type: "addMany";
240 destination: string;
241 base: string;
242 templateFiles: string | string[];
243 stripExtensions?: string[];
244 globOptions: GlobOptions;
245 verbose?: boolean;
246 transform?: TransformFn<AddManyActionConfig>;
247}
248
249interface ModifyActionConfigBase extends ActionConfig {
250 type: "modify";
251 path: string;
252 pattern: string | RegExp;
253 transform?: TransformFn<ModifyActionConfig>;
254}
255
256export type ModifyActionConfig = ModifyActionConfigBase & TemplateStrOrFile;
257
258interface AppendActionConfigBase extends ActionConfig {
259 type: "append";
260 path: string;
261 pattern: string | RegExp;
262 unique: boolean;
263 separator: string;
264}
265
266export type AppendActionConfig = AppendActionConfigBase & TemplateStrOrFile;
267
268export interface PlopCfg {
269 force: boolean;
270 destBasePath: string | undefined;
271}
272
273declare function nodePlop(
274 plopfilePath?: string,
275 plopCfg?: PlopCfg
276): Promise<NodePlopAPI>;
277
278export default nodePlop;