create-gasket-app 7.0.4 → 7.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands/create.js +2 -7
- package/lib/index.d.ts +209 -17
- package/lib/index.js +3 -0
- package/lib/internal.d.ts +133 -0
- package/lib/scaffold/action-wrapper.js +2 -10
- package/lib/scaffold/actions/create-hooks.js +3 -7
- package/lib/scaffold/actions/generate-files.js +5 -20
- package/lib/scaffold/actions/global-prompts.js +10 -19
- package/lib/scaffold/actions/install-modules.js +1 -3
- package/lib/scaffold/actions/link-modules.js +1 -4
- package/lib/scaffold/actions/load-preset.js +3 -3
- package/lib/scaffold/actions/mkdir.js +3 -6
- package/lib/scaffold/actions/post-create-hooks.js +2 -5
- package/lib/scaffold/actions/preset-config-hooks.js +1 -2
- package/lib/scaffold/actions/preset-prompt-hooks.js +1 -2
- package/lib/scaffold/actions/print-report.js +3 -12
- package/lib/scaffold/actions/prompt-hooks.js +3 -12
- package/lib/scaffold/actions/setup-pkg.js +3 -5
- package/lib/scaffold/actions/write-gasket-config.js +7 -16
- package/lib/scaffold/actions/write-pkg.js +1 -3
- package/lib/scaffold/config-builder.js +31 -35
- package/lib/scaffold/create-context.js +5 -66
- package/lib/scaffold/dump-error-context.js +1 -4
- package/lib/scaffold/files.js +8 -5
- package/lib/scaffold/utils.js +1 -9
- package/lib/utils/create-option.js +1 -2
- package/lib/utils/process-args.js +5 -7
- package/lib/utils/process-command.js +2 -4
- package/lib/utils/process-options.js +6 -8
- package/package.json +17 -13
package/lib/commands/create.js
CHANGED
|
@@ -25,9 +25,7 @@ import {
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Parses comma separated option input to array
|
|
28
|
-
*
|
|
29
|
-
* @param {String} input - option argument
|
|
30
|
-
* @returns {String[]} results
|
|
28
|
+
* @type {import('../internal').commasToArray}
|
|
31
29
|
*/
|
|
32
30
|
const commasToArray = input => input.split(',').map(name => name.trim());
|
|
33
31
|
|
|
@@ -97,10 +95,7 @@ const createCommand = {
|
|
|
97
95
|
|
|
98
96
|
/**
|
|
99
97
|
* createCommand action
|
|
100
|
-
* @
|
|
101
|
-
* @param {object} options cmd options
|
|
102
|
-
* @param {Command} command - the command instance
|
|
103
|
-
* @returns {Promise<void>} void
|
|
98
|
+
* @type {import('../index').createCommandAction}
|
|
104
99
|
*/
|
|
105
100
|
createCommand.action = async function run(appname, options, command) {
|
|
106
101
|
process.env.GASKET_ENV = 'create';
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { GasketConfigDefinition, MaybeAsync, Plugin, GasketEngine } from '@gasket/core';
|
|
2
2
|
import type { PackageManager } from '@gasket/utils';
|
|
3
3
|
import type { PromptModule } from 'inquirer';
|
|
4
|
+
import type ora from 'ora';
|
|
4
5
|
|
|
5
6
|
export interface Dependencies {
|
|
6
7
|
dependencies?: Record<string, string>;
|
|
@@ -25,6 +26,41 @@ export interface PackageJson extends Dependencies {
|
|
|
25
26
|
homepage?: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
interface CommandArgument {
|
|
30
|
+
name: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
required?: boolean;
|
|
33
|
+
default?: any;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface CommandOption {
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
required?: boolean;
|
|
40
|
+
short?: string;
|
|
41
|
+
parse?: (value: string) => any;
|
|
42
|
+
type?: string;
|
|
43
|
+
conflicts?: string | string[];
|
|
44
|
+
hidden?: boolean;
|
|
45
|
+
default?: any;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function createCommandAction(
|
|
49
|
+
appname: string,
|
|
50
|
+
options: CreateCommandOptions,
|
|
51
|
+
command: Command
|
|
52
|
+
): Promise<void>;
|
|
53
|
+
|
|
54
|
+
export interface CreateCommand {
|
|
55
|
+
id: string;
|
|
56
|
+
description: string;
|
|
57
|
+
args: CommandArgument[];
|
|
58
|
+
action?: createGasketAction;
|
|
59
|
+
options: CommandOption[];
|
|
60
|
+
hidden?: boolean;
|
|
61
|
+
default?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
28
64
|
export interface ModuleInfo {
|
|
29
65
|
name: string;
|
|
30
66
|
module: any;
|
|
@@ -38,18 +74,28 @@ export interface PresetInfo extends ModuleInfo { }
|
|
|
38
74
|
export interface PluginInfo extends ModuleInfo { }
|
|
39
75
|
|
|
40
76
|
export interface ConfigBuilder<Config> {
|
|
41
|
-
/**
|
|
42
|
-
* fields object
|
|
43
|
-
*/
|
|
77
|
+
/** fields object */
|
|
44
78
|
fields: { [key: string]: any };
|
|
79
|
+
original?: { [key: string]: any };
|
|
80
|
+
source?: Plugin;
|
|
81
|
+
orderBy?: string[];
|
|
82
|
+
orderedFields?: string[];
|
|
83
|
+
objectFields?: string[];
|
|
84
|
+
semverFields?: string[];
|
|
85
|
+
blame?: Map<string, string[]>;
|
|
86
|
+
force?: Set<any>;
|
|
87
|
+
warnings?: string[];
|
|
45
88
|
|
|
46
89
|
/**
|
|
47
90
|
* Adds all `[key, value]` pairs in the `fields` provided.
|
|
48
91
|
* @param fields - Object to merge. Can be a function that accepts the current fields and object to merge.
|
|
92
|
+
* @param source - Plugin to blame if conflicts arise from this operation.
|
|
49
93
|
*/
|
|
50
94
|
extend(
|
|
51
|
-
fields: Partial<Config> | ((current: Config) => Partial<Config>)
|
|
95
|
+
fields: Partial<Config> | ((current: Config) => Partial<Config>),
|
|
96
|
+
source: Plugin
|
|
52
97
|
): void;
|
|
98
|
+
extend(fields: Partial<Config> | ((current: Config) => Partial<Config>)): void;
|
|
53
99
|
|
|
54
100
|
/**
|
|
55
101
|
* Performs an intelligent, domain-aware merge of the `value` for
|
|
@@ -57,17 +103,20 @@ export interface ConfigBuilder<Config> {
|
|
|
57
103
|
*
|
|
58
104
|
* @param key - Field in package.json to add or extend.
|
|
59
105
|
* @param value - Target value to set for key provided.
|
|
106
|
+
* @param source - Plugin to blame if conflicts arise from this operation.
|
|
60
107
|
* @param [options] - Optional arguments for add behavior
|
|
61
108
|
* @param [options.force] - Should the semver version override other attempts
|
|
62
109
|
*
|
|
63
110
|
* Adapted from @vue/cli under MIT License:
|
|
64
111
|
* https://github.com/vuejs/vue-cli/blob/f09722c/packages/%40vue/cli/lib/GeneratorAPI.js#L117-L150
|
|
65
112
|
*/
|
|
66
|
-
add<Key extends keyof Config>(
|
|
113
|
+
add<Key extends keyof Config & string>(
|
|
67
114
|
key: Key,
|
|
68
115
|
value: Config[Key],
|
|
116
|
+
source: Plugin,
|
|
69
117
|
options?: { force?: boolean }
|
|
70
118
|
): void;
|
|
119
|
+
add(key: string, value: object, options?: object): void;
|
|
71
120
|
|
|
72
121
|
/**
|
|
73
122
|
* addPlugin - Add plugin import to the gasket file and use the value in the plugins array
|
|
@@ -146,43 +195,177 @@ export interface PackageJsonBuilder extends ConfigBuilder<PackageJson> {
|
|
|
146
195
|
has(key: keyof PackageJson, value: string): boolean;
|
|
147
196
|
}
|
|
148
197
|
|
|
149
|
-
|
|
150
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Interface for the Files class.
|
|
200
|
+
*/
|
|
201
|
+
interface Files {
|
|
202
|
+
/**
|
|
203
|
+
* Array of glob sets, each containing an array of globs and a source object.
|
|
204
|
+
*/
|
|
205
|
+
globSets: Array<{ globs: string[], source: Plugin }>;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Return array of globs.
|
|
209
|
+
* @deprecated
|
|
210
|
+
* @returns {string[]} `globby` compatible patterns.
|
|
211
|
+
*/
|
|
212
|
+
readonly globs: string[];
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Adds the specified `globby` compatible patterns, `globs`,
|
|
216
|
+
* into the set of all sources for this set of files.
|
|
217
|
+
* @param {Object} params - Object containing `globs` and `source`.
|
|
218
|
+
* @param {string[]} params.globs - `globby` compatible patterns.
|
|
219
|
+
* @param {Object} params.source - Plugin to blame if conflicts arise from this operation.
|
|
220
|
+
*/
|
|
221
|
+
add(params: { globs: string[], source: object }): void;
|
|
222
|
+
add(...globs: string[]): void;
|
|
223
|
+
|
|
224
|
+
/** Add a warning message if this.warnings exists else log it as a warming */
|
|
225
|
+
warn(message: string): void;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Checks if a dependency has been already added
|
|
229
|
+
* @param {string} key Dependency bucket
|
|
230
|
+
* @param {string} value Dependency to search
|
|
231
|
+
* @returns {boolean} True if the dependency exists on the bucket
|
|
232
|
+
*/
|
|
233
|
+
has(key: string, value: string): boolean;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Returns the existing and target array merged without duplicates
|
|
237
|
+
* @param {Array} existing Partial lattice to merge.
|
|
238
|
+
* @param {Array} target Partial lattice to merge.
|
|
239
|
+
* @returns {Array} existing ∪ (i.e. union) target
|
|
240
|
+
*
|
|
241
|
+
* Adapted from @vue/cli under MIT License:
|
|
242
|
+
* https://github.com/vuejs/vue-cli/blob/f09722c/packages/%40vue/cli/lib/GeneratorAPI.js#L15
|
|
243
|
+
*/
|
|
244
|
+
mergeArrayDeduped(existing: any[], target: any[]): any[];
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Attempts to merge all entries within the `value` provided by
|
|
248
|
+
* the plugin specified by `name` into the `existing` semver-aware
|
|
249
|
+
* Object `key` (e.g. dependencies, etc.) for this instance.
|
|
250
|
+
*
|
|
251
|
+
* Merge algorithm:
|
|
252
|
+
*
|
|
253
|
+
* - ∀ [dep, ver] := Object.entries(value)
|
|
254
|
+
* and [prev] := any existing version for dep
|
|
255
|
+
*
|
|
256
|
+
* - If ver is not valid semver ––> ■
|
|
257
|
+
* - If ¬∃ prev ––> set and blame [dep, ver]
|
|
258
|
+
* - If ver > prev ––> set and blame [dep, ver]
|
|
259
|
+
* - If ¬(ver ∩ prev) ––> Conflict. Print.
|
|
260
|
+
* @param {object} options
|
|
261
|
+
* @param {string} options.key {devD,peerD,optionalD,d}ependencies
|
|
262
|
+
* @param {object} options.value Updates for { name: version } pairs
|
|
263
|
+
* @param {object} options.existing Existing { name: version } pairs
|
|
264
|
+
* @param {string} options.name Plugin name providing merge `value``
|
|
265
|
+
* @param {boolean} [options.force] Should the semver version override other attempts
|
|
266
|
+
*
|
|
267
|
+
* Adapted from @vue/cli under MIT License:
|
|
268
|
+
* https://github.com/vuejs/vue-cli/blob/f09722c/packages/%40vue/cli/lib/util/mergeDeps.js
|
|
269
|
+
*/
|
|
270
|
+
semanticMerge({ key, value, existing, name, force }: {
|
|
271
|
+
key: string;
|
|
272
|
+
value: any;
|
|
273
|
+
existing: any;
|
|
274
|
+
name: string;
|
|
275
|
+
force?: boolean;
|
|
276
|
+
}): void;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Normalizes a potential semver range into a semver string
|
|
280
|
+
* and returns the newest version
|
|
281
|
+
* @param {string} r1 Semver string (potentially invalid).
|
|
282
|
+
* @param {string} r2 Semver string (potentially invalid).
|
|
283
|
+
* @returns {string | undefined} Newest semver version.
|
|
284
|
+
*
|
|
285
|
+
* Adapted from @vue/cli under MIT License:
|
|
286
|
+
* https://github.com/vuejs/vue-cli/blob/f09722c/packages/%40vue/cli/lib/util/mergeDeps.js#L58-L64
|
|
287
|
+
*/
|
|
288
|
+
tryGetNewerRange(r1: string, r2: string): string | undefined;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Performs a naive attempt to take a transform a semver range
|
|
292
|
+
* into a concrete version that may be used for "newness"
|
|
293
|
+
* comparison.
|
|
294
|
+
* @param {string} range Valid "basic" semver: ^X.Y.Z, ~A.B.C, >=2.3.x, 1.x.x
|
|
295
|
+
* @returns {string} Concrete as possible version: X.Y.Z, A.B.C, 2.3.0, 1.0.0
|
|
296
|
+
*/
|
|
297
|
+
rangeToVersion(range: string): string;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Orders top-level keys by `orderBy` options with any fields specified in
|
|
301
|
+
* the `orderFields` options having their keys sorted.
|
|
302
|
+
* @returns {object} Ready to be serialized JavaScript object.
|
|
303
|
+
*/
|
|
304
|
+
toJSON(): object;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Orders the given object, `obj`, applying any (optional)
|
|
308
|
+
* key order specified via `orderBy`. If no `orderBy` is provided
|
|
309
|
+
* keys are ordered lexographically.
|
|
310
|
+
* @param {object} obj Object to transform to ordered keys
|
|
311
|
+
* @param {string[]} [orderBy] Explicit key order to use.
|
|
312
|
+
* @returns {object} Shallow clone of `obj` with ordered keys
|
|
313
|
+
*
|
|
314
|
+
* Adapted from @vue/cli under MIT License:
|
|
315
|
+
* https://github.com/vuejs/vue-cli/blob/f09722c/packages/%40vue/cli/lib/util/sortObject.js
|
|
316
|
+
*/
|
|
317
|
+
toOrderedKeys(obj: object, orderBy?: string[]): object;
|
|
151
318
|
}
|
|
152
319
|
|
|
153
|
-
export
|
|
320
|
+
export class Readme {
|
|
154
321
|
/** Markdown content to be injected into the app readme */
|
|
155
322
|
markdown: string[];
|
|
156
323
|
|
|
157
324
|
/** Links to be added to the footer */
|
|
158
325
|
links: string[];
|
|
159
326
|
|
|
327
|
+
addNewLine(): this;
|
|
328
|
+
|
|
160
329
|
/** Add a markdown heading */
|
|
161
|
-
heading(content: string, level?: number):
|
|
330
|
+
heading(content: string, level?: number): this;
|
|
162
331
|
|
|
163
332
|
/** Add a markdown sub-heading */
|
|
164
|
-
subHeading(content: string):
|
|
333
|
+
subHeading(content: string): this;
|
|
165
334
|
|
|
166
335
|
/** Add markdown content */
|
|
167
336
|
content(markdown: string);
|
|
168
337
|
|
|
169
338
|
/** Add a markdown list */
|
|
170
|
-
list(items: string[]):
|
|
339
|
+
list(items: string[]): this;
|
|
171
340
|
|
|
172
341
|
/** Add a markdown link - printed in footer */
|
|
173
|
-
link(content: string, href: string):
|
|
342
|
+
link(content: string, href: string): this;
|
|
174
343
|
|
|
175
344
|
/** Add a markdown code block */
|
|
176
|
-
codeBlock(content: string, syntax?: string):
|
|
345
|
+
codeBlock(content: string, syntax?: string): this;
|
|
177
346
|
|
|
178
347
|
/** Add markdown file */
|
|
179
|
-
markdownFile(path: string): Promise<
|
|
348
|
+
markdownFile(path: string): Promise<this>;
|
|
180
349
|
}
|
|
181
350
|
|
|
182
|
-
|
|
351
|
+
type NoopPromptObject = {
|
|
352
|
+
[key: string]: any;
|
|
353
|
+
};
|
|
354
|
+
type NoopPromptFunction = () => NoopPromptObject;
|
|
355
|
+
export type CreatePrompt = PromptModule | NoopPromptFunction;
|
|
356
|
+
|
|
357
|
+
export interface CreateCommandOptions {
|
|
358
|
+
presets?: string[];
|
|
359
|
+
npmLink?: string[];
|
|
360
|
+
presetPath?: string[];
|
|
361
|
+
packageManager?: string;
|
|
362
|
+
prompts?: boolean;
|
|
363
|
+
config?: string;
|
|
364
|
+
configFile?: string;
|
|
365
|
+
}
|
|
183
366
|
|
|
184
367
|
declare module 'create-gasket-app' {
|
|
185
|
-
export
|
|
368
|
+
export class CreateContext {
|
|
186
369
|
/** Short name of the app */
|
|
187
370
|
appName: string;
|
|
188
371
|
|
|
@@ -223,9 +406,15 @@ declare module 'create-gasket-app' {
|
|
|
223
406
|
/** any generated files to show in report */
|
|
224
407
|
generatedFiles: Set<string>;
|
|
225
408
|
|
|
409
|
+
/** (INTERNAL) false to skip the prompts */
|
|
410
|
+
prompts: boolean;
|
|
411
|
+
|
|
226
412
|
/** Default empty array, populated by load-preset with actual imports */
|
|
227
413
|
presets: Array<Plugin>;
|
|
228
414
|
|
|
415
|
+
/** temporary directory */
|
|
416
|
+
tmpDir: string;
|
|
417
|
+
|
|
229
418
|
/** Default to object w/empty plugins array to be populated by `presetConfig` hook */
|
|
230
419
|
presetConfig: GasketConfigDefinition;
|
|
231
420
|
|
|
@@ -272,13 +461,16 @@ declare module 'create-gasket-app' {
|
|
|
272
461
|
|
|
273
462
|
/** Use to add content to the README.md */
|
|
274
463
|
readme: Readme;
|
|
464
|
+
|
|
465
|
+
constructor(initContext?: Partial<T>);
|
|
466
|
+
runWith(plugin: Plugin): Proxy<CreateContext>;
|
|
275
467
|
}
|
|
276
468
|
}
|
|
277
469
|
|
|
278
470
|
export interface ActionWrapperParams {
|
|
279
471
|
gasket: GasketEngine;
|
|
280
472
|
context: CreateContext;
|
|
281
|
-
spinner?:
|
|
473
|
+
spinner?: ora.Ora;
|
|
282
474
|
}
|
|
283
475
|
|
|
284
476
|
declare module '@gasket/core' {
|
package/lib/index.js
CHANGED
|
@@ -19,6 +19,9 @@ const gasketBin = program
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
async function main() {
|
|
22
|
+
// Suppress deprecation warning for punycode in node 22
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
process.noDeprecation = true;
|
|
22
25
|
const { command, hidden, isDefault } = processCommand(createCommand);
|
|
23
26
|
await warnIfOutdated(pkg.name, pkg.version);
|
|
24
27
|
gasketBin.addCommand(command, { hidden, isDefault });
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Gasket } from '@gasket/core';
|
|
2
|
+
import type {
|
|
3
|
+
CreateContext,
|
|
4
|
+
CreatePrompt,
|
|
5
|
+
ConfigBuilder,
|
|
6
|
+
CreateCommand,
|
|
7
|
+
CommandArgument,
|
|
8
|
+
CommandOption
|
|
9
|
+
} from './index';
|
|
10
|
+
import type { GasketEngine, Plugin } from '@gasket/core';
|
|
11
|
+
import type ora from 'ora';
|
|
12
|
+
import type { Command, Option } from 'commander';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export type PartialCreateContext = Partial<CreateContext>;
|
|
16
|
+
|
|
17
|
+
export function commasToArray(value: string): string[];
|
|
18
|
+
|
|
19
|
+
/** scaffold */
|
|
20
|
+
|
|
21
|
+
export function readConfig(
|
|
22
|
+
context: PartialCreateContext,
|
|
23
|
+
configFlags: { config?: string; configFile?: string }
|
|
24
|
+
): void;
|
|
25
|
+
|
|
26
|
+
export function dumpErrorContext(context: PartialCreateContext, error: Error): Promise<void>;
|
|
27
|
+
|
|
28
|
+
export function makeCreateContext(argv?: string[], options?: CreateCommandOptions): PartialCreateContext;
|
|
29
|
+
|
|
30
|
+
export function makeCreateRuntime(context: PartialCreateContext, source: Plugin): Proxy<CreateContext>;
|
|
31
|
+
|
|
32
|
+
export function spinnerAction({ gasket, context, spinner } : {
|
|
33
|
+
gasket?: GasketEngine;
|
|
34
|
+
context?: CreateContext;
|
|
35
|
+
spinner?: ora.Ora
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
export function withSpinnerWrapper({ gasket, context } : { gasket: GasketEngine, context: CreateContext }): Promise<void>;
|
|
38
|
+
export function withSpinner(
|
|
39
|
+
label: string,
|
|
40
|
+
fn: spinnerAction,
|
|
41
|
+
options?: { startSpinner?: boolean }
|
|
42
|
+
): withSpinnerWrapper
|
|
43
|
+
|
|
44
|
+
/** sacaffold/actions */
|
|
45
|
+
|
|
46
|
+
export function createHooks({ gasket, context } : { gasket: GasketEngine; context: CreateContext }): Promise<void>;
|
|
47
|
+
|
|
48
|
+
export function chooseAppDescription(context: CreateContext, prompt: CreatePrompt): Promise<void>;
|
|
49
|
+
export function choosePackageManager(context: CreateContext, prompt: CreatePrompt): Promise<void>;
|
|
50
|
+
export function chooseTestPlugins(context: CreateContext, prompt: CreatePrompt): Promise<void>;
|
|
51
|
+
export function promptForTestPlugin(
|
|
52
|
+
prompt: CreatePrompt,
|
|
53
|
+
message: string,
|
|
54
|
+
choices: { name: string; value: string; }[]
|
|
55
|
+
): Promise<string | null>;
|
|
56
|
+
export function allowExtantOverwriting(context: CreateContext, prompt: CreatePrompt): Promise<void>;
|
|
57
|
+
export function globalPrompts({ context } : { context: CreateContext }): Promise<void>;
|
|
58
|
+
|
|
59
|
+
export function loadPresets({ context } : { context: CreateContext }): Promise<void>;
|
|
60
|
+
|
|
61
|
+
export function presetPromptHooks({ gasket, context }: { gasket: GasketEngine; context: CreateContext }): Promise<void>;
|
|
62
|
+
|
|
63
|
+
export function presetConfigHooks({ gasket, context }: { gasket: GasketEngine; context: CreateContext }): Promise<void>;
|
|
64
|
+
|
|
65
|
+
export function promptHooks({ gasket, context }: { gasket: GasketEngine; context: CreateContext }): Promise<void>;
|
|
66
|
+
export function execPluginPrompts(gasket: GasketEngine, context: CreateContext): Promise<void>;
|
|
67
|
+
|
|
68
|
+
export function mkDir({ context, spinner }: { context: CreateContext, spinner: ora.Ora }): Promise<void>;
|
|
69
|
+
|
|
70
|
+
export function setupPkg({ context }: { context: CreateContext }): Promise<void>;
|
|
71
|
+
|
|
72
|
+
export function writePkg({ context }: { context: CreateContext }): Promise<void>;
|
|
73
|
+
|
|
74
|
+
export type Descriptior = {
|
|
75
|
+
pattern: string;
|
|
76
|
+
base: string;
|
|
77
|
+
srcFile: string;
|
|
78
|
+
targetFile: string;
|
|
79
|
+
target: string;
|
|
80
|
+
from: string;
|
|
81
|
+
overrides?: string;
|
|
82
|
+
}
|
|
83
|
+
export function generateFiles({ context, spinner }: { context: CreateContext, spinner: ora.Ora }): Promise<void>;
|
|
84
|
+
export function performGenerate(context: CreateContext, descriptors: Descriptior[]): boolean[];
|
|
85
|
+
export function getDescriptors(context: CreateContext): Promise<Descriptior[]>;
|
|
86
|
+
export function assembleDescriptors(dest: string, from: string, pattern: string, srcPaths: sring[]): Descriptior[];
|
|
87
|
+
export function reduceDescriptors(descriptors: Descriptior[]): Descriptior[];
|
|
88
|
+
|
|
89
|
+
export function writeGasketConfig({ context }: { context: CreateContext }): Promise<void>;
|
|
90
|
+
export function writeImports(imports: object | null): string;
|
|
91
|
+
export function writeExpressions(expressions: string[] | null): string;
|
|
92
|
+
export function createInjectionAssignments(config: object, assignments: (object | null)): string;
|
|
93
|
+
export function cleanupFields(config: ConfigBuilder): void;
|
|
94
|
+
export function writePluginImports(plugins: string[]): string;
|
|
95
|
+
export function replaceInjectionAssignments(content: string, assignments: (object | null)): string;
|
|
96
|
+
|
|
97
|
+
export function installModules({ context }: { context: CreateContext }): Promise<void>;
|
|
98
|
+
|
|
99
|
+
export function linkModules({context, spinner}: { context: CreateContext, spinner: ora.Ora }): Promise<void>;
|
|
100
|
+
|
|
101
|
+
export function postCreateHooks({ gasket, context }: { gasket: GasketEngine, context: CreateContext }): Promise<void>;
|
|
102
|
+
|
|
103
|
+
export function printReport({ context }: { context: CreateContext }): Promise<void>;
|
|
104
|
+
export function buildReport(context: CreateContext): {
|
|
105
|
+
appName?: string;
|
|
106
|
+
output?: string;
|
|
107
|
+
generatedFiles?: string[];
|
|
108
|
+
messages?: string[];
|
|
109
|
+
warnings?: string[];
|
|
110
|
+
errors?: string[];
|
|
111
|
+
nextSteps?: string[];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** utils */
|
|
115
|
+
|
|
116
|
+
export function processCommand(command: CreateCommand): { command: Command, hidden: boolean, isDefault: boolean };
|
|
117
|
+
export function isValidCommand(command: CreateCommand): boolean;
|
|
118
|
+
|
|
119
|
+
export function processArgs(args: CommandArgument[]): [string, string?, any?][];
|
|
120
|
+
export function isValidArg(arg: CommandArgument): boolean;
|
|
121
|
+
|
|
122
|
+
interface OptionDefinition {
|
|
123
|
+
options: [string, string];
|
|
124
|
+
conflicts: CommandOption['conflicts'];
|
|
125
|
+
hidden: CommandOption['hidden'];
|
|
126
|
+
required: CommandOption['required'];
|
|
127
|
+
defaultValue: CommandOption['default'];
|
|
128
|
+
parse: CommandOption['parse']
|
|
129
|
+
};
|
|
130
|
+
export function isValidOption(option: CommandOption): boolean;
|
|
131
|
+
export function processOptions(options: CommandOption[]): OptionDefinition[]
|
|
132
|
+
|
|
133
|
+
export function createOption(definition: OptionDefinition): Option
|
|
@@ -4,20 +4,12 @@ import ora from 'ora';
|
|
|
4
4
|
* Decorate a create action with spinner.
|
|
5
5
|
* If an action throws, a fail spinner will render for the step, regardless of
|
|
6
6
|
* if the spinner was started or not.
|
|
7
|
-
*
|
|
8
|
-
* @param {String} label - Label for the spinner
|
|
9
|
-
* @param {Function} fn - Action to wrap
|
|
10
|
-
* @param {Boolean} startSpinner - Should the spinner start
|
|
11
|
-
* @returns {Function} decorated action
|
|
7
|
+
* @type {import('../internal').withSpinner}
|
|
12
8
|
*/
|
|
13
9
|
export default function withSpinner(label, fn, { startSpinner = true } = {}) {
|
|
14
10
|
/**
|
|
15
11
|
* Decorated function
|
|
16
|
-
*
|
|
17
|
-
* @param {ActionWrapperParams} params - ActionWrapperParams
|
|
18
|
-
* @param {GasketEngine} params.gasket - Gasket config
|
|
19
|
-
* @param {CreateContext} params.context - Create context
|
|
20
|
-
* @returns {Promise} promise
|
|
12
|
+
* @type {import('../internal').withSpinnerWrapper}
|
|
21
13
|
*/
|
|
22
14
|
async function wrapper({ gasket = {}, context }) {
|
|
23
15
|
const spinner = ora(label);
|
|
@@ -6,17 +6,13 @@ import Readme from '../readme.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* Executes the `create` hook for all registered plugins.
|
|
8
8
|
* Adds `files` to context for plugins to add their files and templates.
|
|
9
|
-
*
|
|
10
|
-
* @param {GasketEngine} gasket - Gasket API
|
|
11
|
-
* @param {CreateContext} context - Create context
|
|
12
|
-
* @returns {Promise} promise
|
|
9
|
+
* @type {import('../../internal').createHooks}
|
|
13
10
|
*/
|
|
14
11
|
async function createHooks({ gasket, context }) {
|
|
15
|
-
const {
|
|
16
|
-
|
|
12
|
+
const { warnings } = context;
|
|
17
13
|
const files = new Files();
|
|
18
14
|
const readme = new Readme();
|
|
19
|
-
const gasketConfig = ConfigBuilder.create({}, { orderBy: ['plugins'], warnings
|
|
15
|
+
const gasketConfig = ConfigBuilder.create({}, { orderBy: ['plugins'], warnings });
|
|
20
16
|
Object.assign(context, { files, readme, gasketConfig });
|
|
21
17
|
|
|
22
18
|
await gasket.execApply('create', async function applyCreate(plugin, handler) {
|
|
@@ -20,9 +20,7 @@ const splitSep = pthStr => pthStr.split(reSep);
|
|
|
20
20
|
* Find all duplicate target files and reduce to single descriptor.
|
|
21
21
|
* Keeps track of overrides.
|
|
22
22
|
* Last in wins.
|
|
23
|
-
*
|
|
24
|
-
* @param {object[]} descriptors - Details about files to generate
|
|
25
|
-
* @returns {object[]} descriptors
|
|
23
|
+
* @type {import('../../internal').reduceDescriptors}
|
|
26
24
|
*/
|
|
27
25
|
function reduceDescriptors(descriptors) {
|
|
28
26
|
const reduced = descriptors.reduce((acc, desc) => {
|
|
@@ -43,12 +41,7 @@ function reduceDescriptors(descriptors) {
|
|
|
43
41
|
|
|
44
42
|
/**
|
|
45
43
|
* Assemble the description objects from glob results
|
|
46
|
-
*
|
|
47
|
-
* @param {string} dest - app destination
|
|
48
|
-
* @param {string} from - Plugin source name
|
|
49
|
-
* @param {string} pattern - pattern to glob
|
|
50
|
-
* @param {string[]} srcPaths - resulting paths from glob
|
|
51
|
-
* @returns {object[]} descriptors
|
|
44
|
+
* @type {import('../../internal').assembleDescriptors}
|
|
52
45
|
*/
|
|
53
46
|
function assembleDescriptors(dest, from, pattern, srcPaths) {
|
|
54
47
|
const output = joinSep(splitSep(dest));
|
|
@@ -71,9 +64,7 @@ function assembleDescriptors(dest, from, pattern, srcPaths) {
|
|
|
71
64
|
|
|
72
65
|
/**
|
|
73
66
|
* Build a list of descriptions of all files we want to generate
|
|
74
|
-
*
|
|
75
|
-
* @param {CreateContext} context - Create context
|
|
76
|
-
* @returns {object[]} descriptors
|
|
67
|
+
* @type {import('../../internal').getDescriptors}
|
|
77
68
|
*/
|
|
78
69
|
async function getDescriptors(context) {
|
|
79
70
|
const { dest, files } = context;
|
|
@@ -94,10 +85,7 @@ async function getDescriptors(context) {
|
|
|
94
85
|
|
|
95
86
|
/**
|
|
96
87
|
* Read file content, apply templating, then write out target file.
|
|
97
|
-
*
|
|
98
|
-
* @param {CreateContext} context - Create context
|
|
99
|
-
* @param {object[]} descriptors - Details about files to generate
|
|
100
|
-
* @returns {boolean} hasWarnings
|
|
88
|
+
* @type {import('../../internal').performGenerate}
|
|
101
89
|
*/
|
|
102
90
|
async function performGenerate(context, descriptors) {
|
|
103
91
|
const { warnings, errors, generatedFiles } = context;
|
|
@@ -163,10 +151,7 @@ async function performGenerate(context, descriptors) {
|
|
|
163
151
|
|
|
164
152
|
/**
|
|
165
153
|
* Generate the app files and templates using context
|
|
166
|
-
*
|
|
167
|
-
* @param {CreateContext} context - Create context
|
|
168
|
-
* @param {Spinner} spinner - Spinner
|
|
169
|
-
* @returns {Promise} promise
|
|
154
|
+
* @type {import('../../internal').generateFiles}
|
|
170
155
|
*/
|
|
171
156
|
async function generateFiles({ context, spinner }) {
|
|
172
157
|
const { files } = context;
|
|
@@ -3,10 +3,7 @@ import action from '../action-wrapper.js';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* What is your app description?
|
|
6
|
-
*
|
|
7
|
-
* @param {CreateContext} context - Create context
|
|
8
|
-
* @param {function} prompt - function to prompt user
|
|
9
|
-
* @returns {Promise} promise
|
|
6
|
+
* @type {import('../../internal').chooseAppDescription}
|
|
10
7
|
*/
|
|
11
8
|
async function chooseAppDescription(context, prompt) {
|
|
12
9
|
if (!('appDescription' in context)) {
|
|
@@ -25,10 +22,7 @@ async function chooseAppDescription(context, prompt) {
|
|
|
25
22
|
|
|
26
23
|
/**
|
|
27
24
|
* What package manager do you want to use?
|
|
28
|
-
*
|
|
29
|
-
* @param {CreateContext} context - Create context
|
|
30
|
-
* @param {function} prompt - function to prompt user
|
|
31
|
-
* @returns {Promise} promise
|
|
25
|
+
* @type {import('../../internal').choosePackageManager}
|
|
32
26
|
*/
|
|
33
27
|
async function choosePackageManager(context, prompt) {
|
|
34
28
|
const packageManager =
|
|
@@ -61,10 +55,7 @@ async function choosePackageManager(context, prompt) {
|
|
|
61
55
|
|
|
62
56
|
/**
|
|
63
57
|
* Choose your unit test suite and integration test suite
|
|
64
|
-
*
|
|
65
|
-
* @param {CreateContext} context - Create context
|
|
66
|
-
* @param {function} prompt - function to prompt user
|
|
67
|
-
* @returns {Promise} promise
|
|
58
|
+
* @type {import('../../internal').chooseTestPlugins}
|
|
68
59
|
*/
|
|
69
60
|
async function chooseTestPlugins(context, prompt) {
|
|
70
61
|
const knownTestPlugins = {
|
|
@@ -102,6 +93,10 @@ async function chooseTestPlugins(context, prompt) {
|
|
|
102
93
|
}
|
|
103
94
|
}
|
|
104
95
|
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @type {import('../../internal').promptForTestPlugin}
|
|
99
|
+
*/
|
|
105
100
|
async function promptForTestPlugin(prompt, message, choices) {
|
|
106
101
|
const { testPlugin } = await prompt([
|
|
107
102
|
{
|
|
@@ -118,10 +113,7 @@ async function promptForTestPlugin(prompt, message, choices) {
|
|
|
118
113
|
/**
|
|
119
114
|
* Given that gasket is creating in an already existing directory, it should
|
|
120
115
|
* confirm with the user that it's intentionally overwriting that directory
|
|
121
|
-
*
|
|
122
|
-
* @param {CreateContext} context - Create context
|
|
123
|
-
* @param {function} prompt - function to prompt user
|
|
124
|
-
* @returns {Promise} promise
|
|
116
|
+
* @type {import('../../internal').allowExtantOverwriting}
|
|
125
117
|
*/
|
|
126
118
|
async function allowExtantOverwriting(context, prompt) {
|
|
127
119
|
const { dest, extant } = context;
|
|
@@ -148,12 +140,11 @@ export const questions = [
|
|
|
148
140
|
|
|
149
141
|
/**
|
|
150
142
|
* Fire off prompts for user input
|
|
151
|
-
*
|
|
152
|
-
* @param {CreateContext} context - Create context
|
|
153
|
-
* @returns {Promise} promise
|
|
143
|
+
* @type {import('../../internal').globalPrompts}
|
|
154
144
|
*/
|
|
155
145
|
async function globalPrompts({ context }) {
|
|
156
146
|
const prompt = context.prompts ? inquirer.createPromptModule() : () => ({});
|
|
147
|
+
|
|
157
148
|
for (var fn of questions) {
|
|
158
149
|
await fn(context, prompt);
|
|
159
150
|
}
|
|
@@ -2,9 +2,7 @@ import action from '../action-wrapper.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Installs node_modules using the selected package manager
|
|
5
|
-
*
|
|
6
|
-
* @param {CreateContext} context - Create context
|
|
7
|
-
* @returns {Promise} promise
|
|
5
|
+
* @type {import('../../internal').installModules}
|
|
8
6
|
*/
|
|
9
7
|
async function installModules({ context }) {
|
|
10
8
|
const { pkgManager } = context;
|