@form8ion/javascript 6.0.7 → 6.1.0-alpha.1

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/index.js CHANGED
@@ -14,6 +14,7 @@ var cliMessages = require('@travi/cli-messages');
14
14
  var commitConventionPlugin = require('@form8ion/commit-convention');
15
15
  var hoek = require('@hapi/hoek');
16
16
  var execa = require('@form8ion/execa-wrapper');
17
+ var npmConf = require('npm-conf');
17
18
  var ini = require('ini');
18
19
  var os = require('os');
19
20
  var validatePackageName = require('validate-npm-package-name');
@@ -23,8 +24,10 @@ var camelcase = require('camelcase');
23
24
  var makeDir = require('make-dir');
24
25
  var touch = require('touch');
25
26
  var path = require('path');
27
+ var filedirname = require('filedirname');
26
28
  var huskyPlugin = require('@form8ion/husky');
27
29
  var configFile = require('@form8ion/config-file');
30
+ var prettier = require('@form8ion/prettier');
28
31
  var eslint = require('@form8ion/eslint');
29
32
 
30
33
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -52,54 +55,15 @@ var joi__default = /*#__PURE__*/_interopDefaultLegacy(joi);
52
55
  var commitConventionPlugin__namespace = /*#__PURE__*/_interopNamespace(commitConventionPlugin);
53
56
  var hoek__default = /*#__PURE__*/_interopDefaultLegacy(hoek);
54
57
  var execa__default = /*#__PURE__*/_interopDefaultLegacy(execa);
58
+ var npmConf__default = /*#__PURE__*/_interopDefaultLegacy(npmConf);
55
59
  var validatePackageName__default = /*#__PURE__*/_interopDefaultLegacy(validatePackageName);
56
60
  var mustache__default = /*#__PURE__*/_interopDefaultLegacy(mustache);
57
61
  var camelcase__default = /*#__PURE__*/_interopDefaultLegacy(camelcase);
58
62
  var makeDir__default = /*#__PURE__*/_interopDefaultLegacy(makeDir);
59
63
  var touch__default = /*#__PURE__*/_interopDefaultLegacy(touch);
64
+ var filedirname__default = /*#__PURE__*/_interopDefaultLegacy(filedirname);
60
65
  var huskyPlugin__namespace = /*#__PURE__*/_interopNamespace(huskyPlugin);
61
66
 
