create-gasket-app 7.0.3-cli.0 → 7.0.4
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/README.md +223 -3
- package/lib/commands/create.js +149 -0
- package/lib/config/default-plugins.js +15 -0
- package/lib/index.d.ts +310 -0
- package/lib/index.js +24 -9
- package/lib/scaffold/action-wrapper.js +37 -0
- package/lib/scaffold/actions/create-hooks.js +27 -0
- package/lib/scaffold/actions/generate-files.js +189 -0
- package/lib/scaffold/actions/global-prompts.js +162 -0
- package/lib/scaffold/actions/index.js +33 -0
- package/lib/scaffold/actions/install-modules.js +15 -0
- package/lib/scaffold/actions/link-modules.js +19 -0
- package/lib/scaffold/actions/load-preset.js +60 -0
- package/lib/scaffold/actions/mkdir.js +30 -0
- package/lib/scaffold/actions/post-create-hooks.js +31 -0
- package/lib/scaffold/actions/preset-config-hooks.js +13 -0
- package/lib/scaffold/actions/preset-prompt-hooks.js +17 -0
- package/lib/scaffold/actions/print-report.js +89 -0
- package/lib/scaffold/actions/prompt-hooks.js +43 -0
- package/lib/scaffold/actions/setup-pkg.js +34 -0
- package/lib/scaffold/actions/write-gasket-config.js +119 -0
- package/lib/scaffold/actions/write-pkg.js +19 -0
- package/lib/scaffold/config-builder.js +526 -0
- package/lib/scaffold/create-context.js +188 -0
- package/lib/scaffold/dump-error-context.js +28 -0
- package/lib/scaffold/files.js +30 -0
- package/lib/scaffold/readme.js +51 -0
- package/lib/scaffold/utils.js +22 -0
- package/lib/utils/create-option.js +18 -0
- package/lib/utils/index.js +5 -0
- package/lib/utils/logo.js +12 -0
- package/lib/utils/process-args.js +37 -0
- package/lib/utils/process-command.js +50 -0
- package/lib/utils/process-options.js +44 -0
- package/package.json +36 -9
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/* eslint-disable max-len, max-statements */
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { readConfig } from '../scaffold/utils.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The CreateRuntime represents a shallow proxy to a CreateContext
|
|
8
|
+
* that automatically adds transactional information for providing
|
|
9
|
+
* CLI users with blame information in the event of conflicts.
|
|
10
|
+
*
|
|
11
|
+
* @param {CreateContext} context - Create context.
|
|
12
|
+
* @param {Plugin} source - Gasket plugin the create context is within.
|
|
13
|
+
* @returns {Proxy} Shallow proxy to the `context` provided that will
|
|
14
|
+
* pass `source` to `context.{files,pkg}.*` methods.
|
|
15
|
+
*/
|
|
16
|
+
function makeCreateRuntime(context, source) {
|
|
17
|
+
//
|
|
18
|
+
// Create a set of overrides for our Proxy
|
|
19
|
+
//
|
|
20
|
+
const overrides = {
|
|
21
|
+
source,
|
|
22
|
+
files: {
|
|
23
|
+
add(...globs) {
|
|
24
|
+
context.files.add({ globs, source });
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
pkg: {
|
|
28
|
+
extend(fields) {
|
|
29
|
+
context.pkg.extend(fields, source);
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
add(key, value, options) {
|
|
33
|
+
context.pkg.add(key, value, source, options);
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
has(key, value) {
|
|
37
|
+
return context.pkg.has(key, value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return new Proxy(context, {
|
|
43
|
+
get(obj, key) {
|
|
44
|
+
if (overrides[key]) return overrides[key];
|
|
45
|
+
return obj[key];
|
|
46
|
+
},
|
|
47
|
+
set(obj, key, value) {
|
|
48
|
+
if (key !== 'pkg' && key !== 'files' && key !== 'source') {
|
|
49
|
+
obj[key] = value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function flatten(acc, values) {
|
|
56
|
+
return acc.concat(values);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create Context
|
|
61
|
+
*
|
|
62
|
+
* @type {CreateContext}
|
|
63
|
+
*
|
|
64
|
+
* -- Added by command args and options
|
|
65
|
+
*
|
|
66
|
+
* @property {String} appName - Short name of the app
|
|
67
|
+
* @property {String} cwd - Current work directory
|
|
68
|
+
* @property {String} dest - Path to the target app (Default: cwd/appName)
|
|
69
|
+
* @property {String} relDest - Relative path to the target app
|
|
70
|
+
* @property {Boolean} extant - Whether or not target directory already exists
|
|
71
|
+
* @property {[String]} localPresets - paths to the local presets packages
|
|
72
|
+
* @property {PresetDesc[]} rawPresets - Raw preset desc from args. Can include version constraint. Added by load-preset if using localPresets.
|
|
73
|
+
* @property {String[]} pkgLinks - Local packages that should be linked
|
|
74
|
+
* @property {String[]} messages - non-error/warning messages to report
|
|
75
|
+
* @property {String[]} warnings - warnings messages to report
|
|
76
|
+
* @property {String[]} errors - error messages to report but do not exit process
|
|
77
|
+
* @property {String[]} nextSteps - any next steps to report for user
|
|
78
|
+
* @property {Set<String>} generatedFiles - any generated files to show in report
|
|
79
|
+
* @property {any[]} presets - Default empty array, populated by load-preset with actual imports
|
|
80
|
+
* @property {Object} presetConfig - Default to object w/empty plugins array to be populated by `presetConfig` hook
|
|
81
|
+
*
|
|
82
|
+
* -- Added by `global-prompts`
|
|
83
|
+
*
|
|
84
|
+
* @property {String} appDescription - Description of app
|
|
85
|
+
* @property {Boolean} gitInit - Should a git repo be initialized and first commit
|
|
86
|
+
* @property {String} testPlugins - Array of testing plugins
|
|
87
|
+
* @property {String} packageManager - Which package manager to use (Default: 'npm')
|
|
88
|
+
* @property {String} installCmd - Derived install command (Default: 'npm install')
|
|
89
|
+
* @property {String} localCmd - Derived local run command (Default: 'npx gasket local')
|
|
90
|
+
* @property {Boolean} destOverride - Whether or not the user wants to override an extant directory
|
|
91
|
+
*
|
|
92
|
+
* -- Added by `load-preset`
|
|
93
|
+
*
|
|
94
|
+
* @property {PresetName[]} presets - Short name of presets
|
|
95
|
+
*
|
|
96
|
+
*
|
|
97
|
+
* -- Added by `setup-pkg`
|
|
98
|
+
*
|
|
99
|
+
* @property {ConfigBuilder} pkg - package.json builder
|
|
100
|
+
* @property {PackageManager} pkgManager - manager to execute npm or yarn commands
|
|
101
|
+
*
|
|
102
|
+
* -- Added by `setup-gasket-config`
|
|
103
|
+
*
|
|
104
|
+
* @property {ConfigBuilder} gasketConfig - gasket.config builder
|
|
105
|
+
*
|
|
106
|
+
* -- Added by `create-hooks`
|
|
107
|
+
*
|
|
108
|
+
* @property {Files} files - Use to add files and templates to generate
|
|
109
|
+
*/
|
|
110
|
+
export class CreateContext {
|
|
111
|
+
constructor(initContext = {}) {
|
|
112
|
+
Object.assign(this, initContext);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
runWith(plugin) {
|
|
116
|
+
return makeCreateRuntime(this, plugin);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Makes the initial context used through the create command flow.
|
|
122
|
+
*
|
|
123
|
+
* @param {String[]} argv - Commands args
|
|
124
|
+
* @param {Object} options - Command options
|
|
125
|
+
* @returns {CreateContext} context
|
|
126
|
+
*/
|
|
127
|
+
export function makeCreateContext(argv = [], options = {}) {
|
|
128
|
+
const appName = argv[0] || 'templated-app';
|
|
129
|
+
const {
|
|
130
|
+
presets = [],
|
|
131
|
+
npmLink = [],
|
|
132
|
+
presetPath = [],
|
|
133
|
+
packageManager,
|
|
134
|
+
prompts,
|
|
135
|
+
config,
|
|
136
|
+
configFile
|
|
137
|
+
} = options;
|
|
138
|
+
|
|
139
|
+
// Flatten the array of array created by the plugins flag – it
|
|
140
|
+
// supports both multiple instances as well as comma-separated lists.
|
|
141
|
+
const rawPresets = presets.reduce(flatten, []);
|
|
142
|
+
const localPresets = presetPath.reduce(flatten, []);
|
|
143
|
+
const pkgLinks = npmLink.reduce(flatten, []);
|
|
144
|
+
const cwd = process.cwd();
|
|
145
|
+
const dest = path.join(cwd, appName);
|
|
146
|
+
const relDest = `.${path.sep}${path.relative(cwd, dest)}`;
|
|
147
|
+
// eslint-disable-next-line no-sync
|
|
148
|
+
const extant = fs.existsSync(dest);
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Input context which will be appended by prompts and passed to create hooks
|
|
152
|
+
*
|
|
153
|
+
* @type {CreateContext}
|
|
154
|
+
*/
|
|
155
|
+
const context = new CreateContext({
|
|
156
|
+
destOverride: true,
|
|
157
|
+
cwd,
|
|
158
|
+
dest,
|
|
159
|
+
relDest,
|
|
160
|
+
extant,
|
|
161
|
+
pkgLinks,
|
|
162
|
+
localPresets,
|
|
163
|
+
rawPresets,
|
|
164
|
+
messages: [],
|
|
165
|
+
warnings: [],
|
|
166
|
+
errors: [],
|
|
167
|
+
nextSteps: [],
|
|
168
|
+
generatedFiles: new Set(),
|
|
169
|
+
prompts,
|
|
170
|
+
presets: [],
|
|
171
|
+
presetConfig: {
|
|
172
|
+
plugins: []
|
|
173
|
+
},
|
|
174
|
+
readme: []
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
readConfig(context, { config, configFile });
|
|
178
|
+
|
|
179
|
+
if (packageManager) {
|
|
180
|
+
context.packageManager = packageManager;
|
|
181
|
+
}
|
|
182
|
+
if (appName) {
|
|
183
|
+
context.appName = appName;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return context;
|
|
187
|
+
}
|
|
188
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { writeFile } from 'fs/promises';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* If an error occurs during create, dump the context for debugging.
|
|
6
|
+
* The error which cause the exit is also included in the log.
|
|
7
|
+
*
|
|
8
|
+
* @param {CreateContext} context - Create context
|
|
9
|
+
* @param {Error} error - Exiting error
|
|
10
|
+
* @returns {Promise<void>} promise
|
|
11
|
+
*/
|
|
12
|
+
export async function dumpErrorContext(context, error) {
|
|
13
|
+
const { cwd } = context;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const report = { exitError: error.stack, ...context };
|
|
17
|
+
const fileName = 'gasket-create-error.log';
|
|
18
|
+
|
|
19
|
+
const filePath = path.join(cwd, fileName);
|
|
20
|
+
await writeFile(filePath, JSON.stringify(report, null, 2), 'utf8');
|
|
21
|
+
console.log(`Error log dumped to: ${filePath}`);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
//
|
|
24
|
+
// eat but print any errors during writing log file
|
|
25
|
+
//
|
|
26
|
+
console.error(`Error writing error log: ${err}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for plugins to add files and templates for generating
|
|
3
|
+
*
|
|
4
|
+
* @type {Files}
|
|
5
|
+
*/
|
|
6
|
+
export class Files {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.globSets = [];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Return array of globs
|
|
13
|
+
*
|
|
14
|
+
* @deprecated
|
|
15
|
+
* @returns {string[]} `globby` compatible patterns
|
|
16
|
+
*/
|
|
17
|
+
get globs() {
|
|
18
|
+
return this.globSets.reduce((acc, cur) => [...acc, ...cur.globs], []);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Adds the specified `globby` compatible patterns, `globs`,
|
|
23
|
+
* into the set of all sources for this set of files.
|
|
24
|
+
* @param {string[]} globs - `globby` compatible patterns
|
|
25
|
+
* @param {Object} source - Plugin to blame if conflicts arise from this operation.
|
|
26
|
+
*/
|
|
27
|
+
add({ globs, source }) {
|
|
28
|
+
this.globSets.push({ globs, source });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
|
|
3
|
+
/** @type {import('../index').Readme} */
|
|
4
|
+
export default class Readme {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.markdown = [];
|
|
7
|
+
this.links = [];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
addNewLine() {
|
|
11
|
+
this.markdown.push('');
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
heading(content, level = 2) {
|
|
16
|
+
this.markdown.push(`${'#'.repeat(level)} ${content}`);
|
|
17
|
+
return this.addNewLine();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
subHeading(content) {
|
|
21
|
+
return this.heading(content, 3);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
content(content) {
|
|
25
|
+
this.markdown.push(content);
|
|
26
|
+
return this.addNewLine();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
list(items) {
|
|
30
|
+
this.markdown.push(...items.map(item => `- ${item}`));
|
|
31
|
+
return this.addNewLine();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
link(content, href) {
|
|
35
|
+
this.links.push(`[${content}]: ${href}`);
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
codeBlock(content, syntax = '') {
|
|
40
|
+
this.markdown.push(`\`\`\`${syntax}`);
|
|
41
|
+
this.markdown.push(content);
|
|
42
|
+
this.markdown.push('```');
|
|
43
|
+
return this.addNewLine();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async markdownFile(path) {
|
|
47
|
+
const content = await readFile(path, 'utf8');
|
|
48
|
+
this.markdown.push(content);
|
|
49
|
+
return this.addNewLine();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parses JSON file or string to assign to context
|
|
7
|
+
*
|
|
8
|
+
* @param {CreateContext} context - Create context.
|
|
9
|
+
* @param {Object} configFlags - flags to read config from
|
|
10
|
+
* @param {string} configFlags.config - JSON string of config values
|
|
11
|
+
* @param {string} configFlags.configFile - path to JSON file of config values
|
|
12
|
+
*/
|
|
13
|
+
export function readConfig(context, { config, configFile }) {
|
|
14
|
+
if (config) {
|
|
15
|
+
const parsedConfig = JSON.parse(config);
|
|
16
|
+
Object.assign(context, parsedConfig);
|
|
17
|
+
} else if (configFile) {
|
|
18
|
+
const parsedConfigFile = require(path.resolve(context.cwd, configFile));
|
|
19
|
+
Object.assign(context, parsedConfigFile);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Option } from 'commander';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* createOption - Create a commander option
|
|
5
|
+
* @param {CLICommandOption} definition - The option configuration
|
|
6
|
+
* @returns {CommnaderOption} option
|
|
7
|
+
*/
|
|
8
|
+
export function createOption(definition) {
|
|
9
|
+
const option = new Option(...definition.options);
|
|
10
|
+
const { defaultValue, conflicts, parse, hidden, required } = definition;
|
|
11
|
+
|
|
12
|
+
if (conflicts.length) option.conflicts(definition.conflicts);
|
|
13
|
+
if (hidden) option.hideHelp();
|
|
14
|
+
if (typeof defaultValue !== 'undefined') option.default(defaultValue);
|
|
15
|
+
if (parse) option.argParser(parse);
|
|
16
|
+
if (required) option.makeOptionMandatory();
|
|
17
|
+
return option;
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const logo = `
|
|
2
|
+
▄▄▄▄████▀▀█▄
|
|
3
|
+
▄████▀▀▀▀▀▀█▄▄██
|
|
4
|
+
███▀ ▄▄▄▄▄ ▀██▌ ▄▄▄
|
|
5
|
+
▄███ ███▀▀▀▀██ ██ ██ ██
|
|
6
|
+
█▀▀█ ██▌ ▐█▌ ▄▀▀▀█▄ ▄█▀▀▀▄ ██ ▐██▀ ▄█▀▀█▄ ▀██▀▀
|
|
7
|
+
█▄▄█ ██▌ ▀▀██ ▐█▌ ▄▄▄▄██ ▀▀█▄▄▄ █████ ██▄▄██ ██
|
|
8
|
+
▀███ ███▄▄▄▄██ ██ ▀▄▄▄▀█▄ ▀▄▄▄█▀ ▄██▄ ██▄ ▀█▄▄▄▄ ▀█▄▄
|
|
9
|
+
███▄ ▀▀▀ ▀▀ ▄██▌
|
|
10
|
+
▀████▄▄▄▄▄▄█▀▀██
|
|
11
|
+
▀▀▀▀████▄▄█▀
|
|
12
|
+
`;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* isValidArg - Validates the argument configuration
|
|
3
|
+
* @param {CLICommandArg} arg The argument configuration
|
|
4
|
+
* @returns {boolean} True if valid, false otherwise
|
|
5
|
+
*/
|
|
6
|
+
function isValidArg(arg) {
|
|
7
|
+
const keys = Object.keys(arg);
|
|
8
|
+
if (arg.required && arg.default) return false;
|
|
9
|
+
return keys.length &&
|
|
10
|
+
keys.length <= 4 &&
|
|
11
|
+
arg.name && arg.description;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* processArgs - Process the arguments configuration
|
|
16
|
+
* @param {CLICommandArg[]} args Array of argument configurations
|
|
17
|
+
* @returns {ProccesedCLICommandArg[]} Array of argument definitions
|
|
18
|
+
*/
|
|
19
|
+
export function processArgs(args) {
|
|
20
|
+
if (!Array.isArray(args) || !args.every(isValidArg)) throw new Error('Invalid argument(s) configuration');
|
|
21
|
+
|
|
22
|
+
return args.reduce((acc, arg) => {
|
|
23
|
+
const def = [];
|
|
24
|
+
const { name, description, required = false, default: defaultValue } = arg;
|
|
25
|
+
if (required) {
|
|
26
|
+
def.push(`<${name}>`, description);
|
|
27
|
+
} else {
|
|
28
|
+
def.push(`[${name}]`, description);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (defaultValue) def.push(defaultValue);
|
|
32
|
+
|
|
33
|
+
acc.push(def);
|
|
34
|
+
return acc;
|
|
35
|
+
|
|
36
|
+
}, []);
|
|
37
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { processArgs } from './process-args.js';
|
|
3
|
+
import { processOptions } from './process-options.js';
|
|
4
|
+
import { createOption } from './create-option.js';
|
|
5
|
+
const program = new Command();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* isValidCommand - Validates the command configuration
|
|
9
|
+
* @param {CLICommand} command The command configuration
|
|
10
|
+
* @returns {boolean} True if valid, false otherwise
|
|
11
|
+
*/
|
|
12
|
+
function isValidCommand(command) {
|
|
13
|
+
const keys = Object.keys(command);
|
|
14
|
+
return keys.length &&
|
|
15
|
+
keys.length <= 7 &&
|
|
16
|
+
command &&
|
|
17
|
+
command.id &&
|
|
18
|
+
command.description &&
|
|
19
|
+
command.action &&
|
|
20
|
+
typeof command.action === 'function';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* processCommand - Process the command configuration
|
|
25
|
+
* @param {CLICommand} command The command configuration
|
|
26
|
+
* @returns {ProccesedCLICommand} The command instance
|
|
27
|
+
*/
|
|
28
|
+
export function processCommand(command) {
|
|
29
|
+
if (!isValidCommand(command)) throw new Error('Invalid command configuration');
|
|
30
|
+
const { id, description, action, args, options, hidden = false, default: isDefault = false } = command;
|
|
31
|
+
const cmd = program
|
|
32
|
+
.command(id)
|
|
33
|
+
.description(description)
|
|
34
|
+
.action(action);
|
|
35
|
+
|
|
36
|
+
if (args) {
|
|
37
|
+
const cmdArgs = processArgs(args);
|
|
38
|
+
cmdArgs.forEach(arg => cmd.argument(...arg));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (options) {
|
|
42
|
+
const cmdOpts = processOptions(options);
|
|
43
|
+
cmdOpts.forEach(o => {
|
|
44
|
+
const option = createOption(o);
|
|
45
|
+
cmd.addOption(option);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { command: cmd, hidden, isDefault };
|
|
50
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* isValidOption - Validate the option
|
|
3
|
+
* @param {CLICommandOption} option The option configuration
|
|
4
|
+
* @returns {boolean} True if valid, false otherwise
|
|
5
|
+
*/
|
|
6
|
+
function isValidOption(option) {
|
|
7
|
+
const keys = Object.keys(option);
|
|
8
|
+
return keys.length &&
|
|
9
|
+
keys.length <= 5 &&
|
|
10
|
+
option.name &&
|
|
11
|
+
option.description;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* processOptions - Process the options configuration
|
|
16
|
+
* @param {CLICommandOption[]} options Array of option configurations
|
|
17
|
+
* @returns {ProccesedCLICommandOption[]} Processed option definitions
|
|
18
|
+
*/
|
|
19
|
+
export function processOptions(options) {
|
|
20
|
+
if (!Array.isArray(options) || !options.every(isValidOption)) throw new Error('Invalid option(s) configuration');
|
|
21
|
+
|
|
22
|
+
return options.reduce((acc, option) => {
|
|
23
|
+
const def = [];
|
|
24
|
+
const {
|
|
25
|
+
name,
|
|
26
|
+
description,
|
|
27
|
+
required = false,
|
|
28
|
+
short,
|
|
29
|
+
parse,
|
|
30
|
+
type = 'string',
|
|
31
|
+
conflicts = [],
|
|
32
|
+
hidden = false,
|
|
33
|
+
default: defaultValue
|
|
34
|
+
} = option;
|
|
35
|
+
|
|
36
|
+
const format = required ? `<${name}>` : `[${name}]`;
|
|
37
|
+
const flags = short ? `-${short}, --${name}` : `--${name}`;
|
|
38
|
+
|
|
39
|
+
def.push(`${flags}${type !== 'boolean' ? ` ${format}` : ''}`, description);
|
|
40
|
+
acc.push({ options: def, conflicts, hidden, defaultValue, parse, required });
|
|
41
|
+
|
|
42
|
+
return acc;
|
|
43
|
+
}, []);
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-gasket-app",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.4",
|
|
4
4
|
"description": "starter pack for creating a gasket app",
|
|
5
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-gasket-app": "./lib/index.js"
|
|
8
8
|
},
|
|
9
|
+
"main": "lib/index.js",
|
|
10
|
+
"types": "lib/index.d.ts",
|
|
9
11
|
"files": [
|
|
10
12
|
"lib"
|
|
11
13
|
],
|
|
12
14
|
"scripts": {
|
|
13
15
|
"lint": "eslint .",
|
|
14
16
|
"lint:fix": "npm run lint -- --fix",
|
|
15
|
-
"test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict' jest",
|
|
16
|
-
"test:watch": "
|
|
17
|
+
"test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict --experimental-vm-modules' jest",
|
|
18
|
+
"test:watch": "npm run test -- --watch",
|
|
17
19
|
"test:coverage": "jest --coverage",
|
|
18
20
|
"posttest": "npm run lint"
|
|
19
21
|
},
|
|
@@ -31,15 +33,37 @@
|
|
|
31
33
|
},
|
|
32
34
|
"homepage": "https://github.com/godaddy/gasket/tree/main/packages/create-gasket-app",
|
|
33
35
|
"dependencies": {
|
|
34
|
-
"@gasket/
|
|
36
|
+
"@gasket/core": "^7.0.1",
|
|
37
|
+
"@gasket/plugin-command": "^7.0.1",
|
|
38
|
+
"@gasket/plugin-docs": "^7.0.4",
|
|
39
|
+
"@gasket/plugin-docusaurus": "^7.0.3",
|
|
40
|
+
"@gasket/plugin-git": "^7.0.1",
|
|
41
|
+
"@gasket/plugin-logger": "^7.0.4",
|
|
42
|
+
"@gasket/plugin-metadata": "^7.0.4",
|
|
43
|
+
"@gasket/utils": "^7.0.1",
|
|
44
|
+
"commander": "^12.0.0",
|
|
45
|
+
"deepmerge": "^4.3.1",
|
|
46
|
+
"glob": "^8.1.0",
|
|
47
|
+
"handlebars": "^4.7.8",
|
|
48
|
+
"inquirer": "6.5.2",
|
|
49
|
+
"json5": "^2.2.3",
|
|
50
|
+
"mkdirp": "^1.0.4",
|
|
51
|
+
"ora": "3.4.0",
|
|
52
|
+
"pump": "^3.0.0",
|
|
53
|
+
"semver": "^7.5.4",
|
|
54
|
+
"tar-fs": "^2.0.0",
|
|
55
|
+
"untildify": "^4.0.0"
|
|
35
56
|
},
|
|
36
57
|
"devDependencies": {
|
|
58
|
+
"@types/inquirer": "^9.0.7",
|
|
37
59
|
"cross-env": "^7.0.3",
|
|
60
|
+
"diagnostics": "^2.0.2",
|
|
61
|
+
"dotenv": "^16.4.5",
|
|
38
62
|
"eslint": "^8.56.0",
|
|
39
|
-
"eslint-config-godaddy": "^7.
|
|
40
|
-
"eslint-plugin-jest": "^
|
|
63
|
+
"eslint-config-godaddy": "^7.1.1",
|
|
64
|
+
"eslint-plugin-jest": "^28.6.0",
|
|
41
65
|
"eslint-plugin-json": "^3.1.0",
|
|
42
|
-
"eslint-plugin-unicorn": "^
|
|
66
|
+
"eslint-plugin-unicorn": "^55.0.0",
|
|
43
67
|
"jest": "^29.7.0"
|
|
44
68
|
},
|
|
45
69
|
"eslintConfig": {
|
|
@@ -57,5 +81,8 @@
|
|
|
57
81
|
"eslintIgnore": [
|
|
58
82
|
"test/fixtures"
|
|
59
83
|
],
|
|
60
|
-
"
|
|
84
|
+
"jest": {
|
|
85
|
+
"transform": {}
|
|
86
|
+
},
|
|
87
|
+
"gitHead": "af49c0e42e7947e000faa771777b815b90aaffa3"
|
|
61
88
|
}
|