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