62
- function ownKeys(object, enumerableOnly) {
63
- var keys = Object.keys(object);
64
-
65
- if (Object.getOwnPropertySymbols) {
66
- var symbols = Object.getOwnPropertySymbols(object);
67
- enumerableOnly && (symbols = symbols.filter(function (sym) {
68
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
69
- })), keys.push.apply(keys, symbols);
70
- }
71
-
72
- return keys;
73
- }
74
-
75
- function _objectSpread2(target) {
76
- for (var i = 1; i < arguments.length; i++) {
77
- var source = null != arguments[i] ? arguments[i] : {};
78
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
79
- _defineProperty(target, key, source[key]);
80
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
81
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
82
- });
83
- }
84
-
85
- return target;
86
- }
87
-
88
- function _defineProperty(obj, key, value) {
89
- if (key in obj) {
90
- Object.defineProperty(obj, key, {
91
- value: value,
92
- enumerable: true,
93
- configurable: true,
94
- writable: true
95
- });
96
- } else {
97
- obj[key] = value;
98
- }
99
-
100
- return obj;
101
- }
102
-
103
67
  const questionNames$1 = {
104
68
  UNIT_TEST_FRAMEWORK: 'unitTestFramework',
105
69
  NODE_VERSION_CATEGORY: 'nodeVersionCategory',
@@ -117,113 +81,74 @@ const questionNames$1 = {
117
81
  DIALECT: 'dialect'
118
82
  };
119
83
 
120
- async function scaffoldC8 ({
121
- projectRoot
122
- }) {
123
- await fs.promises.writeFile(`${projectRoot}/.c8rc.json`, JSON.stringify({
124
- reporter: ['lcov', 'text-summary', 'html'],
125
- exclude: ['src/**/*-test.js', 'test/', 'thirdparty-wrappers/', 'vendor/']
126
- }));
84
+ async function scaffoldC8 ({projectRoot}) {
85
+ await fs.promises.writeFile(
86
+ `${projectRoot}/.c8rc.json`,
87
+ JSON.stringify({
88
+ reporter: ['lcov', 'text-summary', 'html'],
89
+ exclude: ['src/**/*-test.js', 'test/', 'thirdparty-wrappers/', 'vendor/']
90
+ })
91
+ );
92
+
127
93
  return {
128
94
  devDependencies: ['cross-env', 'c8'],
129
- vcsIgnore: {
130
- files: [],
131
- directories: ['/coverage/']
132
- },
133
- eslint: {
134
- ignore: {
135
- directories: ['/coverage/']
136
- }
137
- }
95
+ vcsIgnore: {files: [], directories: ['/coverage/']},
96
+ eslint: {ignore: {directories: ['/coverage/']}}
138
97
  };
139
98
  }
140
99
 
141
- async function scaffoldCoverage ({
142
- projectRoot,
143
- vcs,
144
- visibility,
145
- pathWithinParent
146
- }) {
147
- return deepmerge__default["default"](await scaffoldC8({
148
- projectRoot
149
- }), await codecov.scaffold({
150
- vcs,
151
- visibility,
152
- pathWithinParent
153
- }));
100
+ async function scaffoldCoverage ({projectRoot, vcs, visibility, pathWithinParent}) {
101
+ return deepmerge__default["default"](await scaffoldC8({projectRoot}), await codecov.scaffold({vcs, visibility, pathWithinParent}));
154
102
  }
155
103
 
156
- function nycIsConfigured ({
157
- projectRoot
158
- }) {
104
+ function nycIsConfigured ({projectRoot}) {
159
105
  return core.fileExists(`${projectRoot}/.nycrc`);
160
106
  }
161
107
 
162
- async function removeDependencies ({
163
- packageManager,
164
- dependencies
165
- }) {
108
+ async function removeDependencies ({packageManager, dependencies}) {
166
109
  await execa__default["default"](packageManager, ['remove', ...dependencies]);
167
110
  }
168
111
 
169
- async function removeNyc ({
170
- projectRoot,
171
- packageManager
172
- }) {
173
- await Promise.all([fs.promises.unlink(`${projectRoot}/.nycrc`), fs.promises.rm(`${projectRoot}/.nyc_output`, {
174
- recursive: true,
175
- force: true
176
- }), removeDependencies({
177
- packageManager,
178
- dependencies: ['nyc', '@istanbuljs/nyc-config-babel', 'babel-plugin-istanbul']
179
- })]);
180
- }
181
-
182
- async function lift$2({
183
- projectRoot,
184
- packageManager
185
- }) {
186
- const codecovResults = await codecov.lift({
187
- projectRoot,
188
- packageManager
189
- });
190
-
191
- if (await nycIsConfigured({
192
- projectRoot
193
- })) {
194
- const [c8Results] = await Promise.all([scaffoldC8({
195
- projectRoot
196
- }), removeNyc({
197
- projectRoot,
198
- packageManager
199
- })]);
200
- return deepmerge__default["default"].all([c8Results, codecovResults, {
201
- scripts: {
202
- 'test:unit': 'cross-env NODE_ENV=test c8 run-s test:unit:base'
203
- },
204
- nextSteps: [{
205
- summary: 'Remove use of `@istanbuljs/nyc-config-babel` from your babel config, if present,' + ' after the migration away from `nyc`'
206
- }]
207
- }]);
112
+ async function removeNyc ({projectRoot, packageManager}) {
113
+ await Promise.all([
114
+ fs.promises.unlink(`${projectRoot}/.nycrc`),
115
+ fs.promises.rm(`${projectRoot}/.nyc_output`, {recursive: true, force: true}),
116
+ removeDependencies({packageManager, dependencies: ['nyc', '@istanbuljs/nyc-config-babel', 'babel-plugin-istanbul']})
117
+ ]);
118
+ }
119
+
120
+ async function lift$2({projectRoot, packageManager}) {
121
+ const codecovResults = await codecov.lift({projectRoot, packageManager});
122
+
123
+ if (await nycIsConfigured({projectRoot})) {
124
+ const [c8Results] = await Promise.all([
125
+ scaffoldC8({projectRoot}),
126
+ removeNyc({projectRoot, packageManager})
127
+ ]);
128
+
129
+ return deepmerge__default["default"].all([
130
+ c8Results,
131
+ codecovResults,
132
+ {
133
+ scripts: {'test:unit': 'cross-env NODE_ENV=test c8 run-s test:unit:base'},
134
+ nextSteps: [{
135
+ summary: 'Remove use of `@istanbuljs/nyc-config-babel` from your babel config, if present,'
136
+ + ' after the migration away from `nyc`'
137
+ }]
138
+ }
139
+ ]);
208
140
  }
209
141
 
210
142
  return {};
211
143
  }
212
144
 
213
- function c8IsConfigured ({
214
- projectRoot
215
- }) {
145
+ function c8IsConfigured ({projectRoot}) {
216
146
  return core.fileExists(`${projectRoot}/.c8rc.json`);
217
147
  }
218
148
 
219
- async function tester ({
220
- projectRoot
221
- }) {
222
- const [c8Exists, nycExists] = await Promise.all([c8IsConfigured({
223
- projectRoot
224
- }), nycIsConfigured({
225
- projectRoot
226
- })]);
149
+ async function tester ({projectRoot}) {
150
+ const [c8Exists, nycExists] = await Promise.all([c8IsConfigured({projectRoot}), nycIsConfigured({projectRoot})]);
151
+
227
152
  return c8Exists || nycExists;
228
153
  }
229
154
 
@@ -238,76 +163,47 @@ const unitTestFrameworksSchema = joi__default["default"].object().required().pat
238
163
  scaffolder: joi__default["default"].func().arity(1).required()
239
164
  }));
240
165
 
241
- async function chooseFramework ({
242
- frameworks,
243
- decisions
244
- }) {
166
+ async function chooseFramework ({frameworks, decisions}) {
245
167
  if (!Object.keys(frameworks).length) return 'Other';
168
+
246
169
  const answers = await overridablePrompts.prompt([{
247
170
  name: questionNames$1.UNIT_TEST_FRAMEWORK,
248
171
  type: 'list',
249
172
  message: 'Which type of unit testing framework should be used?',
250
173
  choices: [...Object.keys(frameworks), new overridablePrompts.Separator(), 'Other']
251
174
  }], decisions);
175
+
252
176
  return answers[questionNames$1.UNIT_TEST_FRAMEWORK];
253
177
  }
254
178
 
255
- async function scaffoldUnitTesting ({
256
- projectRoot,
257
- frameworks,
258
- decisions,
259
- visibility,
260
- vcs,
261
- pathWithinParent,
262
- dialect
263
- }) {
179
+ async function scaffoldUnitTesting ({projectRoot, frameworks, decisions, visibility, vcs, pathWithinParent, dialect}) {
264
180
  const validatedFrameworks = javascriptCore.validateOptions(unitTestFrameworksSchema, frameworks);
265
- const [framework, coverage] = await Promise.all([chooseFramework({
266
- frameworks: validatedFrameworks,
267
- decisions
268
- }).then(chosenFramework => javascriptCore.scaffoldChoice(validatedFrameworks, chosenFramework, {
269
- projectRoot,
270
- dialect
271
- })), scaffoldCoverage({
272
- projectRoot,
273
- vcs,
274
- visibility,
275
- pathWithinParent
276
- })]);
277
- return deepmerge__default["default"].all([{
278
- scripts: {
279
- 'test:unit': 'cross-env NODE_ENV=test c8 run-s test:unit:base'
280
- }
281
- }, framework, coverage]);
181
+ const [framework, coverage] = await Promise.all([
182
+ chooseFramework({frameworks: validatedFrameworks, decisions})
183
+ .then(chosenFramework => javascriptCore.scaffoldChoice(validatedFrameworks, chosenFramework, {projectRoot, dialect})),
184
+ scaffoldCoverage({projectRoot, vcs, visibility, pathWithinParent})
185
+ ]);
186
+
187
+ return deepmerge__default["default"].all([
188
+ {scripts: {'test:unit': 'cross-env NODE_ENV=test c8 run-s test:unit:base'}},
189
+ framework,
190
+ coverage
191
+ ]);
282
192
  }
283
193
 
284
- async function test$1({
285
- projectRoot
286
- }) {
287
- const {
288
- engines
289
- } = JSON.parse(await fs.promises.readFile(`${projectRoot}/package.json`, 'utf8'));
290
- return !!(engines !== null && engines !== void 0 && engines.node);
194
+ async function test$1({projectRoot}) {
195
+ const {engines} = JSON.parse(await fs.promises.readFile(`${projectRoot}/package.json`, 'utf8'));
196
+
197
+ return !!engines?.node;
291
198
  }
292
- async function lift$1({
293
- projectRoot
294
- }) {
295
- const {
296
- name
297
- } = JSON.parse(await fs.promises.readFile(`${projectRoot}/package.json`, 'utf8'));
199
+
200
+ async function lift$1({projectRoot}) {
201
+ const {name} = JSON.parse(await fs.promises.readFile(`${projectRoot}/package.json`, 'utf8'));
202
+
298
203
  return {
299
204
  devDependencies: ['ls-engines'],
300
- scripts: {
301
- 'lint:engines': 'ls-engines'
302
- },
303
- badges: {
304
- consumer: {
305
- node: {
306
- img: `https://img.shields.io/node/v/${name}?logo=node.js`,
307
- text: 'node'
308
- }
309
- }
310
- }
205
+ scripts: {'lint:engines': 'ls-engines'},
206
+ badges: {consumer: {node: {img: `https://img.shields.io/node/v/${name}?logo=node.js`, text: 'node'}}}
311
207
  };
312
208
  }
313
209
 
@@ -330,27 +226,33 @@ function projectShouldBeBuiltForVerification(scripts) {
330
226
  }
331
227
 
332
228
  function updateTestScript (scripts) {
333
- return _objectSpread2(_objectSpread2({}, scripts), {}, {
334
- test: `npm-run-all --print-label${projectShouldBeBuiltForVerification(scripts) ? ' build' : ''} --parallel lint:*${projectWillBeTested(scripts) ? ' --parallel test:*' : ''}`
335
- });
229
+ return {
230
+ ...scripts,
231
+ test: `npm-run-all --print-label${
232
+ projectShouldBeBuiltForVerification(scripts) ? ' build' : ''
233
+ } --parallel lint:*${
234
+ projectWillBeTested(scripts) ? ' --parallel test:*' : ''
235
+ }`
236
+ };
336
237
  }
337
238
 
338
- function liftScripts ({
339
- existingScripts,
340
- scripts
341
- }) {
342
- return updateTestScript(_objectSpread2(_objectSpread2({}, existingScripts), scripts));
239
+ function liftScripts ({existingScripts, scripts}) {
240
+ return updateTestScript({...existingScripts, ...scripts});
343
241
  }
344
242
 
345
243
  function defineVcsHostDetails(vcs, packageType, packageName, pathWithinParent) {
346
244
  return vcs && 'github' === vcs.host && {
347
- repository: pathWithinParent ? {
348
- type: 'git',
349
- url: `https://github.com/${vcs.owner}/${vcs.name}.git`,
350
- directory: pathWithinParent
351
- } : `${vcs.owner}/${vcs.name}`,
245
+ repository: pathWithinParent
246
+ ? {
247
+ type: 'git',
248
+ url: `https://github.com/${vcs.owner}/${vcs.name}.git`,
249
+ directory: pathWithinParent
250
+ }
251
+ : `${vcs.owner}/${vcs.name}`,
352
252
  bugs: `https://github.com/${vcs.owner}/${vcs.name}/issues`,
353
- homepage: javascriptCore.projectTypes.PACKAGE === packageType ? `https://npm.im/${packageName}` : `https://github.com/${vcs.owner}/${vcs.name}#readme`
253
+ homepage: (javascriptCore.projectTypes.PACKAGE === packageType)
254
+ ? `https://npm.im/${packageName}`
255
+ : `https://github.com/${vcs.owner}/${vcs.name}#readme`
354
256
  };
355
257
  }
356
258
 
@@ -364,15 +266,15 @@ function buildPackageDetails ({
364
266
  description,
365
267
  pathWithinParent
366
268
  }) {
367
- return _objectSpread2(_objectSpread2({
269
+ return {
368
270
  name: packageName,
369
271
  description,
370
272
  license,
371
- type: javascriptCore.dialects.ESM === dialect ? 'module' : 'commonjs'
372
- }, defineVcsHostDetails(vcs, projectType, packageName, pathWithinParent)), {}, {
273
+ type: javascriptCore.dialects.ESM === dialect ? 'module' : 'commonjs',
274
+ ...defineVcsHostDetails(vcs, projectType, packageName, pathWithinParent),
373
275
  author: `${author.name}${author.email ? ` <${author.email}>` : ''}${author.url ? ` (${author.url})` : ''}`,
374
276
  scripts: scaffoldScripts()
375
- });
277
+ };
376
278
  }
377
279
 
378
280
  async function scaffoldPackage ({
@@ -387,6 +289,7 @@ async function scaffoldPackage ({
387
289
  pathWithinParent
388
290
  }) {
389
291
  cliMessages.info('Configuring package.json');
292
+
390
293
  const packageData = await buildPackageDetails({
391
294
  packageName,
392
295
  projectType,
@@ -397,13 +300,10 @@ async function scaffoldPackage ({
397
300
  description,
398
301
  pathWithinParent
399
302
  });
400
- await javascriptCore.writePackageJson({
401
- projectRoot,
402
- config: packageData
403
- });
404
- return {
405
- homepage: packageData.homepage
406
- };
303
+
304
+ await javascriptCore.writePackageJson({projectRoot, config: packageData});
305
+
306
+ return {homepage: packageData.homepage};
407
307
  }
408
308
 
409
309
  async function liftPackage ({
@@ -415,21 +315,21 @@ async function liftPackage ({
415
315
  packageManager
416
316
  }) {
417
317
  if (scripts || tags) {
418
- cliMessages.info('Updating `package.json`', {
419
- level: 'secondary'
420
- });
318
+ cliMessages.info('Updating `package.json`', {level: 'secondary'});
319
+
421
320
  const pathToPackageJson = `${projectRoot}/package.json`;
321
+
422
322
  const existingPackageJsonContents = JSON.parse(await fs.promises.readFile(pathToPackageJson, 'utf8'));
323
+
423
324
  await javascriptCore.writePackageJson({
424
325
  projectRoot,
425
- config: _objectSpread2(_objectSpread2({}, existingPackageJsonContents), {}, {
426
- scripts: liftScripts({
427
- existingScripts: existingPackageJsonContents.scripts,
428
- scripts
429
- })
430
- }, tags && {
431
- keywords: existingPackageJsonContents.keywords ? [...existingPackageJsonContents.keywords, ...tags] : tags
432
- })
326
+ config: {
327
+ ...existingPackageJsonContents,
328
+ scripts: liftScripts({existingScripts: existingPackageJsonContents.scripts, scripts}),
329
+ ...tags && {
330
+ keywords: existingPackageJsonContents.keywords ? [...existingPackageJsonContents.keywords, ...tags] : tags
331
+ }
332
+ }
433
333
  });
434
334
  }
435
335
 
@@ -437,16 +337,13 @@ async function liftPackage ({
437
337
 
438
338
  try {
439
339
  await javascriptCore.installDependencies(dependencies || [], javascriptCore.PROD_DEPENDENCY_TYPE, projectRoot, packageManager);
440
- await javascriptCore.installDependencies([...(devDependencies || [])], javascriptCore.DEV_DEPENDENCY_TYPE, projectRoot, packageManager);
340
+ await javascriptCore.installDependencies([...devDependencies || []], javascriptCore.DEV_DEPENDENCY_TYPE, projectRoot, packageManager);
441
341
  } catch (e) {
442
342
  cliMessages.error('Failed to install dependencies');
443
343
  }
444
344
  }
445
345
 
446
- async function resolvePackageManager ({
447
- projectRoot,
448
- packageManager
449
- }) {
346
+ async function resolvePackageManager ({projectRoot, packageManager}) {
450
347
  if (packageManager) return packageManager;
451
348
 
452
349
  if (await core.fileExists(`${projectRoot}/package-lock.json`)) {
@@ -460,46 +357,28 @@ async function resolvePackageManager ({
460
357
  throw new Error('Package-manager could not be determined');
461
358
  }
462
359
 
463
- async function lift ({
464
- projectRoot,
465
- vcs,
466
- results
467
- }) {
360
+ async function lift ({projectRoot, vcs, results}) {
468
361
  cliMessages.info('Lifting JavaScript-specific details');
469
- const {
470
- scripts,
471
- tags,
472
- eslintConfigs,
473
- eslint: eslint$1,
474
- dependencies,
475
- devDependencies,
476
- packageManager: manager
477
- } = results;
478
- const packageManager = await resolvePackageManager({
479
- projectRoot,
480
- packageManager: manager
481
- });
482
- const eslintResults = await eslint.lift({
483
- projectRoot,
484
- configs: [...(eslintConfigs || []), ...((eslint$1 === null || eslint$1 === void 0 ? void 0 : eslint$1.configs) || [])]
485
- });
362
+
363
+ const {scripts, tags, eslintConfigs, eslint: eslint$1, dependencies, devDependencies, packageManager: manager} = results;
364
+
365
+ const packageManager = await resolvePackageManager({projectRoot, packageManager: manager});
366
+
367
+ const eslintResults = await eslint.lift({projectRoot, configs: [...eslintConfigs || [], ...eslint$1?.configs || []]});
486
368
  const enhancerResults = await core.applyEnhancers({
487
369
  results,
488
370
  enhancers: [huskyPlugin__namespace, enginesEnhancer, coveragePlugin, commitConventionPlugin__namespace],
489
- options: {
490
- packageManager,
491
- projectRoot,
492
- vcs
493
- }
371
+ options: {packageManager, projectRoot, vcs}
494
372
  });
495
- await liftPackage(deepmerge__default["default"].all([{
496
- projectRoot,
497
- scripts,
498
- tags,
499
- dependencies,
500
- devDependencies,
501
- packageManager
502
- }, enhancerResults, eslintResults]));
373
+
374
+ await liftPackage(
375
+ deepmerge__default["default"].all([
376
+ {projectRoot, scripts, tags, dependencies, devDependencies, packageManager},
377
+ enhancerResults,
378
+ eslintResults
379
+ ])
380
+ );
381
+
503
382
  return enhancerResults;
504
383
  }
505
384
 
@@ -508,110 +387,93 @@ const packageBundlersSchema = joi__default["default"].object().pattern(/^/, joi_
508
387
  })).default({});
509
388
 
510
389
  function validate(options) {
511
- const schema = joi__default["default"].object().required().keys({
512
- projectRoot: joi__default["default"].string().required(),
513
- projectName: joi__default["default"].string().regex(/^@\w*\//, {
514
- invert: true
515
- }).required(),
516
- visibility: joi__default["default"].string().valid('Public', 'Private').required(),
517
- license: joi__default["default"].string().required(),
518
- description: joi__default["default"].string(),
519
- pathWithinParent: joi__default["default"].string()
520
- }).keys({
521
- vcs: joi__default["default"].object({
522
- host: joi__default["default"].string().required(),
523
- owner: joi__default["default"].string().required(),
524
- name: joi__default["default"].string().required()
390
+ const schema = joi__default["default"].object().required()
391
+ .keys({
392
+ projectRoot: joi__default["default"].string().required(),
393
+ projectName: joi__default["default"].string().regex(/^@\w*\//, {invert: true}).required(),
394
+ visibility: joi__default["default"].string().valid('Public', 'Private').required(),
395
+ license: joi__default["default"].string().required(),
396
+ description: joi__default["default"].string(),
397
+ pathWithinParent: joi__default["default"].string()
525
398
  })
526
- }).keys({
527
- configs: joi__default["default"].object({
528
- eslint: joi__default["default"].object({
529
- scope: joi__default["default"].string().regex(/^@[a-z0-9-]+$/i, 'scope').required()
530
- }),
531
- typescript: joi__default["default"].object({
532
- scope: joi__default["default"].string().regex(/^@[a-z0-9-]+$/i, 'scope').required()
533
- }),
534
- commitlint: joi__default["default"].object({
535
- packageName: joi__default["default"].string().required(),
536
- name: joi__default["default"].string().required()
537
- }),
538
- babelPreset: joi__default["default"].object({
539
- packageName: joi__default["default"].string().required(),
399
+ .keys({
400
+ vcs: joi__default["default"].object({
401
+ host: joi__default["default"].string().required(),
402
+ owner: joi__default["default"].string().required(),
540
403
  name: joi__default["default"].string().required()
541
- }),
542
- remark: joi__default["default"].string()
543
- }).default({})
544
- }).keys({
545
- overrides: joi__default["default"].object({
546
- npmAccount: joi__default["default"].string(),
547
- author: joi__default["default"].object({
548
- name: joi__default["default"].string().required(),
549
- email: joi__default["default"].string().email(),
550
- url: joi__default["default"].string().uri()
551
404
  })
552
- }).default({})
553
- }).keys({
554
- ciServices: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
555
- scaffolder: joi__default["default"].func().arity(1).required(),
556
- public: joi__default["default"].boolean(),
557
- private: joi__default["default"].boolean()
558
- })).default({})
559
- }).keys({
560
- hosts: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
561
- scaffolder: joi__default["default"].func().arity(1).required(),
562
- projectTypes: joi__default["default"].array().items(joi__default["default"].string().valid('static', 'node')).default([])
563
- })).default({})
564
- }).keys({
565
- applicationTypes: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
566
- scaffolder: joi__default["default"].func().arity(1).required()
567
- })).default({}),
568
- packageTypes: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
569
- scaffolder: joi__default["default"].func().arity(1).required()
570
- })).default({}),
571
- monorepoTypes: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
572
- scaffolder: joi__default["default"].func().arity(1).required()
573
- }))
574
- }).keys({
575
- unitTestFrameworks: unitTestFrameworksSchema,
576
- packageBundlers: packageBundlersSchema
577
- }).keys({
578
- decisions: joi__default["default"].object()
579
- }).keys({
580
- registries: joi__default["default"].object().pattern(joi__default["default"].string(), joi__default["default"].string().uri()).default({})
581
- });
582
- const {
583
- error,
584
- value
585
- } = schema.validate(options);
405
+ })
406
+ .keys({
407
+ configs: joi__default["default"].object({
408
+ eslint: joi__default["default"].object({scope: joi__default["default"].string().regex(/^@[a-z0-9-]+$/i, 'scope').required()}),
409
+ typescript: joi__default["default"].object({scope: joi__default["default"].string().regex(/^@[a-z0-9-]+$/i, 'scope').required()}),
410
+ commitlint: joi__default["default"].object({
411
+ packageName: joi__default["default"].string().required(),
412
+ name: joi__default["default"].string().required()
413
+ }),
414
+ babelPreset: joi__default["default"].object({
415
+ packageName: joi__default["default"].string().required(),
416
+ name: joi__default["default"].string().required()
417
+ }),
418
+ remark: joi__default["default"].string()
419
+ }).default({})
420
+ })
421
+ .keys({
422
+ overrides: joi__default["default"].object({
423
+ npmAccount: joi__default["default"].string(),
424
+ author: joi__default["default"].object({
425
+ name: joi__default["default"].string().required(),
426
+ email: joi__default["default"].string().email(),
427
+ url: joi__default["default"].string().uri()
428
+ })
429
+ }).default({})
430
+ })
431
+ .keys({
432
+ ciServices: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
433
+ scaffolder: joi__default["default"].func().arity(1).required(),
434
+ public: joi__default["default"].boolean(),
435
+ private: joi__default["default"].boolean()
436
+ })).default({})
437
+ })
438
+ .keys({
439
+ hosts: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
440
+ scaffolder: joi__default["default"].func().arity(1).required(),
441
+ projectTypes: joi__default["default"].array().items(joi__default["default"].string().valid('static', 'node')).default([])
442
+ })).default({})
443
+ })
444
+ .keys({
445
+ applicationTypes: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
446
+ scaffolder: joi__default["default"].func().arity(1).required()
447
+ })).default({}),
448
+ packageTypes: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
449
+ scaffolder: joi__default["default"].func().arity(1).required()
450
+ })).default({}),
451
+ monorepoTypes: joi__default["default"].object().pattern(/^/, joi__default["default"].object({
452
+ scaffolder: joi__default["default"].func().arity(1).required()
453
+ }))
454
+ })
455
+ .keys({
456
+ unitTestFrameworks: unitTestFrameworksSchema,
457
+ packageBundlers: packageBundlersSchema
458
+ })
459
+ .keys({
460
+ decisions: joi__default["default"].object()
461
+ })
462
+ .keys({registries: joi__default["default"].object().pattern(joi__default["default"].string(), joi__default["default"].string().uri()).default({})});
463
+ const {error, value} = schema.validate(options);
464
+
586
465
  hoek__default["default"].assert(!error, error);
