UNPKG

23.6 kBTypeScriptView Raw
1import { Command } from "commander";
2import { EventEmitter } from "events";
3import { ExecaChildProcess, ExecaSyncReturnValue, Options, SyncOptions } from "execa";
4import * as inquirer from "inquirer";
5import { Store as MemFsStore } from "mem-fs";
6import * as Generator from "yeoman-generator";
7import Storage = require("yeoman-generator/lib/util/storage");
8import TerminalAdapter = require("./lib/adapter");
9import { Logger as LoggerBase } from "./lib/util/log";
10import util = require("./lib/util/util");
11import Conflicter = require("./lib/util/conflicter");
12import { Stream, Transform } from "stream";
13
14/**
15 * `Environment` object is responsible of handling the lifecycle and bootstrap
16 * of generators in a specific environment (your app).
17 *
18 * It provides a high-level API to create and run generators, as well as further
19 * tuning where and how a generator is resolved.
20 *
21 * An environment is created using a list of `arguments` and a Hash of `options`.
22 * Usually, this is the list of arguments you get back from your CLI options parser.
23 *
24 * An optional adapter can be passed to provide interaction in non-CLI environment
25 * (e.g. IDE plugins), otherwise a `TerminalAdapter` is instantiated by default
26 */
27declare class Environment<TOptions extends Environment.Options = Environment.Options> extends EventEmitter {
28 /**
29 * The utilities of the module.
30 */
31 static util: typeof util;
32
33 /**
34 * The arguments passed to this environment.
35 */
36 arguments: string[];
37
38 /**
39 * The options of the environment.
40 */
41 options: TOptions;
42
43 /**
44 * The adapter of the environment.
45 */
46 adapter: TerminalAdapter;
47
48 /**
49 * The working-directory of the environment.
50 */
51 cwd: string;
52
53 /**
54 * The config-storage of the environment.
55 */
56 store: Storage;
57
58 /**
59 * The file-system of the environment.
60 */
61 sharedFs: MemFsStore;
62
63 /**
64 * The file-paths to look for generators (such as `lib/generators/`).
65 */
66 lookups: string[];
67
68 /**
69 * The alias-settings of the environment.
70 */
71 aliases: Environment.Alias[];
72
73 /**
74 * Initializes a new instance of the `Environment` class.
75 *
76 * @param args The arguments to pass to the environment.
77 * @param opts The options for the environment.
78 * @param adapter A `TerminalAdapter` instance for handling input/output.
79 */
80 constructor(args?: string | string[], opts?: TOptions, adapter?: Environment.Adapter);
81
82 /**
83 * Creates a new `Environment` instance.
84 *
85 * @param args The arguments to pass to the environment.
86 * @param opts The options for the environment.
87 * @param adapter A `TerminalAdapter` instance for handling input/output.
88 * @returns The newly created environment.
89 */
90 static createEnv<TOptions extends Environment.Options = Environment.Options>(
91 args?: string | string[],
92 opts?: TOptions,
93 adapter?: Environment.Adapter,
94 ): Environment<TOptions>;
95
96 /**
97 * Creates a new `Environment` instance with the specified `version`.
98 *
99 * @param version The version of the environment.
100 * @param args The arguments to pass to the environment.
101 * @param opts The options for the environment.
102 * @param adapter A `TerminalAdapter` instance for handling input/output.
103 * @returns The newly created environment.
104 */
105 static createEnvWithVersion<TOptions extends Environment.Options>(
106 version: string,
107 args?: string | string[],
108 opts?: TOptions,
109 adapter?: Environment.Adapter,
110 ): Environment<TOptions>;
111
112 /**
113 * Makes sure the Environment present expected methods if an old version is passed to a Generator.
114 *
115 * @param env The environment to update.
116 * @returns The updated `env`.
117 */
118 static enforceUpdate<TEnv extends Environment>(env: TEnv): TEnv;
119
120 /**
121 * Invokes a lookup for a specific generator.
122 *
123 * @param namespace The namespace of the generator to search.
124 * @param options Options for searching the generator.
125 * @returns The paths to the generators which were found.
126 */
127 static lookupGenerator(namespace: string, options?: Environment.ArrayGeneratorLookupOptions): string[];
128
129 /**
130 * Invokes a lookup for a specific generator.
131 *
132 * @param namespace The namespace of the generator to search.
133 * @param options Options for searching the generator.
134 * @returns The path to the generator which was found.
135 */
136 static lookupGenerator(namespace: string, options?: Environment.SingleGeneratorLookupOptions): string;
137
138 /**
139 * Converts a generator namespace to its name.
140 *
141 * @param namespace The generator namespace.
142 */
143 static namespaceToName(namespace: string): string;
144
145 /**
146 * Prepares a command for cli support.
147 *
148 * @param generatorClass The generator class to create a command for.
149 * @returns The prepared command.
150 */
151 static prepareCommand(generatorClass: Generator.GeneratorConstructor): Command;
152
153 /**
154 * Prepares a command for cli support.
155 *
156 * @param command The command to prepare.
157 * @param generatorClass The constructor of the generator to prepare the command for.
158 * @returns The prepared command.
159 */
160 static prepareGeneratorCommand(command: Command, generatorClass: Generator.GeneratorConstructor): Command;
161
162 /**
163 * Gets the alias for the specified `name`.
164 */
165 alias(name: string): string;
166
167 /**
168 * Creates an alias.
169 *
170 * Alias allows the `get()` and `lookup()` methods to search in alternate filepath for a given namespaces.
171 * It's used for example to map `generator-*` npm package to their namespace equivalent (without the generator- prefix),
172 * or to default a single namespace like `angular` to `angular:app` or `angular:all`.
173 *
174 * If multiple aliases are defined, then the replacement is recursive, replacing each alias in reverse order.
175 *
176 * An alias can be a single String or a Regular Expression.
177 * The finding is done based on .match().
178 *
179 * @param match The name to match.
180 * @param value The replacement for the specified `match`.
181 *
182 * @example
183 * env.alias(/^([a-zA-Z0-9:\*]+)$/, 'generator-$1');
184 * env.alias(/^([^:]+)$/, '$1:app');
185 * env.alias(/^([^:]+)$/, '$1:all');
186 * env.alias('foo');
187 * // => generator-foo:all
188 */
189 alias(match: string | RegExp, value: string): void;
190
191 /**
192 * Applies the specified transform streams to the files in the `sharedFs`.
193 *
194 * @param transformStreams The transforms to apply.
195 * @param stream The file stream to apply the transforms on.
196 */
197 applyTransforms(transformStreams: Transform[], stream?: NodeJS.ReadableStream): Promise<void>;
198
199 /**
200 * Commits the `mem-fs` to the disk.
201 *
202 * @param stream The files to commit.
203 */
204 commitSharedFs(stream: Stream): Promise<void>;
205
206 /**
207 * Composes with a generator.
208 *
209 * @param namespaceOrPath The namespace of the generator or the path to a generator.
210 * @param args The options to pass to the generator.
211 * @param options The options to pass to the generator.
212 * @returns The instantiated generator or a singleton instance.
213 */
214 composeWith(namespaceOrPath: string, args: string[], options: Generator.GeneratorOptions): Generator;
215
216 /**
217 * Creates a new generator.
218 *
219 * @param namespaceOrPath The namespace of the generator or the path to a generator.
220 * @param args The arguments to pass to the generator.
221 * @param options The options to pass to the generator.
222 * @returns Either the newly created generator or the error that occurred.
223 */
224 create<TOptions extends Generator.GeneratorOptions>(
225 namespaceOrPath: string,
226 args: string[],
227 options?: Environment.InstantiateOptions<TOptions>,
228 ): Generator<TOptions> | Error;
229
230 /**
231 * Handles the specified `error`.
232 *
233 * The `error`-event is emitted with the specified `error` object.
234 * If no `error` listener is registered, the error is thrown.
235 *
236 * @param error An object representing the error.
237 */
238 error(error: Error | object): Error;
239
240 /**
241 * Searches npm for every available generator.
242 * Generators are npm-packages whose name starts with `generator-` and that are placed in the top level `node_module` path.
243 * They can be installed globally or locally.
244 *
245 * @deprecated
246 * @param list The paths to search for generators.
247 * @param options The options for looking for generators.
248 */
249 findGeneratorsIn(list: string[], options?: Environment.GeneratorsInOptions): string[];
250
251 /**
252 * Gets a single constructor of a generator from the registered list of generators.
253 *
254 * The lookup is based on generator's namespace, "walking up" the namespaces until a matching is found.
255 * Eg. if an `angular:common` namespace is registered, and we try to get `angular:common:all`,
256 * then we get `angular:common` as a fallback (unless an `angular:common:all` generator is registered).
257 *
258 * @param namespaceOrPath The namespace of the generator or the path to a generator.
259 * @returns The constructor of the generator registered under the namespace.
260 */
261 get(namespaceOrPath: string): typeof Generator | undefined;
262
263 /**
264 * Gets a constructor of a generator by the path instead of the namespace.
265 *
266 * @param path The path to the generator.
267 * @returns The constructor of the generator found at the location.
268 */
269 getByPath(path: string): typeof Generator | undefined;
270
271 /**
272 * Gets the names of the registered generators.
273 */
274 getGeneratorNames(): string[];
275
276 /**
277 * Gets metadata of the registered generators.
278 */
279 getGeneratorsMeta(): Record<string, Environment.GeneratorMeta>;
280
281 /**
282 * Gets paths to directories to look for npm-packages (such as `./node_modules`).
283 *
284 * @deprecated
285 */
286 getNpmPaths(options?: Environment.NpmPathsOptions): string[];
287
288 /**
289 * Gets the most recent path to the generator by its namespace.
290 *
291 * @param namespace The namespace of the generator.
292 */
293 getPackagePath(namespace: string): string;
294
295 /**
296 * Gets all paths which have been populated for a generator by its namespace.
297 *
298 * @param namespace The namespace of the generator.
299 */
300 getPackagePaths(namespace: string): string[];
301
302 /**
303 * Gets the namespaces of all registered generators.
304 */
305 getRegisteredPackages(): string[];
306
307 /**
308 * Gets the version of this `Environment` object.
309 */
310 getVersion(): string;
311
312 /**
313 * Gets the version of the specified `dependency`.
314 *
315 * @param dependency The name of the dependency.
316 */
317 // tslint:disable-next-line:unified-signatures
318 getVersion(dependency: string): string;
319
320 /**
321 * Outputs general help and usage for the specified `command`.
322 * Optionally, if generators have been registered, a list of available generators is displayed.
323 *
324 * @param command `The name of the command to get help for.
325 */
326 help(command?: string): string;
327
328 /**
329 * Installs generators at the custom local repository and registers them.
330 *
331 * @param packages The package-names with the corresponding versions to install.
332 */
333 installLocalGenerators(packages: Record<string, string>): boolean;
334
335 /**
336 * Instantiates a generator.
337 *
338 * @param generator The constructor of the generator.
339 * @param args The arguments to pass to the generator.
340 * @param options The options to pass to the generator.
341 */
342 instantiate(
343 generator: Generator.GeneratorConstructor,
344 args: string[],
345 options: Environment.InstantiateOptions,
346 ): Generator;
347
348 /**
349 * Checks whether a package with the specified `packageNamespace` has been registered.
350 *
351 * @param packageNamespace The package-namespace to check.
352 * @returns A value indicating whether a package with the specified `packageNamespace` has been registered.
353 */
354 isPackageRegistered(packageNamespace?: string): boolean;
355
356 /**
357 * Applies the specified `options` to the environment.
358 *
359 * @param options The options to load.
360 * @returns The new options of the environment.
361 */
362 loadEnvironmentOptions(options: Environment.Options): Environment.Options;
363
364 /**
365 * Loads the specified `options` into the environment for passing to the generators.
366 *
367 * @param options The options to load.
368 * @return the new shared options of the environment.
369 */
370 loadSharedOptions(options: Generator.GeneratorOptions): Generator.GeneratorOptions;
371
372 /**
373 * Searches for generators and their sub-generators.
374 *
375 * A generator is a `:lookup/:name/index.js` file placed inside an npm package.
376 *
377 * Default lookups are:
378 * - `./`
379 * - `./generators/`
380 * - `./lib/generators/`
381 *
382 * So the index file `node_modules/generator-dummy/lib/generators/yo/index.js` would be registered as `dummy:yo` generator.
383 *
384 * @param options The options for the lookup.
385 * @returns A list of generators.
386 */
387 lookup(options?: Environment.LookupOptions): Environment.LookupGeneratorMeta[];
388
389 /**
390 * Searches and registers generators inside the custom local repository.
391 *
392 * @param packagesToLookup The patterns of the packages to lookup.
393 */
394 lookupLocalPackages(packagesToLookup?: string[]): Environment.LookupGeneratorMeta[];
395
396 /**
397 * Converts the specified `filePath` to a namespace.
398 *
399 * @param filePath The path to convert.
400 * @param lookups The path-part to exclude (such as `lib/generators`).
401 */
402 namespace(filePath: string, lookups?: string[]): string;
403
404 /**
405 * Gets a list of all registered namespaces.
406 */
407 namespaces(): string[];
408
409 /**
410 * Queue's the environment's commit task.
411 */
412 queueConflicter(): void;
413
414 /**
415 * Queues the specified `generator`.
416 *
417 * @param generator The generator to queue.
418 * @param schedule A value indicating whether the execution of the generator should be scheduled.
419 * @returns The queued generator.
420 */
421 queueGenerator(generator: Generator, schedule?: boolean): Generator;
422
423 /**
424 * Queues the package manager installation task.
425 */
426 queuePackageManagerInstall(): void;
427
428 /**
429 * Registers a specific `generator` to this environment.
430 * This generator is stored under the provided `namespace` or, if not specified, a default namespace format.
431 *
432 * @param name The filepath to the generator or an npm package name.
433 * @param namespace The namespace under which the generator should be registered.
434 * @param packagePath The path to the npm package of the generator.
435 */
436 register(name: string, namespace?: string, packagePath?: string): this;
437
438 /**
439 * Registers a stubbed generator to this environment.
440 *
441 * @param generator The generator constructor.
442 * @param namespace The namespace under which the generator should be registered.
443 * @param resolved The file-path to the generator.
444 * @param packagePath The path to the npm package of the generator.
445 */
446 registerStub(
447 generator: Generator.GeneratorConstructor,
448 namespace: string,
449 resolved?: string,
450 packagePath?: string,
451 ): this;
452
453 /**
454 * Resolves the path of the specified module.
455 *
456 * @param moduleId The name of the module.
457 * @returns The resolved path to the module.
458 */
459 resolveModulePath(moduleId: string): string;
460
461 /**
462 * Resolves a package name with a specific version.
463 *
464 * @param packageName The name of the package to resolve.
465 * @param packageVersion The version or the version range of the package to resolve.
466 */
467 resolvePackage(packageName: string, packageVersion: string): [string, string];
468
469 /**
470 * Gets the first generator that was queued to run in this environment.
471 */
472 rootGenerator(): Generator;
473
474 /**
475 * Tries to locate and run a specific generator.
476 * The lookup is done depending on the provided arguments, options and the list of registered generators.
477 *
478 * When the environment was unable to resolve a generator, an error is raised.
479 *
480 * @param args The arguments to pass to the generator.
481 * @param options The options to pass to the generator.
482 */
483 run(args: string | [string, ...string[]], options?: Generator.GeneratorOptions): Promise<void>;
484
485 /**
486 * Runs the specified generator.
487 *
488 * See [#101](https://github.com/yeoman/environment/pull/101) for more info.
489 *
490 * @param generator The generator to run.
491 */
492 runGenerator(generator: Generator): Promise<void>;
493
494 /**
495 * Starts the environment queue.
496 *
497 * @param options The conflicter options.
498 */
499 start(options: Conflicter.ConflicterOptions): Promise<void>;
500
501 /**
502 * Spawns a command asynchronously.
503 *
504 * @param command The command to execute.
505 * @param args The arguments to pass to the program.
506 * @param options The options to use for running the command.
507 */
508 spawnCommand(command: string, args: string[], options: Options): ExecaChildProcess;
509
510 /**
511 * Spawns a command synchronously.
512 *
513 * @param command The command to execute.
514 * @param args The arguments to pass to the program.
515 * @param options The options to use for running the command.
516 */
517 spawnCommandSync(command: string, args: string[], options: SyncOptions): ExecaSyncReturnValue;
518}
519
520declare namespace Environment {
521 /**
522 * Represents a component for logging messages.
523 */
524 type Logger = LoggerBase;
525
526 /**
527 * Represents a question.
528 */
529 type Question<T extends inquirer.Answers> = inquirer.DistinctQuestion<T>;
530
531 /**
532 * Represents a collection of questions.
533 */
534 type Questions<T extends inquirer.Answers> = inquirer.QuestionCollection<T>;
535
536 /**
537 * Represents an answer-hash.
538 */
539 type Answers = inquirer.Answers;
540
541 /**
542 * Represents an adapter.
543 */
544 type Adapter = TerminalAdapter;
545
546 /**
547 * Represents an alias.
548 */
549 interface Alias {
550 /**
551 * The pattern to match.
552 */
553 match: RegExp;
554
555 /**
556 * The replacement of the `match`.
557 */
558 value: string;
559 }
560
561 /**
562 * Represents options for an `Environment`.
563 */
564 interface Options {
565 /**
566 * The working-directory of the environment.
567 */
568 cwd?: string | undefined;
569
570 /**
571 * A value indicating whether the experimental features should be enabled.
572 */
573 experimental?: boolean;
574
575 /**
576 * The options to pass to generators.
577 */
578 sharedOptions?: Generator.GeneratorOptions;
579
580 /**
581 * A console instance for logging messages.
582 */
583 console?: Console;
584
585 /**
586 * A stream for receiving data from.
587 */
588 stdin?: Stream;
589
590 /**
591 * A stream to write normal messages to.
592 */
593 stdout?: Stream;
594
595 /**
596 * A stream to write error messages to.
597 */
598 stderr?: Stream;
599
600 /**
601 * Additional options.
602 */
603 [key: string]: any;
604 }
605
606 /**
607 * Provides information about a generator.
608 */
609 interface GeneratorMeta {
610 /**
611 * The resolved path to the generator.
612 */
613 resolved: string;
614
615 /**
616 * The namespace of the generator.
617 */
618 namespace: string;
619
620 /**
621 * The path to the package containing the generator.
622 */
623 packagePath: string;
624 }
625
626 /**
627 * Provides information about a generator.
628 */
629 interface LookupGeneratorMeta extends GeneratorMeta {
630 /**
631 * A value indicating whether the generator could be registered.
632 */
633 registered: boolean;
634 }
635
636 /**
637 * Provides options for instantiating a generator.
638 */
639 interface InstantiateOptions<TOptions extends Generator.GeneratorOptions = Generator.GeneratorOptions> {
640 /**
641 * The arguments to pass to the generator.
642 */
643 arguments?: string | string[] | undefined;
644
645 /**
646 * The options for creating the generator.
647 */
648 options?: TOptions | undefined;
649 }
650
651 /**
652 * Provides options for lookups.
653 */
654 interface LookupOptionBase {
655 /**
656 * A value indicating whether globally installed packages should be ignored.
657 */
658 localOnly?: boolean | undefined;
659 }
660
661 /**
662 * Provides options for generator-lookups.
663 */
664 interface GeneratorLookupOptions extends LookupOptionBase {
665 /**
666 * A value indicating whether the path to the package should be returned instead of the path to the generator.
667 */
668 packagePath?: boolean | undefined;
669
670 /**
671 * A value indicating whether only one result should be returned.
672 */
673 singleResult?: boolean | undefined;
674 }
675
676 /**
677 * Provides options for single generator lookups.
678 */
679 interface SingleGeneratorLookupOptions extends GeneratorLookupOptions {
680 /**
681 * @inheritdoc
682 */
683 singleResult: true;
684 }
685
686 /**
687 * Provides options array generator lookups.
688 */
689 interface ArrayGeneratorLookupOptions extends GeneratorLookupOptions {
690 /**
691 * @inheritdoc
692 */
693 singleResult?: false | undefined;
694 }
695
696 /**
697 * Provides options for the `getNpmPaths` method.
698 */
699 interface NpmPathsOptions extends LookupOptionBase {
700 /**
701 * A value indicating whether paths which don't end with a supported directory-name should be filtered (unless they are part of `NODE_PATH`).
702 */
703 filterPaths?: boolean | undefined;
704 }
705
706 /**
707 * Provides options for the `lookup` method.
708 */
709 interface LookupOptions extends LookupOptionBase {
710 /**
711 * The paths to look for generators.
712 */
713 packagePaths?: string[] | undefined;
714
715 /**
716 * The rep√ľository paths to look for generator packages.
717 */
718 npmPaths?: string[] | undefined;
719
720 /**
721 * The file-patterns to look for.
722 */
723 filePatterns?: string[] | undefined;
724
725 /**
726 * The package patterns to look for.
727 */
728 packagePatterns?: string[] | undefined;
729
730 /**
731 * A value indicating whether the lookup should be stopped after finding the first result.
732 */
733 singleResult?: boolean | undefined;
734
735 /**
736 * The `deep` option to pass to `globby`.
737 */
738 globbyDeep?: number | undefined;
739 }
740
741 /**
742 * Provides options for the `findGeneratorsIn` method.
743 */
744 interface GeneratorsInOptions {
745 /**
746 * The package-patterns to look for.
747 */
748 packagePatterns?: string[] | undefined;
749 }
750
751 /**
752 * Provides the functionality to handle callbacks.
753 */
754 type Callback =
755 /**
756 * Handles a callback.
757 *
758 * @param err The error that occurred.
759 */
760 (err: Error | null) => void;
761}
762
763export = Environment;
764
\No newline at end of file