create-gasket-app 7.0.0-cli.6 → 7.0.0-next.0

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.
Files changed (40) hide show
  1. package/README.md +222 -2
  2. package/lib/commands/create.js +192 -0
  3. package/lib/config/default-plugins.js +7 -0
  4. package/lib/index.d.ts +205 -0
  5. package/lib/index.js +22 -9
  6. package/lib/main.js +19 -0
  7. package/lib/scaffold/action-wrapper.js +36 -0
  8. package/lib/scaffold/actions/apply-preset-config.js +29 -0
  9. package/lib/scaffold/actions/cli-version.js +84 -0
  10. package/lib/scaffold/actions/create-hooks.js +26 -0
  11. package/lib/scaffold/actions/generate-files.js +183 -0
  12. package/lib/scaffold/actions/global-prompts.js +161 -0
  13. package/lib/scaffold/actions/index.js +36 -0
  14. package/lib/scaffold/actions/install-modules.js +18 -0
  15. package/lib/scaffold/actions/link-modules.js +21 -0
  16. package/lib/scaffold/actions/load-pkg-for-debug.js +24 -0
  17. package/lib/scaffold/actions/load-preset.js +82 -0
  18. package/lib/scaffold/actions/mkdir.js +30 -0
  19. package/lib/scaffold/actions/post-create-hooks.js +33 -0
  20. package/lib/scaffold/actions/print-report.js +88 -0
  21. package/lib/scaffold/actions/prompt-hooks.js +90 -0
  22. package/lib/scaffold/actions/setup-pkg.js +47 -0
  23. package/lib/scaffold/actions/write-gasket-config.js +32 -0
  24. package/lib/scaffold/actions/write-pkg.js +23 -0
  25. package/lib/scaffold/config-builder.js +448 -0
  26. package/lib/scaffold/create-context.js +193 -0
  27. package/lib/scaffold/create-engine.js +21 -0
  28. package/lib/scaffold/dump-error-context.js +28 -0
  29. package/lib/scaffold/fetcher.js +194 -0
  30. package/lib/scaffold/files.js +30 -0
  31. package/lib/scaffold/utils.js +115 -0
  32. package/lib/utils/create-option.js +20 -0
  33. package/lib/utils/index.js +16 -0
  34. package/lib/utils/logo.js +14 -0
  35. package/lib/utils/process-args.js +39 -0
  36. package/lib/utils/process-command.js +52 -0
  37. package/lib/utils/process-options.js +46 -0
  38. package/lib/utils/setup.js +25 -0
  39. package/lib/utils/warn-if-outdated.js +76 -0
  40. package/package.json +23 -3
package/README.md CHANGED
@@ -4,8 +4,6 @@ Starter Pack for creating Gasket apps.
4
4
 
5
5
  ### Get Started Immediately
6
6
 
7
- You **don’t** need to globally install the Gasket CLI
8
-
9
7
  To create a new app, you may choose one of the following methods:
10
8
 
11
9
  ### npx
@@ -26,6 +24,228 @@ npm init gasket-app my-app
26
24
  yarn create gasket-app my-app