466
+
587
467
  return value;
588
468
  }
589
469
 
590
- const npmConf = require('npm-conf');
591
-
592
- var npmConfFactory = npmConf;
593
-
594
- function buildDialectChoices ({
595
- babelPreset,
596
- typescript
597
- }) {
598
- return [{
599
- name: 'Common JS (no transpilation)',
600
- value: javascriptCore.dialects.COMMON_JS,
601
- short: 'cjs'
602
- }, ...(babelPreset ? [{
603
- name: 'Modern JavaScript (transpiled)',
604
- value: javascriptCore.dialects.BABEL,
605
- short: 'modern'
606
- }] : []), {
607
- name: 'ESM-only (no transpilation)',
608
- value: javascriptCore.dialects.ESM,
609
- short: 'esm'
610
- }, ...(typescript ? [{
611
- name: 'TypeScript',
612
- value: javascriptCore.dialects.TYPESCRIPT,
613
- short: 'ts'
614
- }] : [])];
470
+ function buildDialectChoices ({babelPreset, typescript}) {
471
+ return [
472
+ {name: 'Common JS (no transpilation)', value: javascriptCore.dialects.COMMON_JS, short: 'cjs'},
473
+ ...babelPreset ? [{name: 'Modern JavaScript (transpiled)', value: javascriptCore.dialects.BABEL, short: 'modern'}] : [],
474
+ {name: 'ESM-only (no transpilation)', value: javascriptCore.dialects.ESM, short: 'esm'},
475
+ ...typescript ? [{name: 'TypeScript', value: javascriptCore.dialects.TYPESCRIPT, short: 'ts'}] : []
476
+ ];
615
477
  }
616
478
 
617
479
  function projectIsPackage(answers) {
@@ -637,9 +499,11 @@ function willBePublishedToNpm(answers) {
637
499
  function shouldBeScopedPromptShouldBePresented(answers) {
638
500
  return willBePublishedToNpm(answers);
639
501
  }
502
+
640
503
  function scopePromptShouldBePresentedFactory(visibility) {
641
504
  return answers => willBePublishedToNpm(answers) && packageShouldBeScoped(visibility, answers);
642
505
  }
506
+
643
507
  function lintingPromptShouldBePresented({
644
508
  [languageScaffolderPrompts.questionNames.UNIT_TESTS]: unitTested,
645
509
  [languageScaffolderPrompts.questionNames.INTEGRATION_TESTS]: integrationTested
@@ -657,38 +521,45 @@ function scope(visibility) {
657
521
  };
658
522
  }
659
523
 
660
- function authorQuestions({
661
- name,
662
- email,
663
- url
664
- }) {
665
- return [{
666
- name: questionNames$1.AUTHOR_NAME,
667
- message: 'What is the author\'s name?',
668
- default: name
669
- }, {
670
- name: questionNames$1.AUTHOR_EMAIL,
671
- message: 'What is the author\'s email?',
672
- default: email
673
- }, {
674
- name: questionNames$1.AUTHOR_URL,
675
- message: 'What is the author\'s website url?',
676
- default: url
677
- }];
678
- }
679
-
680
- async function prompt({
681
- npmAccount,
682
- author
683
- }, ciServices, hosts, visibility, vcs, decisions, configs, pathWithinParent) {
684
- const npmConf = npmConfFactory();
685
- let maybeLoggedInNpmUsername;
524
+ function authorQuestions({name, email, url}) {
525
+ return [
526
+ {
527
+ name: questionNames$1.AUTHOR_NAME,
528
+ message: 'What is the author\'s name?',
529
+ default: name
530
+ },
531
+ {
532
+ name: questionNames$1.AUTHOR_EMAIL,
533
+ message: 'What is the author\'s email?',
534
+ default: email
535
+ },
536
+ {
537
+ name: questionNames$1.AUTHOR_URL,
538
+ message: 'What is the author\'s website url?',
539
+ default: url
540
+ }
541
+ ];
542
+ }
543
+
544
+ async function prompt(
545
+ {npmAccount, author},
546
+ ciServices,
547
+ hosts,
548
+ visibility,
549
+ vcs,
550
+ decisions,
551
+ configs,
552
+ pathWithinParent
553
+ ) {
554
+ const npmConf = npmConf__default["default"]();
686
555
 
556
+ let maybeLoggedInNpmUsername;
687
557
  try {
688
558
  maybeLoggedInNpmUsername = (await execa__default["default"]('npm', ['whoami'])).stdout;
689
559
  } catch (failedExecutionResult) {
690
560
  if (!decisions[questionNames$1.SCOPE]) {
691
- cliMessages.warn('No logged in user found with `npm whoami`. Login with `npm login` ' + 'to use your npm account name as the package scope default.');
561
+ cliMessages.warn('No logged in user found with `npm whoami`. Login with `npm login` '
562
+ + 'to use your npm account name as the package scope default.');
692
563
  }
693
564
  }
694
565
 
@@ -706,89 +577,85 @@ async function prompt({
706
577
  [questionNames$1.CONFIGURE_LINTING]: configureLinting,
707
578
  [questionNames$1.PACKAGE_MANAGER]: packageManager,
708
579
  [questionNames$1.DIALECT]: dialect
709
- } = await overridablePrompts.prompt([{
710
- name: questionNames$1.DIALECT,
711
- message: 'Which JavaScript dialect should this project follow?',
712
- type: 'list',
713
- choices: buildDialectChoices(configs),
714
- default: 'babel'
715
- }, ...(pathWithinParent ? [] : [{
716
- name: questionNames$1.NODE_VERSION_CATEGORY,
717
- message: 'What node.js version should be used?',
718
- type: 'list',
719
- choices: ['LTS', 'Latest'],
720
- default: 'LTS'
721
- }]), {
722
- name: questionNames$1.PACKAGE_MANAGER,
723
- message: 'Which package manager will be used with this project?',
724
- type: 'list',
725
- choices: Object.values(javascriptCore.packageManagers),
726
- default: javascriptCore.packageManagers.NPM
727
- }, {
728
- name: questionNames$1.PROJECT_TYPE,
729
- message: 'What type of JavaScript project is this?',
730
- type: 'list',
731
- choices: [...Object.values(javascriptCore.projectTypes), new overridablePrompts.Separator(), 'Other'],
732
- default: javascriptCore.projectTypes.PACKAGE
733
- }, ...('Private' === visibility ? [] : [{
734
- name: questionNames$1.SHOULD_BE_SCOPED,
735
- message: 'Should this package be scoped?',
736
- type: 'confirm',
737
- when: shouldBeScopedPromptShouldBePresented,
738
- default: true
739
- }]), {
740
- name: questionNames$1.SCOPE,
741
- message: 'What is the scope?',
742
- when: scopePromptShouldBePresentedFactory(visibility),
743
- validate: scope(visibility),
744
- default: npmAccount || maybeLoggedInNpmUsername
745
- }, ...authorQuestions(author || {
746
- name: npmConf.get('init.author.name'),
747
- email: npmConf.get('init.author.email'),
748
- url: npmConf.get('init.author.url')
749
- }), ...languageScaffolderPrompts.questions({
750
- vcs,
751
- ciServices,
752
- visibility,
753
- pathWithinParent
754
- }), {
755
- name: questionNames$1.CONFIGURE_LINTING,
756
- message: 'Will there be source code that should be linted?',
757
- type: 'confirm',
758
- when: lintingPromptShouldBePresented
759
- }, {
760
- name: questionNames$1.HOST,
761
- type: 'list',
762
- message: 'Where will the application be hosted?',
763
- when: projectIsApplication,
764
- choices: [...Object.keys(hosts), new overridablePrompts.Separator(), 'Other']
765
- }], decisions);
766
- return {
767
- tests: {
768
- unit: unitTested,
769
- integration: integrationTested
580
+ } = await overridablePrompts.prompt([
581
+ {
582
+ name: questionNames$1.DIALECT,
583
+ message: 'Which JavaScript dialect should this project follow?',
584
+ type: 'list',
585
+ choices: buildDialectChoices(configs),
586
+ default: 'babel'
587
+ },
588
+ ...pathWithinParent ? [] : [{
589
+ name: questionNames$1.NODE_VERSION_CATEGORY,
590
+ message: 'What node.js version should be used?',
591
+ type: 'list',
592
+ choices: ['LTS', 'Latest'],
593
+ default: 'LTS'
594
+ }],
595
+ {
596
+ name: questionNames$1.PACKAGE_MANAGER,
597
+ message: 'Which package manager will be used with this project?',
598
+ type: 'list',
599
+ choices: Object.values(javascriptCore.packageManagers),
600
+ default: javascriptCore.packageManagers.NPM
601
+ },
602
+ {
603
+ name: questionNames$1.PROJECT_TYPE,
604
+ message: 'What type of JavaScript project is this?',
605
+ type: 'list',
606
+ choices: [...Object.values(javascriptCore.projectTypes), new overridablePrompts.Separator(), 'Other'],
607
+ default: javascriptCore.projectTypes.PACKAGE
608
+ },
609
+ ...'Private' === visibility ? [] : [{
610
+ name: questionNames$1.SHOULD_BE_SCOPED,
611
+ message: 'Should this package be scoped?',
612
+ type: 'confirm',
613
+ when: shouldBeScopedPromptShouldBePresented,
614
+ default: true
615
+ }],
616
+ {
617
+ name: questionNames$1.SCOPE,
618
+ message: 'What is the scope?',
619
+ when: scopePromptShouldBePresentedFactory(visibility),
620
+ validate: scope(visibility),
621
+ default: npmAccount || maybeLoggedInNpmUsername
622
+ },
623
+ ...authorQuestions(author || {
624
+ name: npmConf.get('init.author.name'),
625
+ email: npmConf.get('init.author.email'),
626
+ url: npmConf.get('init.author.url')
627
+ }),
628
+ ...languageScaffolderPrompts.questions(({vcs, ciServices, visibility, pathWithinParent})),
629
+ {
630
+ name: questionNames$1.CONFIGURE_LINTING,
631
+ message: 'Will there be source code that should be linted?',
632
+ type: 'confirm',
633
+ when: lintingPromptShouldBePresented
770
634
  },
635
+ {
636
+ name: questionNames$1.HOST,
637
+ type: 'list',
638
+ message: 'Where will the application be hosted?',
639
+ when: projectIsApplication,
640
+ choices: [...Object.keys(hosts), new overridablePrompts.Separator(), 'Other']
641
+ }
642
+ ], decisions);
643
+
644
+ return {
645
+ tests: {unit: unitTested, integration: integrationTested},
771
646
  projectType,
772
647
  ci,
773
648
  chosenHost,
774
649
  scope: scope$1,
775
650
  nodeVersionCategory,
776
- author: {
777
- name: authorName,
778
- email: authorEmail,
779
- url: authorUrl
780
- },
651
+ author: {name: authorName, email: authorEmail, url: authorUrl},
781
652
  configureLinting: false !== configureLinting,
782
653
  packageManager,
783
654
  dialect
784
655
  };
785
656
  }
786
657
 
787
- async function scaffoldBabel ({
788
- projectRoot,
789
- preset,
790
- buildDirectory
791
- }) {
658
+ async function scaffoldBabel ({projectRoot, preset, buildDirectory}) {
792
659
  if (!preset) {
793
660
  throw new Error('No babel preset provided. Cannot configure babel transpilation');
794
661
  }
@@ -797,74 +664,50 @@ async function scaffoldBabel ({
797
664
  path: projectRoot,
798
665
  name: 'babel',
799
666
  format: core.fileTypes.JSON,
800
- config: {
801
- presets: [preset.name],
802
- ignore: [`./${buildDirectory}/`]
803
- }
667
+ config: {presets: [preset.name], ignore: [`./${buildDirectory}/`]}
804
668
  });
669
+
805
670
  return {
806
671
  devDependencies: ['@babel/register', preset.packageName],
807
672
  eslint: {}
808
673
  };
809
674
  }
810
675
 
811
- async function scaffoldTypescript ({
812
- config,
813
- projectType,
814
- projectRoot,
815
- testFilenamePattern
816
- }) {
676
+ async function scaffoldTypescript ({config, projectType, projectRoot, testFilenamePattern}) {
817
677
  const eslintConfigs = ['typescript'];
818
678
  const shareableTsConfigPackage = `${config.scope}/tsconfig`;
819
- await fs.promises.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify(_objectSpread2({
820
- $schema: 'https://json.schemastore.org/tsconfig',
821
- extends: shareableTsConfigPackage,
822
- compilerOptions: _objectSpread2({
823
- rootDir: 'src'
824
- }, javascriptCore.projectTypes.PACKAGE === projectType && {
825
- outDir: 'lib',
826
- declaration: true
827
- }),
828
- include: ['src/**/*.ts']
829
- }, testFilenamePattern && {
830
- exclude: [testFilenamePattern]
831
- })));
679
+
680
+ await fs.promises.writeFile(
681
+ `${projectRoot}/tsconfig.json`,
682
+ JSON.stringify({
683
+ $schema: 'https://json.schemastore.org/tsconfig',
684
+ extends: shareableTsConfigPackage,
685
+ compilerOptions: {
686
+ rootDir: 'src',
687
+ ...javascriptCore.projectTypes.PACKAGE === projectType && {
688
+ outDir: 'lib',
689
+ declaration: true
690
+ }
691
+ },
692
+ include: ['src/**/*.ts'],
693
+ ...testFilenamePattern && {exclude: [testFilenamePattern]}
694
+ })
695
+ );
696
+
832
697
  return {
833
- eslint: {
834
- configs: eslintConfigs
835
- },
698
+ eslint: {configs: eslintConfigs},
836
699
  eslintConfigs,
837
700
  devDependencies: ['typescript', shareableTsConfigPackage],
838
- vcsIgnore: {
839
- files: ['tsconfig.tsbuildinfo']
840
- }
701
+ vcsIgnore: {files: ['tsconfig.tsbuildinfo']}
841
702
  };
842
703
  }
843
704
 
844
- function scaffoldDialect ({
845
- dialect,
846
- projectType,
847
- projectRoot,
848
- configs,
849
- buildDirectory,
850
- testFilenamePattern
851
- }) {
705
+ function scaffoldDialect ({dialect, projectType, projectRoot, configs, buildDirectory, testFilenamePattern}) {
852
706
  switch (dialect) {
853
707
  case javascriptCore.dialects.BABEL:
854
- return scaffoldBabel({
855
- preset: configs.babelPreset,
856
- projectRoot,
857
- buildDirectory
858
- });
859
-
708
+ return scaffoldBabel({preset: configs.babelPreset, projectRoot, buildDirectory});
860
709
  case javascriptCore.dialects.TYPESCRIPT:
861
- return scaffoldTypescript({
862
- config: configs.typescript,
863
- projectType,
864
- projectRoot,
865
- testFilenamePattern
866
- });
867
-
710
+ return scaffoldTypescript({config: configs.typescript, projectType, projectRoot, testFilenamePattern});
868
711
  default:
869
712
  return {};
870
713
  }
@@ -879,34 +722,38 @@ async function scaffoldNpmConfig ({
879
722
  projectType,
880
723
  registries
881
724
  }) {
882
- await fs.promises.writeFile(`${projectRoot}/.npmrc`, ini.stringify(_objectSpread2(_objectSpread2({
883
- 'update-notifier': false
884
- }, projectWillNotBeConsumed(projectType) && {
885
- 'save-exact': true
886
- }), Object.fromEntries(Object.entries(registries).filter(([scope]) => 'publish' !== scope).map(([scope, url]) => {
887
- if ('registry' === scope) return ['registry', url];
888
- return [`@${scope}:registry`, url];
889
- })))));
890
- return {
891
- scripts: {
892
- 'lint:peer': 'npm ls >/dev/null'
893
- }
894
- };
725
+ await fs.promises.writeFile(
726
+ `${projectRoot}/.npmrc`,
727
+ ini.stringify({
728
+ 'update-notifier': false,
729
+ ...projectWillNotBeConsumed(projectType) && {'save-exact': true},
730
+ ...Object.fromEntries(Object.entries(registries)
731
+ .filter(([scope]) => 'publish' !== scope)
732
+ .map(([scope, url]) => {
733
+ if ('registry' === scope) return ['registry', url];
734
+
735
+ return [`@${scope}:registry`, url];
736
+ }))
737
+ })
738
+ );
739
+
740
+ return {scripts: {'lint:peer': 'npm ls >/dev/null'}};
895
741
  }
896
742
 
897
743
  function buildDocumentationCommand (packageManager) {
898
744
  if (javascriptCore.packageManagers.NPM === packageManager) return 'npm run generate:md';
899
745
  if (javascriptCore.packageManagers.YARN === packageManager) return 'yarn generate:md';
900
- throw new Error(`The ${packageManager} package manager is currently not supported. ` + `Only ${Object.values(javascriptCore.packageManagers).join(' and ')} are currently supported.`);
746
+
747
+ throw new Error(
748
+ `The ${packageManager} package manager is currently not supported. `
749
+ + `Only ${Object.values(javascriptCore.packageManagers).join(' and ')} are currently supported.`
750
+ );
901
751
  }
902
752
 
903
- function scaffoldDocumentation ({
904
- projectTypeResults,
905
- packageManager
906
- }) {
907
- return _objectSpread2(_objectSpread2({
908
- toc: `Run \`${buildDocumentationCommand(packageManager)}\` to generate a table of contents`
909
- }, projectTypeResults.documentation), {}, {
753
+ function scaffoldDocumentation ({projectTypeResults, packageManager}) {
754
+ return {
755
+ toc: `Run \`${buildDocumentationCommand(packageManager)}\` to generate a table of contents`,
756
+ ...projectTypeResults.documentation,
910
757
  contributing: `### Dependencies
911
758
 
912
759
  \`\`\`sh
@@ -919,43 +766,43 @@ $ ${packageManager} install
919
766
  \`\`\`sh
920
767
  $ ${packageManager} test
921
768
  \`\`\``
922
- });
769
+ };
923
770
  }
924
771
 
925
772
  async function determineLatestVersionOf(nodeVersionCategory) {
926
- cliMessages.info('Determining version of node', {
927
- level: 'secondary'
928
- });
929
- const {
930
- stdout: nvmLsOutput
931
- } = await execa__default["default"](`. ~/.nvm/nvm.sh && nvm ls-remote${'LTS' === nodeVersionCategory ? ' --lts' : ''}`, {
932
- shell: true
933
- });
773
+ cliMessages.info('Determining version of node', {level: 'secondary'});
774
+
775
+ const {stdout: nvmLsOutput} = await execa__default["default"](
776
+ `. ~/.nvm/nvm.sh && nvm ls-remote${('LTS' === nodeVersionCategory) ? ' --lts' : ''}`,
777
+ {shell: true}
778
+ );
779
+
934
780
  const lsLines = nvmLsOutput.split('\n');
935
781
  const lsLine = lsLines[lsLines.length - 2];
782
+
936
783
  return lsLine.match(/(v[0-9]+)\.[0-9]+\.[0-9]+/)[1];
937
784
  }
785
+
938
786
  function install(nodeVersionCategory) {
939
- cliMessages.info(`Installing ${nodeVersionCategory} version of node using nvm`, {
940
- level: 'secondary'
941
- });
942
- const subprocess = execa__default["default"]('. ~/.nvm/nvm.sh && nvm install', {
943
- shell: true
944
- });
787
+ cliMessages.info(`Installing ${nodeVersionCategory} version of node using nvm`, {level: 'secondary'});
788
+
789
+ const subprocess = execa__default["default"]('. ~/.nvm/nvm.sh && nvm install', {shell: true});
945
790
  subprocess.stdout.pipe(process.stdout);
946
791
  return subprocess;
947
792
  }
948
793
 
949
- async function scaffoldNodeVersion ({
950
- projectRoot,
951
- nodeVersionCategory
952
- }) {
794
+ async function scaffoldNodeVersion ({projectRoot, nodeVersionCategory}) {
953
795
  if (!nodeVersionCategory) return undefined;
796
+
954
797
  const lowerCaseCategory = nodeVersionCategory.toLowerCase();
955
798
  cliMessages.info(`Configuring ${lowerCaseCategory} version of node`);
799
+
956
800
  const version = await determineLatestVersionOf(nodeVersionCategory);
801
+
957
802
  await fs.promises.writeFile(`${projectRoot}/.nvmrc`, version);
803
+
958
804
  await install(nodeVersionCategory);
805
+
959
806
  return version;
960
807
  }
961
808
 
@@ -966,54 +813,52 @@ function buildBadgesDetails (contributors) {
966
813
  function buildVcsIgnoreLists (vcsIgnoreLists = {}) {
967
814
  return {
968
815
  files: vcsIgnoreLists.files || [],
969
- directories: ['/node_modules/', ...(vcsIgnoreLists.directories || [])]
816
+ directories: ['/node_modules/', ...vcsIgnoreLists.directories || []]
970
817
  };
971
818
  }
972
819
 
973
820
  function buildPackageName (projectName, scope) {
974
821
  const name = `${scope ? `@${scope}/` : ''}${projectName}`;
975
- const {
976
- validForNewPackages,
977
- errors
978
- } = validatePackageName__default["default"](name);
822
+
823
+ const {validForNewPackages, errors} = validatePackageName__default["default"](name);
824
+
979
825
  if (validForNewPackages) return name;
980
826
  if (1 === errors.length && errors.includes('name cannot start with a period')) return projectName.slice(1);
827
+
981
828
  throw new Error(`The package name ${name} is invalid:${os.EOL}\t* ${errors.join(`${os.EOL}\t* `)}`);
982
829
  }
983
830
 
984
- async function chooseApplicationType ({
985
- types,
986
- projectType,
987
- decisions
988
- }) {
831
+ async function chooseApplicationType ({types, projectType, decisions}) {
989
832
  if (!Object.keys(types).length) return 'Other';
833
+
990
834
  const answers = await overridablePrompts.prompt([{
991
835
  name: questionNames$1.PROJECT_TYPE_CHOICE,
992
836
  type: 'list',
993
837
  message: `What type of ${projectType} is this?`,
994
838
  choices: [...Object.keys(types), new overridablePrompts.Separator(), 'Other']
995
839
  }], decisions);
840
+
996
841
  return answers[questionNames$1.PROJECT_TYPE_CHOICE];
997
842
  }
998
843
 
999
844
  function getInstallationCommand(packageManager) {
1000
845
  if (javascriptCore.packageManagers.NPM === packageManager) return 'npm install';
1001
846
  if (javascriptCore.packageManagers.YARN === packageManager) return 'yarn add';
1002
- throw new Error(`The ${packageManager} package manager is currently not supported. ` + `Only ${Object.values(javascriptCore.packageManagers).join(' and ')} are currently supported.`);
847
+
848
+ throw new Error(
849
+ `The ${packageManager} package manager is currently not supported. `
850
+ + `Only ${Object.values(javascriptCore.packageManagers).join(' and ')} are currently supported.`
851
+ );
1003
852
  }
1004
853
 
1005
- function scaffoldPackageDocumentation ({
1006
- scope,
1007
- packageName,
1008
- packageManager,
1009
- visibility
1010
- }) {
854
+ function scaffoldPackageDocumentation ({scope, packageName, packageManager, visibility}) {
1011
855
  return {
1012
856
  usage: `### Installation
1013
857
  ${'Private' === visibility ? `
1014
858
  :warning: this is a private package, so you will need to use an npm token with
1015
859
  access to private packages under \`@${scope}\`
1016
- ` : ''}
860
+ ` : ''
861
+ }
1017
862
  \`\`\`sh
1018
863
  $ ${getInstallationCommand(packageManager)} ${packageName}
1019
864
  \`\`\`
@@ -1026,48 +871,56 @@ run \`${buildDocumentationCommand(packageManager)}\` to inject the usage example
1026
871
 
1027
872
  function defineBadges (packageName, visibility) {
1028
873
  return {
1029
- consumer: _objectSpread2({}, 'Public' === visibility && {
1030
- npm: {
1031
- img: `https://img.shields.io/npm/v/${packageName}?logo=npm`,
1032
- text: 'npm',
1033
- link: `https://www.npmjs.com/package/${packageName}`
874
+ consumer: {
875
+ ...'Public' === visibility && {
876
+ npm: {
877
+ img: `https://img.shields.io/npm/v/${packageName}?logo=npm`,
878
+ text: 'npm',
879
+ link: `https://www.npmjs.com/package/${packageName}`
880
+ }
1034
881
  }
1035
- }),
882
+ },
1036
883
  status: {}
1037
884
  };
1038
885
  }
1039
886
 
1040
- async function chooseBundler ({
1041
- bundlers,
1042
- decisions
1043
- }) {
887
+ async function chooseBundler ({bundlers, decisions}) {
1044
888
  if (!Object.keys(bundlers).length) return 'Other';
889
+
1045
890
  const answers = await overridablePrompts.prompt([{
1046
891
  name: questionNames$1.PACKAGE_BUNDLER,
1047
892
  type: 'list',
1048
893
  message: 'Which bundler should be used?',
1049
894
  choices: [...Object.keys(bundlers), new overridablePrompts.Separator(), 'Other']
1050
895
  }], decisions);
896
+
1051
897
  return answers[questionNames$1.PACKAGE_BUNDLER];
1052
898
  }
1053
899
 
1054
900
  function determinePathToTemplateFile (fileName) {
901
+ const [, __dirname] = filedirname__default["default"]();
902
+
1055
903
  return path.resolve(__dirname, '..', 'templates', fileName);
1056
904
  }
1057
905
 
1058
906
  const defaultBuildDirectory$2 = 'lib';
1059
907
 
1060
908
  async function createExample(projectRoot, projectName) {
1061
- return fs.promises.writeFile(`${projectRoot}/example.js`, mustache__default["default"].render(await fs.promises.readFile(determinePathToTemplateFile('example.mustache'), 'utf8'), {
1062
- projectName: camelcase__default["default"](projectName)
1063
- }));
909
+ return fs.promises.writeFile(
910
+ `${projectRoot}/example.js`,
911
+ mustache__default["default"].render(
912
+ await fs.promises.readFile(determinePathToTemplateFile('example.mustache'), 'utf8'),
913
+ {projectName: camelcase__default["default"](projectName)}
914
+ )
915
+ );
1064
916
  }
1065
917
 
1066
- async function buildDetailsForCommonJsProject({
1067
- projectRoot,
1068
- projectName
1069
- }) {
1070
- await Promise.all([touch__default["default"](`${projectRoot}/index.js`), fs.promises.writeFile(`${projectRoot}/example.js`, `const ${camelcase__default["default"](projectName)} = require('.');\n`)]);
918
+ async function buildDetailsForCommonJsProject({projectRoot, projectName}) {
919
+ await Promise.all([
920
+ touch__default["default"](`${projectRoot}/index.js`),
921
+ fs.promises.writeFile(`${projectRoot}/example.js`, `const ${camelcase__default["default"](projectName)} = require('.');\n`)
922
+ ]);
923
+
1071
924
  return {};
1072
925
  }
1073
926
 
@@ -1080,42 +933,42 @@ async function buildDetails ({
1080
933
  dialect,
1081
934
  decisions
1082
935
  }) {
1083
- if (javascriptCore.dialects.COMMON_JS === dialect) return buildDetailsForCommonJsProject({
1084
- projectRoot,
1085
- projectName
1086
- });
1087
- const chosenBundler = await chooseBundler({
1088
- bundlers: packageBundlers,
1089
- decisions
1090
- });
936
+ if (javascriptCore.dialects.COMMON_JS === dialect) return buildDetailsForCommonJsProject({projectRoot, projectName});
937
+
938
+ const chosenBundler = await chooseBundler({bundlers: packageBundlers, decisions});
939
+
1091
940
  const pathToCreatedSrcDirectory = await makeDir__default["default"](`${projectRoot}/src`);
1092
- const [bundlerResults] = await Promise.all([javascriptCore.scaffoldChoice(packageBundlers, chosenBundler, {
1093
- projectRoot,
1094
- dialect,
1095
- projectType: javascriptCore.projectTypes.PACKAGE
1096
- }), await createExample(projectRoot, projectName), touch__default["default"](`${pathToCreatedSrcDirectory}/index.js`)]);
1097
- return deepmerge__default["default"](bundlerResults, {
1098
- devDependencies: ['rimraf'],
1099
- scripts: {
1100
- clean: `rimraf ./${defaultBuildDirectory$2}`,
1101
- prebuild: 'run-s clean',
1102
- build: 'npm-run-all --print-label --parallel build:*',
1103
- prepack: 'run-s build'
1104
- },
1105
- vcsIgnore: {
1106
- directories: [`/${defaultBuildDirectory$2}/`]
1107
- },
1108
- buildDirectory: defaultBuildDirectory$2,
1109
- badges: {
1110
- consumer: _objectSpread2({}, 'Public' === visibility && {
1111
- runkit: {
1112
- img: `https://badge.runkitcdn.com/${packageName}.svg`,
1113
- text: `Try ${packageName} on RunKit`,
1114
- link: `https://npm.runkit.com/${packageName}`
941
+ const [bundlerResults] = await Promise.all([
942
+ javascriptCore.scaffoldChoice(packageBundlers, chosenBundler, {projectRoot, dialect, projectType: javascriptCore.projectTypes.PACKAGE}),
943
+ await createExample(projectRoot, projectName),
944
+ touch__default["default"](`${pathToCreatedSrcDirectory}/index.js`)
945
+ ]);
946
+
947
+ return deepmerge__default["default"](
948
+ bundlerResults,
949
+ {
950
+ devDependencies: ['rimraf'],
951
+ scripts: {
952
+ clean: `rimraf ./${defaultBuildDirectory$2}`,
953
+ prebuild: 'run-s clean',
954
+ build: 'npm-run-all --print-label --parallel build:*',
955
+ prepack: 'run-s build'
956
+ },
957
+ vcsIgnore: {directories: [`/${defaultBuildDirectory$2}/`]},
958
+ buildDirectory: defaultBuildDirectory$2,
959
+ badges: {
960
+ consumer: {
961
+ ...'Public' === visibility && {
962
+ runkit: {
963
+ img: `https://badge.runkitcdn.com/${packageName}.svg`,
964
+ text: `Try ${packageName} on RunKit`,
965
+ link: `https://npm.runkit.com/${packageName}`
966
+ }
967
+ }
1115
968
  }
1116
- })
969
+ }
1117
970
  }
1118
- });
971
+ );
1119
972
  }
1120
973
 
1121
974
  async function scaffoldPackageType ({
@@ -1133,78 +986,70 @@ async function scaffoldPackageType ({
1133
986
  publishRegistry
1134
987
  }) {
1135
988
  cliMessages.info('Scaffolding Package Details');
1136
- const [detailsForBuild] = await Promise.all([buildDetails({
1137
- projectRoot,
1138
- projectName,
1139
- packageBundlers,
1140
- visibility,
1141
- packageName,
1142
- dialect,
1143
- decisions
1144
- }), javascriptCore.mergeIntoExistingPackageJson({
1145
- projectRoot,
1146
- config: _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({
1147
- files: ['example.js', ...(javascriptCore.dialects.COMMON_JS === dialect ? ['index.js'] : ['lib/'])],
1148
- publishConfig: _objectSpread2({
1149
- access: 'Public' === visibility ? 'public' : 'restricted'
1150
- }, publishRegistry && {
1151
- registry: publishRegistry
1152
- }),
1153
- sideEffects: false
1154
- }, 'Public' === visibility && {
1155
- runkitExampleFilename: './example.js'
1156
- }), javascriptCore.dialects.BABEL === dialect && {
1157
- main: './lib/index.cjs.js',
1158
- module: './lib/index.es.js',
1159
- exports: {
1160
- require: './lib/index.cjs.js',
1161
- import: './lib/index.es.js'
1162
- }
1163
- }), javascriptCore.dialects.ESM === dialect && {
1164
- main: './lib/index.es.js',
1165
- exports: './lib/index.es.js'
1166
- }), javascriptCore.dialects.TYPESCRIPT === dialect && {
1167
- main: './lib/index.cjs.js',
1168
- module: './lib/index.es.js',
1169
- types: './lib/index.d.ts',
1170
- exports: {
1171
- types: './lib/index.d.ts',
1172
- require: './lib/index.cjs.js',
1173
- import: './lib/index.es.js'
989
+
990
+ const [detailsForBuild] = await Promise.all([
991
+ buildDetails({projectRoot, projectName, packageBundlers, visibility, packageName, dialect, decisions}),
992
+ javascriptCore.mergeIntoExistingPackageJson({
993
+ projectRoot,
994
+ config: {
995
+ files: ['example.js', ...javascriptCore.dialects.COMMON_JS === dialect ? ['index.js'] : ['lib/']],
996
+ publishConfig: {
997
+ access: 'Public' === visibility ? 'public' : 'restricted',
998
+ ...publishRegistry && {registry: publishRegistry}
999
+ },
1000
+ sideEffects: false,
1001
+ ...'Public' === visibility && {runkitExampleFilename: './example.js'},
1002
+ ...javascriptCore.dialects.BABEL === dialect && {
1003
+ main: './lib/index.cjs.js',
1004
+ module: './lib/index.es.js',
1005
+ exports: {
1006
+ require: './lib/index.cjs.js',
1007
+ import: './lib/index.es.js'
1008
+ }
1009
+ },
1010
+ ...javascriptCore.dialects.ESM === dialect && {
1011
+ main: './lib/index.es.js',
1012
+ exports: './lib/index.es.js'
1013
+ },
1014
+ ...javascriptCore.dialects.TYPESCRIPT === dialect && {
1015
+ main: './lib/index.cjs.js',
1016
+ module: './lib/index.es.js',
1017
+ types: './lib/index.d.ts',
1018
+ exports: {
1019
+ types: './lib/index.d.ts',
1020
+ require: './lib/index.cjs.js',
1021
+ import: './lib/index.es.js'
1022
+ }
1023
+ }
1174
1024
  }
1175
1025
  })
1176
- })]);
1177
- const chosenType = await chooseApplicationType({
1178
- types: packageTypes,
1179
- projectType: 'package',
1180
- decisions
1181
- });
1182
- const results = await javascriptCore.scaffoldChoice(packageTypes, chosenType, {
1183
- projectRoot,
1184
- projectName,
1185
- packageName,
1186
- tests,
1187
- scope
1188
- });
1189
- return deepmerge__default["default"].all([{
1190
- documentation: scaffoldPackageDocumentation({
1191
- packageName,
1192
- visibility,
1193
- scope,
1194
- packageManager
1195
- }),
1196
- eslintConfigs: [],
1197
- nextSteps: [{
1198
- summary: 'Add the appropriate `save` flag to the installation instructions in the README'
1199
- }, {
1200
- summary: 'Publish pre-release versions to npm until package is stable enough to publish v1.0.0'
1201
- }],
1202
- scripts: {},
1203
- badges: defineBadges(packageName, visibility)
1204
- }, detailsForBuild, results]);
1026
+ ]);
1027
+
1028
+ const chosenType = await chooseApplicationType({types: packageTypes, projectType: 'package', decisions});
1029
+ const results = await javascriptCore.scaffoldChoice(
1030
+ packageTypes,
1031
+ chosenType,
1032
+ {projectRoot, projectName, packageName, tests, scope}
1033
+ );
1034
+
1035
+ return deepmerge__default["default"].all([
1036
+ {
1037
+ documentation: scaffoldPackageDocumentation({packageName, visibility, scope, packageManager}),
1038
+ eslintConfigs: [],
1039
+ nextSteps: [
1040
+ {summary: 'Add the appropriate `save` flag to the installation instructions in the README'},
1041
+ {summary: 'Publish pre-release versions to npm until package is stable enough to publish v1.0.0'}
1042
+ ],
1043
+ scripts: {},
1044
+ badges: defineBadges(packageName, visibility)
1045
+ },
1046
+ detailsForBuild,
1047
+ results
1048
+ ]);
1205
1049
  }
1206
1050
 
1207
1051
  const defaultBuildDirectory$1 = 'lib';
1052
+
1208
1053
  async function scaffoldApplicationType ({
1209
1054
  applicationTypes,
1210
1055
  projectRoot,
@@ -1215,112 +1060,94 @@ async function scaffoldApplicationType ({
1215
1060
  decisions
1216
1061
  }) {
1217
1062
  cliMessages.info('Scaffolding Application Details');
1218
- const [chosenType] = await Promise.all([chooseApplicationType({
1219
- types: applicationTypes,
1220
- projectType: 'application',
1221
- decisions
1222
- }), javascriptCore.mergeIntoExistingPackageJson({
1223
- projectRoot,
1224
- config: {
1225
- private: true
1226
- }
1227
- })]);
1228
- const results = await javascriptCore.scaffoldChoice(applicationTypes, chosenType, {
1229
- projectRoot,
1230
- projectName,
1231
- packageName,
1232
- packageManager,
1233
- tests
1234
- });
1063
+
1064
+ const [chosenType] = await Promise.all([
1065
+ chooseApplicationType({types: applicationTypes, projectType: 'application', decisions}),
1066
+ javascriptCore.mergeIntoExistingPackageJson({projectRoot, config: {private: true}})
1067
+ ]);
1068
+
1069
+ const results = await javascriptCore.scaffoldChoice(
1070
+ applicationTypes,
1071
+ chosenType,
1072
+ {projectRoot, projectName, packageName, packageManager, tests}
1073
+ );
1074
+
1235
1075
  const buildDirectory = results.buildDirectory || defaultBuildDirectory$1;
1236
- return deepmerge__default["default"]({
1237
- scripts: {
1238
- clean: `rimraf ./${buildDirectory}`,
1239
- start: `node ./${buildDirectory}/index.js`,
1240
- prebuild: 'run-s clean'
1241
- },
1242
- dependencies: [],
1243
- devDependencies: ['rimraf'],
1244
- vcsIgnore: {
1245
- files: ['.env'],
1246
- directories: [`/${buildDirectory}/`]
1076
+
1077
+ return deepmerge__default["default"](
1078
+ {
1079
+ scripts: {
1080
+ clean: `rimraf ./${buildDirectory}`,
1081
+ start: `node ./${buildDirectory}/index.js`,
1082
+ prebuild: 'run-s clean'
1083
+ },
1084
+ dependencies: [],
1085
+ devDependencies: ['rimraf'],
1086
+ vcsIgnore: {files: ['.env'], directories: [`/${buildDirectory}/`]},
1087
+ buildDirectory,
1088
+ eslintConfigs: [],
1089
+ nextSteps: []
1247
1090
  },
1248
- buildDirectory,
1249
- eslintConfigs: [],
1250
- nextSteps: []
1251
- }, results);
1091
+ results
1092
+ );
1252
1093
  }
1253
1094
 
1254
- async function scaffoldMonorepoType ({
1255
- monorepoTypes,
1256
- projectRoot,
1257
- packageManager,
1258
- decisions
1259
- }) {
1095
+ async function scaffoldMonorepoType ({monorepoTypes, projectRoot, packageManager, decisions}) {
1260
1096
  cliMessages.info('Scaffolding Monorepo Details');
1261
- const chosenType = await chooseApplicationType({
1262
- types: monorepoTypes,
1263
- projectType: javascriptCore.projectTypes.MONOREPO,
1264
- decisions
1265
- });
1266
- const results = await javascriptCore.scaffoldChoice(monorepoTypes, chosenType, {
1267
- projectRoot,
1268
- packageManager
1269
- });
1270
- return deepmerge__default["default"]({
1271
- eslintConfigs: [],
1272
- packageProperties: {
1273
- private: true
1097
+
1098
+ const chosenType = await chooseApplicationType({types: monorepoTypes, projectType: javascriptCore.projectTypes.MONOREPO, decisions});
1099
+ const results = await javascriptCore.scaffoldChoice(monorepoTypes, chosenType, {projectRoot, packageManager});
1100
+
1101
+ return deepmerge__default["default"](
1102
+ {
1103
+ eslintConfigs: [],
1104
+ packageProperties: {private: true},
1105
+ nextSteps: [{
1106
+ summary: 'Add packages to your new monorepo',
1107
+ description: 'Leverage [@form8ion/add-package-to-monorepo](https://npm.im/@form8ion/add-package-to-monorepo)'
1108
+ + ' to scaffold new packages into your new monorepo'
1109
+ }]
1274
1110
  },
1275
- nextSteps: [{
1276
- summary: 'Add packages to your new monorepo',
1277
- description: 'Leverage [@form8ion/add-package-to-monorepo](https://npm.im/@form8ion/add-package-to-monorepo)' + ' to scaffold new packages into your new monorepo'
1278
- }]
1279
- }, results);
1111
+ results
1112
+ );
1280
1113
  }
1281
1114
 
1282
1115
  const defaultBuildDirectory = 'bin';
1283
- async function scaffoldCliType ({
1284
- packageName,
1285
- visibility,
1286
- projectRoot,
1287
- dialect,
1288
- publishRegistry
1289
- }) {
1290
- const [rollupResults] = await Promise.all([rollup.scaffold({
1291
- projectRoot,
1292
- dialect,
1293
- projectType: javascriptCore.projectTypes.CLI
1294
- }), javascriptCore.mergeIntoExistingPackageJson({
1295
- projectRoot,
1296
- config: {
1297
- bin: {},
1298
- files: [`${defaultBuildDirectory}/`],
1299
- publishConfig: _objectSpread2({
1300
- access: 'Public' === visibility ? 'public' : 'restricted'
1301
- }, publishRegistry && {
1302
- registry: publishRegistry
1303
- })
1116
+
1117
+ async function scaffoldCliType ({packageName, visibility, projectRoot, dialect, publishRegistry}) {
1118
+ const [rollupResults] = await Promise.all([
1119
+ rollup.scaffold({projectRoot, dialect, projectType: javascriptCore.projectTypes.CLI}),
1120
+ javascriptCore.mergeIntoExistingPackageJson({
1121
+ projectRoot,
1122
+ config: {
1123
+ bin: {},
1124
+ files: [`${defaultBuildDirectory}/`],
1125
+ publishConfig: {
1126
+ access: 'Public' === visibility ? 'public' : 'restricted',
1127
+ ...publishRegistry && {registry: publishRegistry}
1128
+ }
1129
+ }
1130
+ })
1131
+ ]);
1132
+
1133
+ return deepmerge__default["default"](
1134
+ rollupResults,
1135
+ {
1136
+ scripts: {
1137
+ clean: `rimraf ./${defaultBuildDirectory}`,
1138
+ prebuild: 'run-s clean',
1139
+ build: 'npm-run-all --print-label --parallel build:*',
1140
+ prepack: 'run-s build'
1141
+ },
1142
+ dependencies: ['update-notifier'],
1143
+ devDependencies: ['rimraf'],
1144
+ vcsIgnore: {files: [], directories: [`/${defaultBuildDirectory}/`]},
1145
+ buildDirectory: defaultBuildDirectory,
1146
+ badges: defineBadges(packageName, visibility),
1147
+ eslintConfigs: [],
1148
+ nextSteps: []
1304
1149
  }
1305
- })]);
1306
- return deepmerge__default["default"](rollupResults, {
1307
- scripts: {
1308
- clean: `rimraf ./${defaultBuildDirectory}`,
1309
- prebuild: 'run-s clean',
1310
- build: 'npm-run-all --print-label --parallel build:*',
1311
- prepack: 'run-s build'
1312
- },
1313
- dependencies: ['update-notifier'],
1314
- devDependencies: ['rimraf'],
1315
- vcsIgnore: {
1316
- files: [],
1317
- directories: [`/${defaultBuildDirectory}/`]
1318
- },
1319
- buildDirectory: defaultBuildDirectory,
1320
- badges: defineBadges(packageName, visibility),
1321
- eslintConfigs: [],
1322
- nextSteps: []
1323
- });
1150
+ );
1324
1151
  }
1325
1152
 
1326
1153
  async function scaffoldProjectType ({
@@ -1358,7 +1185,6 @@ async function scaffoldProjectType ({
1358
1185
  dialect,
1359
1186
  publishRegistry
1360
1187
  });
1361
-
1362
1188
  case javascriptCore.projectTypes.APPLICATION:
1363
1189
  return scaffoldApplicationType({
1364
1190
  projectRoot,
@@ -1369,29 +1195,14 @@ async function scaffoldProjectType ({
1369
1195
  tests,
1370
1196
  decisions
1371
1197
  });
1372
-
1373
1198
  case javascriptCore.projectTypes.CLI:
1374
- return scaffoldCliType({
1375
- packageName,
1376
- visibility,
1377
- projectRoot,
1378
- dialect,
1379
- publishRegistry
1380
- });
1381
-
1199
+ return scaffoldCliType({packageName, visibility, projectRoot, dialect, publishRegistry});
1382
1200
  case javascriptCore.projectTypes.MONOREPO:
1383
- return scaffoldMonorepoType({
1384
- monorepoTypes,
1385
- projectRoot,
1386
- packageManager,
1387
- decisions
1388
- });
1389
-
1201
+ return scaffoldMonorepoType({monorepoTypes, projectRoot, packageManager, decisions});
1390
1202
  case 'Other':
1391
1203
  return {
1392
1204
  eslintConfigs: []
1393
1205
  };
1394
-
1395
1206
  default:
1396
1207
  throw new Error(`The project-type of ${projectType} is invalid`);
1397
1208
  }
@@ -1400,48 +1211,39 @@ async function scaffoldProjectType ({
1400
1211
  async function scaffoldTesting ({
1401
1212
  projectRoot,
1402
1213
  visibility,
1403
- tests: {
1404
- unit,
1405
- integration
1406
- },
1214
+ tests: {unit, integration},
1407
1215
  vcs,
1408
1216
  unitTestFrameworks,
1409
1217
  decisions,
1410
1218
  dialect,
1411
1219
  pathWithinParent
1412
1220
  }) {
1413
- const unitResults = unit ? await scaffoldUnitTesting({
1414
- projectRoot,
1415
- visibility,
1416
- vcs,
1417
- frameworks: unitTestFrameworks,
1418
- decisions,
1419
- dialect,
1420
- pathWithinParent
1421
- }) : {};
1422
- return deepmerge__default["default"]({
1423
- devDependencies: [...(unit || integration ? ['@travi/any'] : [])],
1424
- eslint: {}
1425
- }, unitResults);
1221
+ const unitResults = unit
1222
+ ? await scaffoldUnitTesting({
1223
+ projectRoot,
1224
+ visibility,
1225
+ vcs,
1226
+ frameworks: unitTestFrameworks,
1227
+ decisions,
1228
+ dialect,
1229
+ pathWithinParent
1230
+ })
1231
+ : {};
1232
+
1233
+ return deepmerge__default["default"]({devDependencies: [...(unit || integration) ? ['@travi/any'] : []], eslint: {}}, unitResults);
1426
1234
  }
1427
1235
 
1428
- function scaffoldBanSensitiveFiles ({
1429
- pathWithinParent
1430
- }) {
1236
+ function scaffoldBanSensitiveFiles ({pathWithinParent}) {
1431
1237
  if (pathWithinParent) return {};
1432
- return {
1433
- scripts: {
1434
- 'lint:sensitive': 'ban'
1435
- },
1436
- devDependencies: ['ban-sensitive-files']
1437
- };
1238
+
1239
+ return {scripts: {'lint:sensitive': 'ban'}, devDependencies: ['ban-sensitive-files']};
1438
1240
  }
1439
1241
 
1440
- function buildAllowedHostsList ({
1441
- packageManager,
1442
- registries
1443
- }) {
1444
- return [...(!registries || registries && !registries.registry ? [packageManager] : []), ...Object.values(Object.fromEntries(Object.entries(registries).filter(([scope]) => 'publish' !== scope)))];
1242
+ function buildAllowedHostsList ({packageManager, registries}) {
1243
+ return [
1244
+ ...(!registries || (registries && !registries.registry)) ? [packageManager] : [],
1245
+ ...Object.values(Object.fromEntries(Object.entries(registries).filter(([scope]) => 'publish' !== scope)))
1246
+ ];
1445
1247
  }
1446
1248
 
1447
1249
  const lockfileLintSupportedPackageManagers = [javascriptCore.packageManagers.NPM, javascriptCore.packageManagers.YARN];
@@ -1451,6 +1253,7 @@ function determineLockfilePathFor(packageManager) {
1451
1253
  [javascriptCore.packageManagers.NPM]: 'package-lock.json',
1452
1254
  [javascriptCore.packageManagers.YARN]: 'yarn.lock'
1453
1255
  };
1256
+
1454
1257
  return lockfilePaths[packageManager];
1455
1258
  }
1456
1259
 
@@ -1458,46 +1261,35 @@ function lockfileLintSupports(packageManager) {
1458
1261
  return lockfileLintSupportedPackageManagers.includes(packageManager);
1459
1262
  }
1460
1263
 
1461
- async function scaffoldLockfileLint ({
1462
- projectRoot,
1463
- packageManager,
1464
- registries
1465
- }) {
1264
+ async function scaffoldLockfileLint ({projectRoot, packageManager, registries}) {
1466
1265
  if (!lockfileLintSupports(packageManager)) {
1467
- throw new Error(`The ${packageManager} package manager is currently not supported by lockfile-lint. ` + `Only ${lockfileLintSupportedPackageManagers.join(' and ')} are currently supported.`);
1266
+ throw new Error(
1267
+ `The ${packageManager} package manager is currently not supported by lockfile-lint. `
1268
+ + `Only ${lockfileLintSupportedPackageManagers.join(' and ')} are currently supported.`
1269
+ );
1468
1270
  }
1469
1271
 
1470
- await fs.promises.writeFile(`${projectRoot}/.lockfile-lintrc.json`, JSON.stringify({
1471
- path: determineLockfilePathFor(packageManager),
1472
- type: packageManager,
1473
- 'validate-https': true,
1474
- 'allowed-hosts': buildAllowedHostsList({
1475
- packageManager,
1476
- registries
1272
+ await fs.promises.writeFile(
1273
+ `${projectRoot}/.lockfile-lintrc.json`,
1274
+ JSON.stringify({
1275
+ path: determineLockfilePathFor(packageManager),
1276
+ type: packageManager,
1277
+ 'validate-https': true,
1278
+ 'allowed-hosts': buildAllowedHostsList({packageManager, registries})
1477
1279
  })
1478
- }));
1280
+ );
1281
+
1479
1282
  return {
1480
1283
  devDependencies: ['lockfile-lint'],
1481
- scripts: {
1482
- 'lint:lockfile': 'lockfile-lint'
1483
- }
1284
+ scripts: {'lint:lockfile': 'lockfile-lint'}
1484
1285
  };
1485
1286
  }
1486
1287
 
1487
- async function scaffoldLinting ({
1488
- projectRoot,
1489
- packageManager,
1490
- registries,
1491
- vcs,
1492
- pathWithinParent
1493
- }) {
1494
- return deepmerge__default["default"].all(await Promise.all([scaffoldLockfileLint({
1495
- projectRoot,
1496
- packageManager,
1497
- registries
1498
- }), vcs ? scaffoldBanSensitiveFiles({
1499
- pathWithinParent
1500
- }) : {}]));
1288
+ async function scaffoldLinting ({projectRoot, packageManager, registries, vcs, pathWithinParent}) {
1289
+ return deepmerge__default["default"].all(await Promise.all([
1290
+ scaffoldLockfileLint({projectRoot, packageManager, registries}),
1291
+ vcs ? scaffoldBanSensitiveFiles({pathWithinParent}) : {}
1292
+ ]));
1501
1293
  }
1502
1294
 
1503
1295
  async function scaffoldVerification({
@@ -1512,60 +1304,33 @@ async function scaffoldVerification({
1512
1304
  decisions,
1513
1305
  pathWithinParent
1514
1306
  }) {
1515
- const [testingResults, lintingResults, huskyResults] = await Promise.all([scaffoldTesting({
1516
- projectRoot,
1517
- tests,
1518
- visibility,
1519
- vcs,
1520
- unitTestFrameworks,
1521
- decisions,
1522
- dialect,
1523
- pathWithinParent
1524
- }), scaffoldLinting({
1525
- projectRoot,
1526
- packageManager,
1527
- registries,
1528
- vcs,
1529
- pathWithinParent
1530
- }), huskyPlugin.scaffold({
1531
- projectRoot,
1532
- packageManager,
1533
- pathWithinParent
1534
- })]);
1307
+ const [testingResults, lintingResults, huskyResults] = await Promise.all([
1308
+ scaffoldTesting({
1309
+ projectRoot,
1310
+ tests,
1311
+ visibility,
1312
+ vcs,
1313
+ unitTestFrameworks,
1314
+ decisions,
1315
+ dialect,
1316
+ pathWithinParent
1317
+ }),
1318
+ scaffoldLinting({projectRoot, packageManager, registries, vcs, pathWithinParent}),
1319
+ huskyPlugin.scaffold({projectRoot, packageManager, pathWithinParent})
1320
+ ]);
1321
+
1535
1322
  return deepmerge__default["default"].all([testingResults, lintingResults, huskyResults]);
1536
1323
  }
1537
1324
 
1538
- async function scaffoldEslint ({
1539
- config,
1540
- projectRoot,
1541
- buildDirectory,
1542
- additionalConfiguration
1543
- }) {
1544
- const {
1545
- scope
1546
- } = config;
1547
- const {
1548
- ignore
1549
- } = additionalConfiguration;
1550
- const ignores = deepmerge__default["default"](ignore, {
1551
- directories: [`/${buildDirectory}/`]
1552
- });
1553
- return eslint.scaffold({
1554
- scope,
1555
- projectRoot,
1556
- ignore: {
1557
- directories: ignores.directories
1558
- }
1559
- });
1325
+ async function scaffoldEslint ({config, projectRoot, buildDirectory, additionalConfiguration}) {
1326
+ const {scope} = config;
1327
+ const {ignore} = additionalConfiguration;
1328
+ const ignores = deepmerge__default["default"](ignore, {directories: [`/${buildDirectory}/`]});
1329
+
1330
+ return eslint.scaffold({scope, projectRoot, ignore: {directories: ignores.directories}});
1560
1331
  }
1561
1332
 
1562
- async function scaffoldRemark ({
1563
- config,
1564
- projectRoot,
1565
- projectType,
1566
- vcs,
1567
- dialect
1568
- }) {
1333
+ async function scaffoldRemark ({config, projectRoot, projectType, vcs, dialect}) {
1569
1334
  await configFile.write({
1570
1335
  format: core.fileTypes.JSON,
1571
1336
  path: projectRoot,
@@ -1578,28 +1343,30 @@ async function scaffoldRemark ({
1578
1343
  bullet: '*',
1579
1344
  incrementListMarker: false
1580
1345
  },
1581
- plugins: [config, ['remark-toc', {
1582
- tight: true
1583
- }], ...(javascriptCore.projectTypes.PACKAGE === projectType ? [['remark-usage', {
1584
- heading: 'example'
1585
- }]] : []), ...(!vcs ? [['validate-links', {
1586
- repository: false
1587
- }]] : [])]
1346
+ plugins: [
1347
+ config,
1348
+ ['remark-toc', {tight: true}],
1349
+ ...javascriptCore.projectTypes.PACKAGE === projectType ? [['remark-usage', {heading: 'example'}]] : [],
1350
+ ...!vcs ? [['validate-links', {repository: false}]] : []
1351
+ ]
1588
1352
  }
1589
1353
  });
1590
- return deepmerge__default["default"]({
1591
- devDependencies: [config, 'remark-cli', 'remark-toc'],
1592
- scripts: {
1593
- 'lint:md': 'remark . --frail',
1594
- 'generate:md': 'remark . --output'
1595
- }
1596
- }, _objectSpread2({}, javascriptCore.projectTypes.PACKAGE === projectType && _objectSpread2({
1597
- devDependencies: ['remark-usage']
1598
- }, javascriptCore.dialects.COMMON_JS !== dialect && {
1599
- scripts: {
1600
- 'pregenerate:md': 'run-s build'
1354
+
1355
+ return deepmerge__default["default"](
1356
+ {
1357
+ devDependencies: [config, 'remark-cli', 'remark-toc'],
1358
+ scripts: {
1359
+ 'lint:md': 'remark . --frail',
1360
+ 'generate:md': 'remark . --output'
1361
+ }
1362
+ },
1363
+ {
1364
+ ...javascriptCore.projectTypes.PACKAGE === projectType && {
1365
+ devDependencies: ['remark-usage'],
1366
+ ...javascriptCore.dialects.COMMON_JS !== dialect && {scripts: {'pregenerate:md': 'run-s build'}}
1367
+ }
1601
1368
  }
1602
- })));
1369
+ );
1603
1370
  }
1604
1371
 
1605
1372
  async function scaffoldCodeStyle ({
@@ -1612,22 +1379,28 @@ async function scaffoldCodeStyle ({
1612
1379
  buildDirectory,
1613
1380
  eslint
1614
1381
  }) {
1615
- return deepmerge__default["default"].all(await Promise.all([configs.eslint && configureLinting ? scaffoldEslint({
1616
- projectRoot,
1617
- config: configs.eslint,
1618
- buildDirectory,
1619
- additionalConfiguration: eslint
1620
- }) : {}, scaffoldRemark({
1621
- projectRoot,
1622
- projectType,
1623
- dialect,
1624
- vcs,
1625
- config: configs.remark || '@form8ion/remark-lint-preset'
1626
- })]));
1382
+ return deepmerge__default["default"].all(await Promise.all([
1383
+ configs.eslint && configureLinting
1384
+ && scaffoldEslint({
1385
+ projectRoot,
1386
+ config: configs.eslint,
1387
+ buildDirectory,
1388
+ additionalConfiguration: eslint
1389
+ }),
1390
+ scaffoldRemark({
1391
+ projectRoot,
1392
+ projectType,
1393
+ dialect,
1394
+ vcs,
1395
+ config: configs.remark || '@form8ion/remark-lint-preset'
1396
+ }),
1397
+ prettier.scaffold({projectRoot, config: configs.prettier})
1398
+ ].filter(Boolean)));
1627
1399
  }
1628
1400
 
1629
1401
  async function scaffolder (options) {
1630
1402
  cliMessages.info('Initializing JavaScript project');
1403
+
1631
1404
  const {
1632
1405
  projectRoot,
1633
1406
  projectName,
@@ -1648,6 +1421,7 @@ async function scaffolder (options) {
1648
1421
  pathWithinParent,
1649
1422
  registries
1650
1423
  } = validate(options);
1424
+
1651
1425
  const {
1652
1426
  tests,
1653
1427
  projectType,
@@ -1660,13 +1434,11 @@ async function scaffolder (options) {
1660
1434
  packageManager,
1661
1435
  dialect
1662
1436
  } = await prompt(overrides, ciServices, hosts, visibility, vcs, decisions, configs, pathWithinParent);
1663
- cliMessages.info('Writing project files', {
1664
- level: 'secondary'
1665
- });
1437
+
1438
+ cliMessages.info('Writing project files', {level: 'secondary'});
1439
+
1666
1440
  const packageName = buildPackageName(projectName, scope);
1667
- const {
1668
- homepage: projectHomepage
1669
- } = await scaffoldPackage({
1441
+ const {homepage: projectHomepage} = await scaffoldPackage({
1670
1442
  projectRoot,
1671
1443
  projectType,
1672
1444
  dialect,
@@ -1677,111 +1449,106 @@ async function scaffolder (options) {
1677
1449
  description,
1678
1450
  pathWithinParent
1679
1451
  });
1680
- const [projectTypeResults, verificationResults] = await Promise.all([scaffoldProjectType({
1681
- projectType,
1682
- projectRoot,
1683
- projectName,
1684
- packageName,
1685
- packageManager,
1686
- visibility,
1687
- applicationTypes,
1688
- packageTypes,
1689
- packageBundlers,
1690
- monorepoTypes,
1691
- scope,
1692
- tests,
1693
- vcs,
1694
- decisions,
1695
- dialect,
1696
- publishRegistry: registries.publish
1697
- }), scaffoldVerification({
1698
- projectRoot,
1699
- dialect,
1700
- visibility,
1701
- packageManager,
1702
- vcs,
1703
- registries,
1704
- tests,
1705
- unitTestFrameworks,
1706
- decisions,
1707
- pathWithinParent
1708
- })]);
1709
- const [nodeVersion, npmResults, dialectResults, codeStyleResults] = await Promise.all([scaffoldNodeVersion({
1710
- projectRoot,
1711
- nodeVersionCategory
1712
- }), scaffoldNpmConfig({
1713
- projectType,
1714
- projectRoot,
1715
- registries
1716
- }), scaffoldDialect({
1717
- dialect,
1718
- configs,
1719
- projectRoot,
1720
- projectType,
1721
- buildDirectory: projectTypeResults.buildDirectory,
1722
- testFilenamePattern: verificationResults.testFilenamePattern
1723
- }), scaffoldCodeStyle({
1724
- projectRoot,
1725
- projectType,
1726
- dialect,
1727
- configs,
1728
- vcs,
1729
- configureLinting,
1730
- buildDirectory: projectTypeResults.buildDirectory,
1731
- eslint: verificationResults.eslint
1732
- })]);
1733
- const mergedContributions = deepmerge__default["default"].all([...(await Promise.all([javascriptCore.scaffoldChoice(hosts, chosenHost, {
1734
- buildDirectory: `./${projectTypeResults.buildDirectory}`,
1735
- projectRoot,
1736
- projectName,
1737
- nodeVersion
1738
- }), javascriptCore.scaffoldChoice(ciServices, ci, {
1739
- projectRoot,
1740
- vcs,
1741
- visibility,
1742
- projectType,
1743
- projectName,
1744
- nodeVersion,
1745
- tests
1746
- }), commitConventionPlugin.scaffold({
1747
- projectRoot,
1748
- projectType,
1749
- configs,
1750
- pathWithinParent
1751
- })])), projectTypeResults, verificationResults, codeStyleResults, npmResults, dialectResults]);
1452
+ const [projectTypeResults, verificationResults] = await Promise.all([
1453
+ scaffoldProjectType({
1454
+ projectType,
1455
+ projectRoot,
1456
+ projectName,
1457
+ packageName,
1458
+ packageManager,
1459
+ visibility,
1460
+ applicationTypes,
1461
+ packageTypes,
1462
+ packageBundlers,
1463
+ monorepoTypes,
1464
+ scope,
1465
+ tests,
1466
+ vcs,
1467
+ decisions,
1468
+ dialect,
1469
+ publishRegistry: registries.publish
1470
+ }),
1471
+ scaffoldVerification({
1472
+ projectRoot,
1473
+ dialect,
1474
+ visibility,
1475
+ packageManager,
1476
+ vcs,
1477
+ registries,
1478
+ tests,
1479
+ unitTestFrameworks,
1480
+ decisions,
1481
+ pathWithinParent
1482
+ })
1483
+ ]);
1484
+ const [nodeVersion, npmResults, dialectResults, codeStyleResults] = await Promise.all([
1485
+ scaffoldNodeVersion({projectRoot, nodeVersionCategory}),
1486
+ scaffoldNpmConfig({projectType, projectRoot, registries}),
1487
+ scaffoldDialect({
1488
+ dialect,
1489
+ configs,
1490
+ projectRoot,
1491
+ projectType,
1492
+ buildDirectory: projectTypeResults.buildDirectory,
1493
+ testFilenamePattern: verificationResults.testFilenamePattern
1494
+ }),
1495
+ scaffoldCodeStyle({
1496
+ projectRoot,
1497
+ projectType,
1498
+ dialect,
1499
+ configs,
1500
+ vcs,
1501
+ configureLinting,
1502
+ buildDirectory: projectTypeResults.buildDirectory,
1503
+ eslint: verificationResults.eslint
1504
+ })
1505
+ ]);
1506
+ const mergedContributions = deepmerge__default["default"].all([
1507
+ ...(await Promise.all([
1508
+ javascriptCore.scaffoldChoice(
1509
+ hosts,
1510
+ chosenHost,
1511
+ {buildDirectory: `./${projectTypeResults.buildDirectory}`, projectRoot, projectName, nodeVersion}
1512
+ ),
1513
+ javascriptCore.scaffoldChoice(ciServices, ci, {projectRoot, vcs, visibility, projectType, projectName, nodeVersion, tests}),
1514
+ commitConventionPlugin.scaffold({projectRoot, projectType, configs, pathWithinParent})
1515
+ ])),
1516
+ projectTypeResults,
1517
+ verificationResults,
1518
+ codeStyleResults,
1519
+ npmResults,
1520
+ dialectResults
1521
+ ]);
1522
+
1752
1523
  const liftResults = await lift({
1753
- results: deepmerge__default["default"]({
1754
- devDependencies: ['npm-run-all'],
1755
- packageManager
1756
- }, mergedContributions),
1524
+ results: deepmerge__default["default"]({devDependencies: ['npm-run-all'], packageManager}, mergedContributions),
1757
1525
  projectRoot,
1758
1526
  configs,
1759
1527
  vcs
1760
1528
  });
1529
+
1761
1530
  return {
1762
1531
  badges: buildBadgesDetails([mergedContributions, liftResults]),
1763
- documentation: scaffoldDocumentation({
1764
- projectTypeResults,
1765
- packageManager
1766
- }),
1532
+ documentation: scaffoldDocumentation({projectTypeResults, packageManager}),
1767
1533
  tags: projectTypeResults.tags,
1768
1534
  vcsIgnore: buildVcsIgnoreLists(mergedContributions.vcsIgnore),
1769
1535
  verificationCommand: `${buildDocumentationCommand(packageManager)} && ${packageManager} test`,
1770
- projectDetails: _objectSpread2({}, projectHomepage && {
1771
- homepage: projectHomepage
1772
- }),
1536
+ projectDetails: {...projectHomepage && {homepage: projectHomepage}},
1773
1537
  nextSteps: mergedContributions.nextSteps
1774
1538
  };
1775
1539
  }
1776
1540
 
1777
- async function test ({
1778
- projectRoot
1779
- }) {
1780
- const [nvmIsConfigured, packageLockExists, yarnLockExists] = await Promise.all([core.fileExists(`${projectRoot}/.nvmrc`), core.fileExists(`${projectRoot}/package-lock.json`), core.fileExists(`${projectRoot}/yarn.lock`)]);
1541
+ async function test ({projectRoot}) {
1542
+ const [nvmIsConfigured, packageLockExists, yarnLockExists] = await Promise.all([
1543
+ core.fileExists(`${projectRoot}/.nvmrc`),
1544
+ core.fileExists(`${projectRoot}/package-lock.json`),
1545
+ core.fileExists(`${projectRoot}/yarn.lock`)
1546
+ ]);
1547
+
1781
1548
  return nvmIsConfigured || packageLockExists || yarnLockExists;
1782
1549
  }
1783
1550
 
1784
- const questionNames = _objectSpread2(_objectSpread2({}, languageScaffolderPrompts.questionNames), questionNames$1);
1551
+ const questionNames = {...languageScaffolderPrompts.questionNames, ...questionNames$1};
1785
1552
 
1786
1553
  exports.lift = lift;
1787
1554
  exports.questionNames = questionNames;