@form8ion/javascript 15.8.3 → 16.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +4 -4
  2. package/example.js +2 -2
  3. package/lib/index.js +77 -63
  4. package/lib/index.js.map +1 -1
  5. package/package.json +18 -18
  6. package/src/code-style/lifter.js +2 -2
  7. package/src/dependencies/installer.js +5 -5
  8. package/src/dependencies/installer.test.js +8 -22
  9. package/src/dependencies/processor.js +10 -8
  10. package/src/dependencies/processor.test.js +31 -18
  11. package/src/dependencies/remover.js +2 -3
  12. package/src/dependencies/remover.test.js +4 -2
  13. package/src/lifter.js +8 -5
  14. package/src/lifter.test.js +12 -11
  15. package/src/node-version/scaffolder.js +4 -5
  16. package/src/node-version/scaffolder.test.js +5 -4
  17. package/src/node-version/tasks.js +4 -6
  18. package/src/node-version/tasks.test.js +5 -8
  19. package/src/options/schemas.js +2 -1
  20. package/src/options/schemas.test.js +12 -6
  21. package/src/options/validator.js +2 -1
  22. package/src/options/validator.test.js +2 -1
  23. package/src/package/lifter.js +3 -4
  24. package/src/package/lifter.test.js +8 -4
  25. package/src/package/scaffolder.js +2 -3
  26. package/src/package/scaffolder.test.js +3 -1
  27. package/src/project-type/application/scaffolder.js +2 -3
  28. package/src/project-type/application/scaffolder.test.js +3 -5
  29. package/src/project-type/monorepo/scaffolder.js +2 -3
  30. package/src/project-type/monorepo/scaffolder.test.js +3 -6
  31. package/src/project-type/package/scaffolder.js +2 -3
  32. package/src/project-type/package/scaffolder.test.js +6 -5
  33. package/src/project-type/publishable/access-level.js +1 -1
  34. package/src/project-type/publishable/access-level.test.js +6 -4
  35. package/src/project-type/scaffolder.js +4 -4
  36. package/src/project-type/scaffolder.test.js +15 -16
  37. package/src/prompts/conditionals.js +1 -1
  38. package/src/prompts/conditionals.test.js +27 -6
  39. package/src/prompts/questions.js +4 -4
  40. package/src/prompts/questions.test.js +21 -6
  41. package/src/prompts/validators.js +7 -2
  42. package/src/prompts/validators.test.js +9 -6
  43. package/src/scaffolder.js +7 -8
  44. package/src/scaffolder.test.js +6 -5
  45. package/src/tester.js +2 -4
  46. package/src/tester.test.js +5 -8
@@ -68,7 +68,8 @@ describe('options validator', () => {
68
68
  packageTypes: pluginsSchema,
69
69
  monorepoTypes: pluginsSchema,
70
70
  hosts: pluginsSchema,
71
- ciServices: pluginsSchema
71
+ ciServices: pluginsSchema,
72
+ registries: pluginsSchema
72
73
  }
73
74
  })
74
75
  .thenReturn({required: joiRequiredObject});
@@ -1,6 +1,5 @@
1
1
  import {promises as fs} from 'node:fs';
2
2
  import deepmerge from 'deepmerge';
3
- import {info} from '@travi/cli-messages';
4
3
  import {writePackageJson} from '@form8ion/javascript-core';
5
4
 
6
5
  import sortPackageProperties from './property-sorter.js';
@@ -17,8 +16,8 @@ export default async function liftPackageJson({
17
16
  packageManager,
18
17
  vcs,
19
18
  pathWithinParent
20
- }) {
21
- info('Updating `package.json`', {level: 'secondary'});
19
+ }, {logger}) {
20
+ logger.info('Updating `package.json`', {level: 'secondary'});
22
21
 
23
22
  const existingPackageJsonContents = JSON.parse(await fs.readFile(`${projectRoot}/package.json`, 'utf-8'));
24
23
  const {scripts: liftedScripts, dependencies: scriptDependencies} = liftScripts({
@@ -43,5 +42,5 @@ export default async function liftPackageJson({
43
42
  devDependencies,
44
43
  projectRoot,
45
44
  packageManager
46
- });
45
+ }, {logger});
47
46
  }