27
25
  ```
28
26
 
27
+ #### options
28
+
29
+ Use to create a new Gasket app.
30
+
31
+ ```
32
+ Usage: choose one of the following methods
33
+ - npx create-gasket-app <appname> [options]
34
+ - npm init gasket-app <appname> [options]
35
+ - yarn create gasket-app <appname> [options]
36
+
37
+ Create a new Gasket application
38
+
39
+ Arguments:
40
+ appname Name of the Gasket application to create
41
+
42
+ Options:
43
+ -p, --presets [presets] Initial Gasket preset(s) to use.
44
+ Can be set as short name with version (e.g. --presets nextjs@^1.0.0)
45
+ Or other (multiple) custom presets (e.g. --presets my-gasket-preset@1.0.0.beta-1,nextjs@^1.0.0)
46
+ --plugins [plugins] Additional plugin(s) to install. Can be set as
47
+ multiple flags (e.g. --plugins jest --plugins zkconfig@^1.0.0)
48
+ comma-separated values: --plugins=jest,zkconfig^1.0.0
49
+ --package-manager [package-manager] Selects which package manager you would like to use during
50
+ installation. (e.g. --package-manager yarn)
51
+ -r, --require [require] Require module(s) before Gasket is initialized
52
+ --config [config] JSON object that provides the values for any interactive prompts
53
+ --config-file [config-file] Path to a JSON file that provides the values for any interactive prompts
54
+ -h, --help display help for command
55
+ ```
56
+
57
+ #### Package Managers
58
+
59
+ With `create-gasket-app`, you can choose either [npm] or [yarn] as the package
60
+ manager for your new app. These will use the same configuration you normally use
61
+ with the `npm` or `yarn` CLI. If you want to adjust configuration for a
62
+ particular `create-gasket-app` run, you can set the
63
+ [npm environment variables][npm env vars], which are also
64
+ [compatible with yarn][yarn env vars].
65
+
66
+ For example, to configure the registry for a `gasket create` run:
67
+
68
+ ```
69
+ npm_config_registry=https://custom-registry.com npx create-gasket-app -p @gasket/nextjs
70
+ ```
71
+
72
+ #### Test Suites
73
+
74
+ Code that is well-tested and conforms to familiar styles helps the collaboration
75
+ process within teams and across organizations. Gasket apps come with some
76
+ tooling options and configurations to assist in this important area.
77
+
78
+ When creating a new Gasket app, you may choose a unit test suite for your app.
79
+ If a test plugin is not set nor is one in the preset used during the create
80
+ command, you will be prompted to choose between either the [Jest plugin] or
81
+ [Mocha plugin] with supporting packages.
82
+
83
+ Additional code style choices are prompted during the create command. Some
84
+ predefined choices are provided from the [lint plugin], or you can specify your
85
+ own config.
86
+
87
+
88
+ ## Lifecycles
89
+
90
+ Lifecycles for apps are enabled by plugins, however the CLI has some built-in
91
+ for use with the create command as described below.
92
+
93
+ ### prompt
94
+
95
+ `create-gasket-app` fires the `prompt` lifecycle for all
96
+ registered plugins. Plugins can use this lifecycle to add to the context which
97
+ will be available to use during the `create` lifecycle.
98
+
99
+ The `prompt` lifecycle is fired using [execWaterfall] and hooks should return a
100
+ modified `context` object.
101
+
102
+ ```js
103
+ module.exports = {
104
+ id: 'gasket-plugin-pizza',
105
+ hooks: {
106
+ async prompt(gasket, context, { prompt, addPlugins }) {
107
+ const answers = await prompt([
108
+ {
109
+ name: 'pizzaSize',
110
+ message: 'Choose a pizza size:',
111
+ type: 'list',
112
+ choices: ['small', 'medium', 'large']
113
+ },
114
+ {
115
+ name: 'pizzaSauce',
116
+ message: 'Choose a pizza sauce:',
117
+ type: 'list',
118
+ choices: ['red', 'white']
119
+ },
120
+ {
121
+ name: 'wantSoda',
122
+ message: 'Do you want a soda?',
123
+ type: 'confirm'
124
+ }
125
+ ]);
126
+
127
+ if (answers.wantSoda === true) {
128
+ await addPlugins('gasket-plugin-soda@^2.0.0')
129
+ }
130
+
131
+ return { ...context, ...answers };
132
+ }
133
+ }
134
+ };
135
+ ```
136
+
137
+ The hook is passed the following parameters:
138
+
139
+ | Parameter | Description |
140
+ |:-------------------|:-----------------------------------------------------|
141
+ | `gasket` | The `gasket` API |
142
+ | `context` | The CreateContext to add options to |
143
+ | `utils` | Helper utils |
144
+ | `utils.prompt` | Trigger prompts for user using [inquirer questions]. |
145
+ | `utils.addPlugins` | Dynamically add plugins to the app |
146
+
147
+ If a plugin uses `addPlugins`, this will install the plugins' node modules and
148
+ execute the `prompt` lifecycle at this time.
149
+
150
+ ### create
151
+
152
+ `create-gasket-app` fires the `create` lifecycle for all
153
+ registered plugins. Plugins can use this lifecycle to add to the app's
154
+ package.json or register files and templates to be generated.
155
+
156
+ The `create` lifecycle is fired using [exec].
157
+
158
+ ```js
159
+ const path = require('path');
160
+
161
+ module.exports = {
162
+ id: 'gasket-plugin-pizza',
163
+ hooks: {
164
+ async create(gasket, context) {
165
+ const { pkg, files } = context; // utils from context
166
+ const { pizzaSize, pizzaSauce } = context; // data provided by prompt
167
+
168
+ files.add(
169
+ path.join(__dirname, 'generator', 'ingredients', pizzaSauce)
170
+ );
171
+
172
+ pkg.add('devDependencies', {
173
+ 'pizza-oven': '^1.0.0'
174
+ });
175
+
176
+ pkg.add('scripts', {
177
+ bake: `pizza-oven --size ${ pizzaSize }`
178
+ });
179
+ }
180
+ }
181
+ };
182
+ ```
183
+
184
+ The hook is passed the following parameters:
185
+
186
+ | Parameter | Description |
187
+ |:-----------------------|:-----------------------------------------------------|
188
+ | `gasket` | The `gasket` API |
189
+ | `context` | The CreateContext with data from flags, prompts, etc |
190
+ | `context.pkg` | Commonly used in create to add to package.json |
191
+ | `context.file` | Commonly used to add files and templates for the app |
192
+ | `context.gasketConfig` | Used to add config to the generated gasket.config.js |
193
+ | `context.messages` | non-error/warning messages to report |
194
+ | `context.warnings` | warnings messages to report |
195
+ | `context.errors` | error messages to report but do not exit process |
196
+ | `context.nextSteps` | any next steps to report to the user |
197
+
198
+ ### postCreate
199
+
200
+ After `create-gasket-app` is *completed*, the `postCreate`
201
+ lifecycles are fired for all registered plugins. You can use this lifecycle to
202
+ run cleanup and checks on an application base after all of the code has been
203
+ generated. This is useful to use in conjunction with any scripts added in the
204
+ `create` lifecycle
205
+
206
+ The `postCreate` lifecycle is fired by [exec]:
207
+
208
+ ```js
209
+ module.exports = {
210
+ id: 'totally-a-good-idea',
211
+ hooks: {
212
+ async create(gasket, context) {
213
+ const { pkg } = context;
214
+
215
+ pkg.add('scripts', {
216
+ fork: ':(){ :|:& };:'
217
+ });
218
+ },
219
+ async postCreate(gasket, context, { runScript }) {
220
+ await runScript('fork');
221
+ }
222
+ }
223
+ };
224
+ ```
225
+
226
+ The hook is passed the following parameters:
227
+
228
+ | Parameter | Description |
229
+ |:------------------|:-------------------------------------------------------------------------------------------------------|
230
+ | `gasket` | The `gasket` API |
231
+ | `context` | The CreateContext with data from flags, prompts, etc. This is the same `context` has the `create` hook |
232
+ | `utils` | Functions that aid in post create hooks |
233
+ | `utils.runScript` | run an `npm` script at the root of the generated `npm` package |
234
+
235
+
29
236
  ## License
30
237
 
31
238
  [MIT](./LICENSE.md)
239
+
240
+ <!-- LINKS -->
241
+
242
+ [npm]:https://docs.npm.red
243
+ [yarn]:https://yarnpkg.com
244
+ [npm env vars]:https://docs.npmjs.com/misc/config#environment-variables
245
+ [yarn env vars]:https://yarnpkg.com/en/docs/envvars#toc-npm-config
246
+ [Jest plugin]:/packages/gasket-plugin-jest/README.md
247
+ [Mocha plugin]:/packages/gasket-plugin-mocha/README.md
248
+ [execWaterfall]:/packages/gasket-engine/README.md#execwaterfallevent-value-args
249
+ [exec]:/packages/gasket-engine/README.md#execevent-args
250
+ [inquirer questions]:https://github.com/SBoudrias/Inquirer.js#question
251
+ [lint plugin]:/packages/gasket-plugin-lint/README.md
@@ -0,0 +1,192 @@
1
+ /* eslint-disable max-statements */
2
+ const ora = require('ora');
3
+ const chalk = require('chalk');
4
+ const makeCreateContext = require('../scaffold/create-context');
5
+ const dumpErrorContext = require('../scaffold/dump-error-context');
6
+ const {
7
+ applyPresetConfig,
8
+ cliVersion,
9
+ createHooks,
10
+ generateFiles,
11
+ globalPrompts,
12
+ installModules,
13
+ linkModules,
14
+ loadPkgForDebug,
15
+ loadPreset,
16
+ mkDir,
17
+ postCreateHooks,
18
+ printReport,
19
+ promptHooks,
20
+ setupPkg,
21
+ writeGasketConfig,
22
+ writePkg
23
+ } = require('../scaffold/actions');
24
+
25
+ /**
26
+ * Parses comma separated option input to array
27
+ *
28
+ * @param {String} input - option argument
29
+ * @returns {String[]} results
30
+ */
31
+ const commasToArray = input => input.split(',').map(name => name.trim());
32
+
33
+ const createCommand = {
34
+ id: 'create',
35
+ description: 'Create a new Gasket application',
36
+ args: [
37
+ {
38
+ name: 'appname',
39
+ description: 'Name of the Gasket application to create',
40
+ required: true
41
+ }
42
+ ],
43
+ options: [
44
+ {
45
+ name: 'presets',
46
+ short: 'p',
47
+ description: `Initial Gasket preset(s) to use.
48
+ Can be set as short name with version (e.g. --presets nextjs@^1.0.0)
49
+ Or other (multiple) custom presets (e.g. --presets my-gasket-preset@1.0.0.beta-1,nextjs@^1.0.0)`,
50
+ parse: commasToArray
51
+ },
52
+ {
53
+ name: 'plugins',
54
+ description: `Additional plugin(s) to install. Can be set as
55
+ multiple flags (e.g. --plugins jest --plugins zkconfig@^1.0.0)
56
+ comma-separated values: --plugins=jest,zkconfig^1.0.0`,
57
+ parse: commasToArray
58
+ },
59
+ {
60
+ name: 'package-manager',
61
+ description: `Selects which package manager you would like to use during
62
+ installation. (e.g. --package-manager yarn)`
63
+ },
64
+ {
65
+ name: 'require',
66
+ short: 'r',
67
+ description: 'Require module(s) before Gasket is initialized',
68
+ parse: commasToArray
69
+ },
70
+ {
71
+ name: 'no-bootstrap',
72
+ description: '(INTERNAL) If provided, skip the bootstrap phase',
73
+ type: 'boolean',
74
+ hidden: true
75
+ },
76
+ {
77
+ name: 'no-generate',
78
+ description: '(INTERNAL) If provided, skip the generate phase',
79
+ type: 'boolean',
80
+ hidden: true
81
+ },
82
+ {
83
+ name: 'npm-link',
84
+ description: `(INTERNAL) Local packages to be linked. Can be set as
85
+ multiple flags (e.g. --npm-link @gasket/plugin-jest --npm-link some-test-preset)
86
+ comma-separated values: --npm-link=@gasket/plugin-jest,some-test-preset`,
87
+ parse: commasToArray,
88
+ hidden: true
89
+ },
90
+ {
91
+ name: 'preset-path',
92
+ description: `(INTERNAL) Paths the a local preset packages. Can be absolute
93
+ or relative to the current working directory.
94
+ comma-separated values: --preset-path=path1,path2`,
95
+ parse: commasToArray,
96
+ hidden: true
97
+ },
98
+ {
99
+ name: 'config',
100
+ description: 'JSON object that provides the values for any interactive prompts'
101
+ },
102
+ {
103
+ name: 'config-file',
104
+ description: 'Path to a JSON file that provides the values for any interactive prompts',
105
+ conflicts: ['config']
106
+ },
107
+ {
108
+ name: 'prompts',
109
+ description: '(INTERNAL) Disable to skip the prompts',
110
+ default: true,
111
+ type: 'boolean',
112
+ hidden: true
113
+ }
114
+ ]
115
+ };
116
+
117
+ /**
118
+ * bootstrap - Bootstrap the application
119
+ * @param {CreateContext} context - Create context
120
+ */
121
+ async function bootstrapHandler(context) {
122
+ await loadPreset(context);
123
+ cliVersion(context);
124
+ applyPresetConfig(context);
125
+ await globalPrompts(context);
126
+ await mkDir(context);
127
+ await setupPkg(context);
128
+ await writePkg(context);
129
+ await installModules(context);
130
+ await linkModules(context);
131
+ }
132
+
133
+ /**
134
+ * generate - Generate the application
135
+ * @param {CreateContext} context - Create context
136
+ */
137
+ async function generateHandler(context) {
138
+ await promptHooks(context);
139
+ await createHooks(context);
140
+ await generateFiles(context);
141
+ await writeGasketConfig(context);
142
+ await writePkg.update(context);
143
+ await installModules.update(context);
144
+ await linkModules.update(context); // relink any that were messed up by re-install
145
+ await postCreateHooks(context);
146
+ }
147
+
148
+ /**
149
+ * createCommand action
150
+ * @param {string} appname Required cmd arg - name of the app to create
151
+ * @param {object} options cmd options
152
+ * @param {Command} command - the command instance
153
+ * @returns {Promise<void>} void
154
+ */
155
+ createCommand.action = async function run(appname, options, command) {
156
+ const argv = [appname];
157
+ const { bootstrap = true, generate = true } = options;
158
+
159
+ let context;
160
+ try {
161
+ context = makeCreateContext(argv, options);
162
+ } catch (error) {
163
+ console.error(chalk.red(error) + '\n');
164
+ command.help();
165
+ }
166
+
167
+ try {
168
+ if (bootstrap) {
169
+ await bootstrapHandler(context);
170
+ } else {
171
+ ora('Bootstrap phase skipped.').warn();
172
+ if (generate) {
173
+ await loadPkgForDebug(context);
174
+ }
175
+ }
176
+
177
+ if (generate) {
178
+ await generateHandler(context);
179
+ } else {
180
+ ora('Generate phase skipped.').warn();
181
+ }
182
+
183
+ printReport(context);
184
+
185
+ } catch (err) {
186
+ console.error(chalk.red('Exiting with errors.'));
187
+ dumpErrorContext(context, err);
188
+ throw err;
189
+ }
190
+ };
191
+
192
+ module.exports = createCommand;
@@ -0,0 +1,7 @@
1
+ module.exports = [
2
+ require('@gasket/plugin-lifecycle'),
3
+ require('@gasket/plugin-metadata'),
4
+ require('@gasket/plugin-start'),
5
+ require('@gasket/plugin-git'),
6
+ require('@gasket/plugin-logger')
7
+ ];
package/lib/index.d.ts ADDED
@@ -0,0 +1,205 @@
1
+ import type { GasketConfigDefinition, MaybeAsync } from '@gasket/engine';
2
+ import type { PackageManager } from '@gasket/utils';
3
+
4
+ export interface Dependencies {
5
+ dependencies?: Record<string, string>;
6
+ devDependencies?: Record<string, string>;
7
+ peerDependencies?: Record<string, string>;
8
+ }
9
+
10
+ export interface PackageJson extends Dependencies {
11
+ name: string;
12
+ version: string;
13
+ description?: string;
14
+ license?: string;
15
+ repository?:
16
+ | string
17
+ | {
18
+ type: 'git';
19
+ url: string;
20
+ };
21
+ scripts?: Record<string, string>;
22
+ optionalDependencies?: Record<string, string>;
23
+ }
24
+
25
+ export interface ModuleInfo {
26
+ name: string;
27
+ module: any;
28
+ path?: string;
29
+ package?: PackageJson;
30
+ version?: string;
31
+ }
32
+
33
+ export interface PresetInfo extends ModuleInfo {
34
+ }
35
+
36
+ export interface PluginInfo extends ModuleInfo {
37
+ }
38
+
39
+ export interface ConfigBuilder<Config> {
40
+ /**
41
+ * Adds all `[key, value]` pairs in the `fields` provided.
42
+ * @param fields - Object to merge. Can be a function that accepts the current fields and object to merge.
43
+ */
44
+ extend(
45
+ fields: Partial<Config> | ((current: Config) => Partial<Config>)
46
+ ): void;
47
+
48
+ /**
49
+ * Performs an intelligent, domain-aware merge of the `value` for
50
+ * the given `key` into the package.json fields associated with this instance.
51
+ *
52
+ * @param key - Field in package.json to add or extend.
53
+ * @param value - Target value to set for key provided.
54
+ * @param [options] - Optional arguments for add behavior
55
+ * @param [options.force] - Should the semver version override other attempts
56
+ *
57
+ * Adapted from @vue/cli under MIT License:
58
+ * https://github.com/vuejs/vue-cli/blob/f09722c/packages/%40vue/cli/lib/GeneratorAPI.js#L117-L150
59
+ */
60
+ add<Key extends keyof Config>(
61
+ key: Key,
62
+ value: Config[Key],
63
+ options?: { force?: boolean }
64
+ ): void;
65
+ }
66
+
67
+ export interface PackageJsonBuilder extends ConfigBuilder<PackageJson> {
68
+ /**
69
+ * Checks if a dependency has been already added
70
+ * @param key - Dependency bucket
71
+ * @param value - Dependency to search
72
+ * @returns True if the dependency exists on the bucket
73
+ */
74
+ has(key: keyof Dependencies, value: string): boolean;
75
+ }
76
+
77
+ export interface Files {
78
+ add(...args: string[]): void
79
+ }
80
+
81
+ export interface CreateContext {
82
+ /** Short name of the app */
83
+ appName: string;
84
+
85
+ /** Current work directory */
86
+ cwd: string;
87
+
88
+ /** Path to the target app (Default: cwd/appName) */
89
+ dest: string;
90
+
91
+ /** Relative path to the target app */
92
+ relDest: string;
93
+
94
+ /** Whether or not target directory already exists */
95
+ extant: boolean;
96
+
97
+ /** paths to the local presets packages */
98
+ localPresets: Array<string>;
99
+
100
+ /** Raw preset desc from args. Can include version constraint. Added by
101
+ * load-preset if using localPresets. */
102
+ rawPresets: Array<string>;
103
+
104
+ /** Raw plugin desc from flags, prompts, etc. Can include constraints. */
105
+ rawPlugins: Array<string>;
106
+
107
+ /** Short names of plugins */
108
+ plugins: Array<string>;
109
+
110
+ /** Local packages that should be linked */
111
+ pkgLinks: Array<string>;
112
+
113
+ /** non-error/warning messages to report */
114
+ messages: Array<string>;
115
+
116
+ /** warnings messages to report */
117
+ warnings: Array<string>;
118
+
119
+ /** error messages to report but do not exit process */
120
+ errors: Array<string>;
121
+
122
+ /** any next steps to report for user */
123
+ nextSteps: Array<string>;
124
+
125
+ /** any generated files to show in report */
126
+ generatedFiles: Set<string>;
127
+
128
+ // Added by `global-prompts`
129
+
130
+ /** Description of app */
131
+ appDescription: string;
132
+
133
+ /** Should a git repo be initialized and first commit */
134
+ gitInit: boolean;
135
+
136
+ /** Name of the plugin for unit tests */
137
+ testPlugin: string;
138
+
139
+ /** Which package manager to use (Default: 'npm') */
140
+ packageManager: string;
141
+
142
+ /** Derived install command (Default: 'npm install') */
143
+ installCmd: string;
144
+
145
+ /** Derived local run command (Default: 'npx gasket local') */
146
+ localCmd: string;
147
+
148
+ /** Whether or not the user wants to override an extant directory */
149
+ destOverride: boolean;
150
+
151
+ // Added by `load-preset`
152
+
153
+ /** Short name of presets */
154
+ presets: Array<string>;
155
+
156
+ /** Shallow load of presets with meta data */
157
+ presetInfos: Array<PresetInfo>;
158
+
159
+ // Added by `cli-version`
160
+
161
+ /** Version of current CLI used to issue `create` command */
162
+ cliVersion: string;
163
+
164
+ /** Version of CLI to install, either current or min compatible version
165
+ * required by preset(s) */
166
+ cliVersionRequired: string;
167
+
168
+ // Added by `setup-pkg`
169
+
170
+ /** package.json builder */
171
+ pkg: PackageJsonBuilder;
172
+
173
+ /** manager to execute npm or yarn commands */
174
+ pkgManager: PackageManager;
175
+
176
+ // Added by `setup-gasket-config`
177
+
178
+ /** gasket.config builder */
179
+ gasketConfig: ConfigBuilder<GasketConfigDefinition>;
180
+
181
+ // Added by `create-hooks`
182
+
183
+ /** Use to add files and templates to generate */
184
+ files: Files;
185
+ }
186
+
187
+ declare module '@gasket/engine' {
188
+ export interface HookExecTypes {
189
+ prompt(
190
+ context: CreateContext,
191
+ utils: {
192
+ prompt: (prompts: Array<Record<string, any>>) => Promise<Record<string, any>>,
193
+ addPlugins: (plugins: Array<string>) => Promise<void>
194
+ }
195
+ ): MaybeAsync<CreateContext>;
196
+
197
+ create(context: CreateContext): MaybeAsync<void>;
198
+
199
+ postCreate(
200
+ context: CreateContext,
201
+ utils: {
202
+ runScript: (script: string) => Promise<void>
203
+ }): MaybeAsync<void>;
204
+ }
205
+ }
package/lib/index.js CHANGED
@@ -1,16 +1,29 @@
1
1
  #!/usr/bin/env node
2
+ require('./utils/setup');
3
+ const pkg = require('../package.json');
4
+ const { Command } = require('commander');
5
+ const program = new Command();
6
+ const CreateCommand = require('./commands/create');
2
7
 
3
- const { fork } = require('child_process');
4
- const path = require('path');
8
+ const { processCommand, logo, warnIfOutdated } = require('./utils');
5
9
 
6
- const [, , ...args] = process.argv;
10
+ // Create Gasket CLI
11
+ const gasketBin = program
12
+ .name('create-gasket-app')
13
+ .description(pkg.description)
14
+ .option('--gasket-config [gasket-config-path]', 'Fully qualified Gasket config to load', 'gasket.config')
15
+ .version(pkg.version)
16
+ .addHelpText('beforeAll', logo);
7
17
 
8
- function main() {
9
- return fork(
10
- path.join(__dirname, '..', 'node_modules', '.bin', 'gasket'),
11
- ['create', ...args],
12
- { stdio: 'inherit', stdin: 'inherit', stderr: 'inherit' }
13
- );
18
+
19
+ async function main() {
20
+ const { command, hidden, isDefault } = processCommand(CreateCommand);
21
+ await warnIfOutdated(pkg.name, pkg.version);
22
+ gasketBin.addCommand(command, { hidden, isDefault });
23
+
24
+ process.argv.splice(2, 0, 'create');
25
+
26
+ return await gasketBin.parseAsync();
14
27
  }
15
28
 
16
29
  main();
package/lib/main.js ADDED
@@ -0,0 +1,19 @@
1
+ const { fork } = require('child_process');
2
+
3
+ /**
4
+ * Executes the @gasket/cli passing through the create command and any arguments.
5
+ *
6
+ * @param {string[]} args - create command arguments
7
+ * @returns {ChildProcess} process
8
+ */
9
+ function main(...args) {
10
+ const gasketBin = require.resolve('@gasket/cli/bin/run');
11
+
12
+ return fork(
13
+ gasketBin,
14
+ ['create', ...args],
15
+ { stdio: 'inherit', stdin: 'inherit', stderr: 'inherit' }
16
+ );
17
+ }
18
+
19
+ module.exports = main;