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