@@ -34,6 +34,7 @@ describe('package.json lifter', () => {
34
34
  const config = any.simpleObject();
35
35
  const tags = any.listOf(any.word);
36
36
  const scriptDependencies = any.simpleObject();
37
+ const logger = {info: () => undefined};
37
38
 
38
39
  beforeEach(() => {
39
40
  when(defineVcsHostDetails).calledWith(vcs, pathWithinParent).thenReturn(vcsDetails);
@@ -53,7 +54,10 @@ describe('package.json lifter', () => {
53
54
  .calledWith({...existingPackageContents, ...vcsDetails, scripts: liftedScripts})
54
55
  .thenReturn(config);
55
56
 
56
- await liftPackage({dependencies, devDependencies, projectRoot, packageManager, vcs, pathWithinParent, scripts});
57
+ await liftPackage(
58
+ {dependencies, devDependencies, projectRoot, packageManager, vcs, pathWithinParent, scripts},
59
+ {logger}
60
+ );
57
61
 
58
62
  expect(writePackageJson).toHaveBeenCalledWith({projectRoot, config});
59
63
  expect(processDependencies).toHaveBeenCalledWith({
@@ -61,7 +65,7 @@ describe('package.json lifter', () => {
61
65
  devDependencies,
62
66
  projectRoot,
63
67
  packageManager
64
- });
68
+ }, {logger});
65
69
  });
66
70
 
67
71
  it('should update keywords if tags are provided', async () => {
@@ -73,7 +77,7 @@ describe('package.json lifter', () => {
73
77
  .calledWith({...existingPackageContents, ...vcsDetails, scripts: liftedScripts, keywords: tags})
74
78
  .thenReturn(config);
75
79
 
76
- await liftPackage({dependencies, projectRoot, packageManager, vcs, pathWithinParent, scripts, tags});
80
+ await liftPackage({dependencies, projectRoot, packageManager, vcs, pathWithinParent, scripts, tags}, {logger});
77
81
 
78
82
  expect(writePackageJson).toHaveBeenCalledWith({projectRoot, config});
79
83
  });
@@ -93,7 +97,7 @@ describe('package.json lifter', () => {
93
97
  })
94
98
  .thenReturn(config);
95
99
 
96
- await liftPackage({dependencies, projectRoot, packageManager, vcs, pathWithinParent, scripts, tags});
100
+ await liftPackage({dependencies, projectRoot, packageManager, vcs, pathWithinParent, scripts, tags}, {logger});
97
101
 
98
102
  expect(writePackageJson).toHaveBeenCalledWith({projectRoot, config});
99
103
  });
@@ -1,4 +1,3 @@
1
- import {info} from '@travi/cli-messages';
2
1
  import {writePackageJson} from '@form8ion/javascript-core';
3
2
 
4
3
  import buildPackageName from './package-name.js';
@@ -12,8 +11,8 @@ export default async function scaffoldPackage({
12
11
  license,
13
12
  author,
14
13
  description
15
- }) {
16
- info('Configuring package.json');
14
+ }, {logger}) {
15
+ logger.info('Configuring package.json');
17
16
 
18
17
  const packageName = buildPackageName(projectName, scope);
19
18
 
@@ -13,6 +13,8 @@ vi.mock('./package-name.js');
13
13
  vi.mock('./details.js');
14
14
 
15
15
  describe('package scaffolder', () => {
16
+ const logger = {info: () => undefined};
17
+
16
18
  it('should create the package file', async () => {
17
19
  const projectName = any.string();
18
20
  const packageName = any.string();
@@ -40,7 +42,7 @@ describe('package scaffolder', () => {
40
42
  license,
41
43
  author,
42
44
  description
43
- })).toEqual({packageName});
45
+ }, {logger})).toEqual({packageName});
44
46
  expect(writePackageJson).toHaveBeenCalledWith({projectRoot, config: packageDetails});
45
47
  });
46
48
  });
@@ -1,10 +1,9 @@
1
1
  import {mergeIntoExistingPackageJson} from '@form8ion/javascript-core';
2
- import {info} from '@travi/cli-messages';
3
2
 
4
3
  const defaultBuildDirectory = 'public';
5
4
 
6
- export default async function scaffoldApplication({projectRoot}) {
7
- info('Scaffolding Application Details');
5
+ export default async function scaffoldApplication({projectRoot}, {logger}) {
6
+ logger.info('Scaffolding Application Details');
8
7
 
9
8
  await mergeIntoExistingPackageJson({projectRoot, config: {private: true}});
10
9
 
@@ -1,6 +1,6 @@
1
1
  import {mergeIntoExistingPackageJson} from '@form8ion/javascript-core';
2
2
 
3
- import {afterEach, describe, expect, it, vi} from 'vitest';
3
+ import {describe, expect, it, vi} from 'vitest';
4
4
  import any from '@travi/any';
5
5
 
6
6
  import scaffoldApplication from './scaffolder.js';
@@ -8,15 +8,13 @@ import scaffoldApplication from './scaffolder.js';
8
8
  vi.mock('@form8ion/javascript-core');
9
9
 
10
10
  describe('application project-type scaffolder', () => {
11
- afterEach(() => {
12
- vi.clearAllMocks();
13
- });
11
+ const logger = {info: () => undefined};
14
12
 
15
13
  it('should scaffold the details specific to an application project-type', async () => {
16
14
  const projectRoot = any.string();
17
15
  const buildDirectory = 'public';
18
16
 
19
- expect(await scaffoldApplication({projectRoot})).toEqual({
17
+ expect(await scaffoldApplication({projectRoot}, {logger})).toEqual({
20
18
  scripts: {
21
19
  clean: `rimraf ./${buildDirectory}`,
22
20
  start: `node ./${buildDirectory}/index.js`,
@@ -1,8 +1,7 @@
1
1
  import {mergeIntoExistingPackageJson} from '@form8ion/javascript-core';
2
- import {info} from '@travi/cli-messages';
3
2
 
4
- export default async function scaffoldMonorepo({projectRoot}) {
5
- info('Scaffolding Monorepo Details');
3
+ export default async function scaffoldMonorepo({projectRoot}, {logger}) {
4
+ logger.info('Scaffolding Monorepo Details');
6
5
 
7
6
  await mergeIntoExistingPackageJson({projectRoot, config: {private: true}});
8
7
 
@@ -1,6 +1,6 @@
1
1
  import {mergeIntoExistingPackageJson} from '@form8ion/javascript-core';
2
2
 
3
- import {describe, vi, it, expect, afterEach} from 'vitest';
3
+ import {describe, expect, it, vi} from 'vitest';
4
4
  import any from '@travi/any';
5
5
 
6
6
  import scaffoldMonorepo from './scaffolder.js';
@@ -9,13 +9,10 @@ vi.mock('@form8ion/javascript-core');
9
9
 
10
10
  describe('monorepo project-type scaffolder', () => {
11
11
  const projectRoot = any.string();
12
-
13
- afterEach(() => {
14
- vi.clearAllMocks();
15
- });
12
+ const logger = {info: () => undefined};
16
13
 
17
14
  it('should scaffold the monorepo specific project details', async () => {
18
- expect(await scaffoldMonorepo({projectRoot})).toEqual({
15
+ expect(await scaffoldMonorepo({projectRoot}, {logger})).toEqual({
19
16
  nextSteps: [{
20
17
  summary: 'Add packages to your new monorepo',
21
18
  description: 'Leverage [@form8ion/add-package-to-monorepo](https://npm.im/@form8ion/add-package-to-monorepo)'
@@ -1,5 +1,4 @@
1
1
  import deepmerge from 'deepmerge';
2
- import {info} from '@travi/cli-messages';
3
2
  import {dialects, mergeIntoExistingPackageJson} from '@form8ion/javascript-core';
4
3
 
5
4
  import determinePackageAccessLevelFromProjectVisibility from '../publishable/access-level.js';
@@ -19,8 +18,8 @@ export default async function scaffoldPackageProjectType({
19
18
  dialect,
20
19
  provideExample,
21
20
  publishRegistry
22
- }) {
23
- info('Scaffolding Package Details');
21
+ }, {logger}) {
22
+ logger.info('Scaffolding Package Details');
24
23
 
25
24
  const packageAccessLevel = determinePackageAccessLevelFromProjectVisibility({projectVisibility: visibility});
26
25
  const [detailsForBuild, publishableResults] = await Promise.all([
@@ -35,6 +35,7 @@ describe('package project-type scaffolder', () => {
35
35
  const documentation = any.simpleObject();
36
36
  const decisions = any.simpleObject();
37
37
  const buildDetailsResults = any.simpleObject();
38
+ const logger = {info: () => undefined};
38
39
 
39
40
  beforeEach(() => {
40
41
  when(documentationScaffolder.default)
@@ -68,7 +69,7 @@ describe('package project-type scaffolder', () => {
68
69
  decisions,
69
70
  dialect,
70
71
  provideExample
71
- })).toEqual({
72
+ }, {logger})).toEqual({
72
73
  ...publishableResults,
73
74
  ...buildDetailsResults,
74
75
  documentation,
@@ -113,7 +114,7 @@ describe('package project-type scaffolder', () => {
113
114
  packageBundlers,
114
115
  decisions,
115
116
  provideExample
116
- })).toEqual({
117
+ }, {logger})).toEqual({
117
118
  ...publishableResults,
118
119
  ...buildDetailsResults,
119
120
  documentation,
@@ -153,7 +154,7 @@ describe('package project-type scaffolder', () => {
153
154
  decisions,
154
155
  dialect,
155
156
  provideExample
156
- })).toEqual({
157
+ }, {logger})).toEqual({
157
158
  ...publishableResults,
158
159
  ...buildDetailsResults,
159
160
  documentation,
@@ -199,7 +200,7 @@ describe('package project-type scaffolder', () => {
199
200
  packageBundlers,
200
201
  dialect,
201
202
  provideExample
202
- })).toEqual({
203
+ }, {logger})).toEqual({
203
204
  ...publishableResults,
204
205
  ...buildDetailsResults,
205
206
  documentation,
@@ -239,7 +240,7 @@ describe('package project-type scaffolder', () => {
239
240
  dialect,
240
241
  provideExample,
241
242
  packageBundlers
242
- });
243
+ }, {logger});
243
244
 
244
245
  expect(mergeIntoExistingPackageJson).toHaveBeenCalledWith({
245
246
  projectRoot,
@@ -1,3 +1,3 @@
1
1
  export default function mapProjectVisibility({projectVisibility}) {
2
- return 'Public' === projectVisibility ? 'public' : 'restricted';
2
+ return 'OSS' === projectVisibility ? 'public' : 'restricted';
3
3
  }
@@ -1,13 +1,15 @@
1
1
  import {describe, expect, it} from 'vitest';
2
+ import any from '@travi/any';
2
3
 
3
4
  import determinePackageAccessLevelFromProjectVisibility from './access-level.js';
4
5
 
5
6
  describe('package access level', () => {
6
- it('should return `public` when project visibility is `Public`', () => {
7
- expect(determinePackageAccessLevelFromProjectVisibility({projectVisibility: 'Public'})).toEqual('public');
7
+ it('should return `public` when project visibility is `OSS`', () => {
8
+ expect(determinePackageAccessLevelFromProjectVisibility({projectVisibility: 'OSS'})).toEqual('public');
8
9
  });
9
10
 
10
- it('should return `restricted` when the project visibility is `Private`', () => {
11
- expect(determinePackageAccessLevelFromProjectVisibility({projectVisibility: 'Private'})).toEqual('restricted');
11
+ it('should return `restricted` when the project visibility is `ISS` or `CS`', () => {
12
+ expect(determinePackageAccessLevelFromProjectVisibility({projectVisibility: any.fromList(['ISS', 'CS'])}))
13
+ .toEqual('restricted');
12
14
  });
13
15
  });
@@ -18,7 +18,7 @@ export default async function scaffoldProjectType({
18
18
  dialect,
19
19
  provideExample,
20
20
  publishRegistry
21
- }) {
21
+ }, {logger}) {
22
22
  switch (projectType) {
23
23
  case projectTypes.PACKAGE:
24
24
  return scaffoldPackageType({
@@ -33,9 +33,9 @@ export default async function scaffoldProjectType({
33
33
  dialect,
34
34
  provideExample,
35
35
  publishRegistry
36
- });
36
+ }, {logger});
37
37
  case projectTypes.APPLICATION:
38
- return scaffoldApplicationType({projectRoot});
38
+ return scaffoldApplicationType({projectRoot}, {logger});
39
39
  case projectTypes.CLI:
40
40
  return scaffoldCliType({
41
41
  visibility,
@@ -46,7 +46,7 @@ export default async function scaffoldProjectType({
46
46
  packageBundlers
47
47
  });
48
48
  case projectTypes.MONOREPO:
49
- return scaffoldMonorepoType({projectRoot});
49
+ return scaffoldMonorepoType({projectRoot}, {logger});
50
50
  case 'Other':
51
51
  return {};
52
52
  default:
@@ -1,6 +1,6 @@
1
1
  import {projectTypes} from '@form8ion/javascript-core';
2
2
 
3
- import {afterEach, describe, expect, it, vi} from 'vitest';
3
+ import {describe, expect, it, vi} from 'vitest';
4
4
  import any from '@travi/any';
5
5
  import {when} from 'vitest-when';
6
6
 
@@ -27,10 +27,7 @@ describe('project-type scaffolder', () => {
27
27
  const dialect = any.word();
28
28
  const provideExample = any.boolean();
29
29
  const packageBundlers = any.simpleObject();
30
-
31
- afterEach(() => {
32
- vi.clearAllMocks();
33
- });
30
+ const logger = {info: () => undefined};
34
31
 
35
32
  it('should apply the package-type scaffolder when the project-type is `Package`', async () => {
36
33
  const scope = any.word();
@@ -46,7 +43,7 @@ describe('project-type scaffolder', () => {
46
43
  dialect,
47
44
  provideExample,
48
45
  publishRegistry
49
- }).thenResolve(results);
46
+ }, {logger}).thenResolve(results);
50
47
 
51
48
  expect(await projectTypeScaffolder({
52
49
  projectType: projectTypes.PACKAGE,
@@ -61,11 +58,11 @@ describe('project-type scaffolder', () => {
61
58
  dialect,
62
59
  provideExample,
63
60
  publishRegistry
64
- })).toEqual(results);
61
+ }, {logger})).toEqual(results);
65
62
  });
66
63
 
67
64
  it('should apply the application-type scaffolder when the project-type is `Application`', async () => {
68
- when(scaffoldApplicationType).calledWith({projectRoot}).thenResolve(results);
65
+ when(scaffoldApplicationType).calledWith({projectRoot}, {logger}).thenResolve(results);
69
66
 
70
67
  expect(await projectTypeScaffolder({
71
68
  projectType: projectTypes.APPLICATION,
@@ -75,7 +72,7 @@ describe('project-type scaffolder', () => {
75
72
  packageManager,
76
73
  decisions,
77
74
  visibility
78
- })).toEqual(results);
75
+ }, {logger})).toEqual(results);
79
76
  });
80
77
 
81
78
  it('should apply the cli-type scaffolder when the project-type is `CLI`', async () => {
@@ -91,24 +88,26 @@ describe('project-type scaffolder', () => {
91
88
  publishRegistry,
92
89
  decisions,
93
90
  packageBundlers
94
- })).toEqual(results);
91
+ }, {logger})).toEqual(results);
95
92
  });
96
93
 
97
94
  it('should apply the monorepo-type scaffolder when the project-type is `Monorepo`', async () => {
98
- when(scaffoldMonorepoType).calledWith({projectRoot}).thenResolve(results);
95
+ when(scaffoldMonorepoType).calledWith({projectRoot}, {logger}).thenResolve(results);
99
96
 
100
- expect(await projectTypeScaffolder({projectRoot, projectType: projectTypes.MONOREPO, packageManager, decisions}))
101
- .toEqual(results);
97
+ expect(await projectTypeScaffolder(
98
+ {projectRoot, projectType: projectTypes.MONOREPO, packageManager, decisions},
99
+ {logger}
100
+ )).toEqual(results);
102
101
  });
103
102
 
104
103
  it('should not throw an error when the project-type is `Other`', async () => {
105
- expect(await projectTypeScaffolder({projectType: 'Other'})).toEqual({});
104
+ expect(await projectTypeScaffolder({projectType: 'Other'}, {logger})).toEqual({});
106
105
  });
107
106
 
108
107
  it('should throw an error for an unknown project-type', async () => {
109
108
  const projectType = any.word();
110
109
 
111
- await expect(() => projectTypeScaffolder({projectType}))
112
- .rejects.toThrowError(`The project-type of ${projectType} is invalid`);
110
+ await expect(() => projectTypeScaffolder({projectType}, {logger}))
111
+ .rejects.toThrow(`The project-type of ${projectType} is invalid`);
113
112
  });
114
113
  });
@@ -16,7 +16,7 @@ export function projectIsApplication(answers) {
16
16
  }
17
17
 
18
18
  function packageShouldBeScoped(visibility, answers) {
19
- return 'Private' === visibility || answers[questionNames.SHOULD_BE_SCOPED];
19
+ return ['ISS', 'CS'].includes(visibility) || answers[questionNames.SHOULD_BE_SCOPED];
20
20
  }
21
21
 
22
22
  function willBePublishedToNpm(answers) {
@@ -33,8 +33,15 @@ describe('javascript prompt conditionals', () => {
33
33
  })).toBe(true);
34
34
  });
35
35
 
36
- it('should present a scope prompt when a package is private, because they must be scoped', () => {
37
- expect(scopePromptShouldBePresentedFactory('Private')({
36
+ it('should present a scope prompt when a package is inner source, because they must be scoped', () => {
37
+ expect(scopePromptShouldBePresentedFactory('ISS')({
38
+ [questionNames.SHOULD_BE_SCOPED]: false,
39
+ [questionNames.PROJECT_TYPE]: projectTypes.PACKAGE
40
+ })).toBe(true);
41
+ });
42
+
43
+ it('should present a scope prompt when a package is closed source, because they must be scoped', () => {
44
+ expect(scopePromptShouldBePresentedFactory('CS')({
38
45
  [questionNames.SHOULD_BE_SCOPED]: false,
39
46
  [questionNames.PROJECT_TYPE]: projectTypes.PACKAGE
40
47
  })).toBe(true);
@@ -47,15 +54,29 @@ describe('javascript prompt conditionals', () => {
47
54
  })).toBe(true);
48
55
  });
49
56
 
50
- it('should present a scope prompt when a CLI is private, because they must be scoped', () => {
51
- expect(scopePromptShouldBePresentedFactory('Private')({
57
+ it('should present a scope prompt when a CLI is closed source, because they must be scoped', () => {
58
+ expect(scopePromptShouldBePresentedFactory('CS')({
52
59
  [questionNames.SHOULD_BE_SCOPED]: false,
53
60
  [questionNames.PROJECT_TYPE]: projectTypes.CLI
54
61
  })).toBe(true);
55
62
  });
56
63
 
57
- it('should not present a scope prompt when an application is private', () => {
58
- expect(scopePromptShouldBePresentedFactory('Private')({
64
+ it('should present a scope prompt when a CLI is inner source, because they must be scoped', () => {
65
+ expect(scopePromptShouldBePresentedFactory('ISS')({
66
+ [questionNames.SHOULD_BE_SCOPED]: false,
67
+ [questionNames.PROJECT_TYPE]: projectTypes.CLI
68
+ })).toBe(true);
69
+ });
70
+
71
+ it('should not present a scope prompt when an application is closed source', () => {
72
+ expect(scopePromptShouldBePresentedFactory('CS')({
73
+ [questionNames.SHOULD_BE_SCOPED]: false,
74
+ [questionNames.PROJECT_TYPE]: projectTypes.APPLICATION
75
+ })).toBe(false);
76
+ });
77
+
78
+ it('should not present a scope prompt when an application is inner source', () => {
79
+ expect(scopePromptShouldBePresentedFactory('ISS')({
59
80
  [questionNames.SHOULD_BE_SCOPED]: false,
60
81
  [questionNames.PROJECT_TYPE]: projectTypes.APPLICATION
61
82
  })).toBe(false);
@@ -1,7 +1,6 @@
1
1
  import {packageManagers, projectTypes} from '@form8ion/javascript-core';
2
2
  import {prompt as promptWithInquirer} from '@form8ion/overridable-prompts';
3
3
  import {questionNames as commonQuestionNames, questions as commonQuestions} from '@travi/language-scaffolder-prompts';
4
- import {warn} from '@travi/cli-messages';
5
4
 
6
5
  import {execa} from 'execa';
7
6
  import npmConfFactory from '../../thirdparty-wrappers/npm-conf.js';
@@ -43,7 +42,8 @@ export async function prompt(
43
42
  vcs,
44
43
  decisions,
45
44
  configs,
46
- pathWithinParent
45
+ pathWithinParent,
46
+ {logger}
47
47
  ) {
48
48
  const npmConf = npmConfFactory();
49
49
 
@@ -52,7 +52,7 @@ export async function prompt(
52
52
  maybeLoggedInNpmUsername = (await execa('npm', ['whoami'])).stdout;
53
53
  } catch (failedExecutionResult) {
54
54
  if (!decisions[questionNames.SCOPE]) {
55
- warn('No logged in user found with `npm whoami`. Login with `npm login` '
55
+ logger.warn('No logged in user found with `npm whoami`. Login with `npm login` '
56
56
  + 'to use your npm account name as the package scope default.');
57
57
  }
58
58
  }
@@ -101,7 +101,7 @@ export async function prompt(
101
101
  choices: [...Object.values(projectTypes), 'Other'],
102
102
  default: projectTypes.PACKAGE
103
103
  },
104
- ...'Private' === visibility ? [] : [{
104
+ ...['ISS', 'CS'].includes(visibility) ? [] : [{
105
105
  name: questionNames.SHOULD_BE_SCOPED,
106
106
  message: 'Should this package be scoped?',
107
107
  type: 'confirm',
@@ -59,6 +59,7 @@ describe('prompts', () => {
59
59
  [questionNames.DIALECT]: dialect,
60
60
  [questionNames.PROVIDE_EXAMPLE]: provideExample
61
61
  };
62
+ const logger = {info: () => undefined, warn: () => undefined};
62
63
 
63
64
  beforeEach(() => {
64
65
  when(commonPrompts.questions)
@@ -166,7 +167,7 @@ describe('prompts', () => {
166
167
  ], decisions)
167
168
  .thenResolve({...answers, [questionNames.CONFIGURE_LINTING]: any.word()});
168
169
 
169
- expect(await prompt(ciServices, hosts, visibility, vcs, decisions, configs)).toEqual({
170
+ expect(await prompt(ciServices, hosts, visibility, vcs, decisions, configs, undefined, {logger})).toEqual({
170
171
  tests,
171
172
  projectType,
172
173
  ci,
@@ -188,7 +189,7 @@ describe('prompts', () => {
188
189
  when(execa).calledWith('npm', ['whoami']).thenResolve({stdout: npmUser});
189
190
  prompts.prompt.mockResolvedValue({...answers, [questionNames.CONFIGURE_LINTING]: false});
190
191
 
191
- expect(await prompt(ciServices, {}, visibility, vcs, decisions)).toEqual({
192
+ expect(await prompt(ciServices, {}, visibility, vcs, decisions, undefined, undefined, {logger})).toEqual({
192
193
  tests,
193
194
  projectType,
194
195
  ci,
@@ -211,13 +212,13 @@ describe('prompts', () => {
211
212
  .thenReturn(commonQuestions);
212
213
  prompts.prompt.mockResolvedValue(answers);
213
214
 
214
- await prompt(ciServices, {}, 'Private', vcs, null, null, pathWithinParent);
215
+ await prompt(ciServices, {}, 'CS', vcs, null, null, pathWithinParent, {logger});
215
216
 
216
217
  const [questions] = prompts.prompt.mock.lastCall;
217
218
  expect(questions.filter(question => questionNames.NODE_VERSION_CATEGORY === question.name).length).toEqual(0);
218
219
  });
219
220
 
220
- it('should not ask whether private packages should be scoped', async () => {
221
+ it('should not ask whether closed source packages should be scoped', async () => {
221
222
  when(execa).calledWith('npm', ['whoami']).thenResolve({stdout: any.word()});
222
223
  npmConfFactory.mockReturnValue({get: () => undefined});
223
224
  when(commonPrompts.questions)
@@ -225,7 +226,21 @@ describe('prompts', () => {
225
226
  .thenReturn(commonQuestions);
226
227
  prompts.prompt.mockResolvedValue(answers);
227
228
 
228
- await prompt(ciServices, {}, 'Private', vcs, null, null, pathWithinParent);
229
+ await prompt(ciServices, {}, 'CS', vcs, null, null, pathWithinParent, {logger});
230
+
231
+ const [questions] = prompts.prompt.mock.lastCall;
232
+ expect(questions.filter(question => questionNames.SHOULD_BE_SCOPED === question.name).length).toEqual(0);
233
+ });
234
+
235
+ it('should not ask whether inner source packages should be scoped', async () => {
236
+ when(execa).calledWith('npm', ['whoami']).thenResolve({stdout: any.word()});
237
+ npmConfFactory.mockReturnValue({get: () => undefined});
238
+ when(commonPrompts.questions)
239
+ .calledWith({vcs, ciServices, pathWithinParent})
240
+ .thenReturn(commonQuestions);
241
+ prompts.prompt.mockResolvedValue(answers);
242
+
243
+ await prompt(ciServices, {}, 'ISS', vcs, null, null, pathWithinParent, {logger});
229
244
 
230
245
  const [questions] = prompts.prompt.mock.lastCall;
231
246
  expect(questions.filter(question => questionNames.SHOULD_BE_SCOPED === question.name).length).toEqual(0);
@@ -239,7 +254,7 @@ describe('prompts', () => {
239
254
  .thenReturn(commonQuestions);
240
255
  prompts.prompt.mockResolvedValue(answers);
241
256
 
242
- await prompt(ciServices, {}, 'Public', vcs, {}, null, pathWithinParent);
257
+ await prompt(ciServices, {}, 'OSS', vcs, {}, null, pathWithinParent, {logger});
243
258
 
244
259
  const [questions] = prompts.prompt.mock.lastCall;
245
260
  expect(questions.filter(question => questionNames.SHOULD_BE_SCOPED === question.name).length).toEqual(1);
@@ -1,7 +1,12 @@
1
1
  export function scope(visibility) {
2
2
  return input => {
3
- if (!input && 'Private' === visibility) {
4
- return 'Private packages must be scoped (https://docs.npmjs.com/private-modules/intro#setting-up-your-package)';
3
+ if (!input) {
4
+ if ('CS' === visibility) {
5
+ return 'Closed source packages must be scoped';
6
+ }
7
+ if ('ISS' === visibility) {
8
+ return 'Inner source packages must be scoped';
9
+ }
5
10
  }
6
11
 
7
12
  return true;
@@ -1,19 +1,22 @@
1
1
  import {expect, it, describe} from 'vitest';
2
+ import any from '@travi/any';
2
3
 
3
4
  import {scope} from './validators.js';
4
5
 
5
6
  describe('question validators', () => {
6
- it('should require a scope for private project', () => {
7
- expect(scope('Private')()).toEqual(
8
- 'Private packages must be scoped (https://docs.npmjs.com/private-modules/intro#setting-up-your-package)'
9
- );
7
+ it('should require a scope for a closed-source project', () => {
8
+ expect(scope('CS')()).toEqual('Closed source packages must be scoped');
9
+ });
10
+
11
+ it('should require a scope for an inner-source project', () => {
12
+ expect(scope('ISS')()).toEqual('Inner source packages must be scoped');
10
13
  });
11
14
 
12
15
  it('it should consider a provided value to be a valid answer to private projects', () => {
13
- expect(scope('Public')()).toBe(true);
16
+ expect(scope('OSS')(any.word())).toBe(true);
14
17
  });
15
18
 
16
19
  it('it should consider an empty value to be a valid answer to public projects', () => {
17
- expect(scope('Public')()).toBe(true);
20
+ expect(scope('OSS')()).toBe(true);
18
21
  });
19
22
  });