@form8ion/javascript 16.0.0-beta.1 → 16.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/example.js +2 -2
- package/lib/index.js +18 -27
- package/lib/index.js.map +1 -1
- package/package.json +9 -9
- package/src/npm-config/index.js +0 -2
- package/src/npm-config/lifter.js +3 -4
- package/src/npm-config/lifter.test.js +5 -6
- package/src/npm-config/scaffolder.js +2 -4
- package/src/npm-config/scaffolder.test.js +6 -11
- package/src/options/schemas.test.js +1 -1
- package/src/options/validator.js +2 -1
- package/src/options/validator.test.js +2 -1
- package/src/project-type/publishable/access-level.test.js +1 -1
- package/src/prompts/conditionals.js +1 -1
- package/src/prompts/conditionals.test.js +27 -6
- package/src/prompts/questions.js +1 -1
- package/src/prompts/questions.test.js +18 -4
- package/src/prompts/validators.js +7 -2
- package/src/prompts/validators.test.js +9 -6
- package/src/registries/lifter.js +4 -3
- package/src/registries/lifter.test.js +5 -4
- package/src/npm-config/reader.js +0 -11
- package/src/npm-config/reader.test.js +0 -33
- package/src/npm-config/writer.js +0 -6
- package/src/npm-config/writer.test.js +0 -24
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@form8ion/javascript",
|
|
3
3
|
"description": "JavaScript language plugin for the @form8ion toolset",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "16.0.0-beta.
|
|
5
|
+
"version": "16.0.0-beta.3",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": "^22.21.0 || >=24.12"
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"access": "public",
|
|
60
60
|
"provenance": true
|
|
61
61
|
},
|
|
62
|
-
"packageManager": "npm@11.
|
|
62
|
+
"packageManager": "npm@11.16.0+sha512.03be172fc3b199c7a06433163e459be5b110a6983c1dd6305b7ac10f6b0fa12e1440755a8df6b1064ab2ccb789df0474919fb9c684e322dc57685ede21752ccb",
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@form8ion/c8": "^1.0.0-beta.2",
|
|
65
65
|
"@form8ion/codecov": "^7.0.0-beta.1",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@form8ion/core": "^5.0.0-beta.9",
|
|
69
69
|
"@form8ion/eslint": "^7.0.0-beta.1",
|
|
70
70
|
"@form8ion/husky": "^7.0.0-beta.1",
|
|
71
|
-
"@form8ion/javascript-core": "^
|
|
71
|
+
"@form8ion/javascript-core": "^13.0.0",
|
|
72
72
|
"@form8ion/overridable-prompts": "^1.2.0",
|
|
73
73
|
"@form8ion/prettier": "^3.0.0",
|
|
74
74
|
"@hapi/hoek": "^11.0.0",
|
|
@@ -86,23 +86,23 @@
|
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@cucumber/cucumber": "12.9.0",
|
|
89
|
-
"@form8ion/commitlint-config": "2.0.
|
|
89
|
+
"@form8ion/commitlint-config": "2.0.16",
|
|
90
90
|
"@form8ion/eslint-config": "7.1.0-beta.1",
|
|
91
91
|
"@form8ion/eslint-config-cucumber": "1.4.1",
|
|
92
92
|
"@form8ion/eslint-config-vitest": "1.1.0",
|
|
93
93
|
"@form8ion/remark-lint-preset": "6.0.7",
|
|
94
94
|
"@rollup/plugin-node-resolve": "16.0.3",
|
|
95
95
|
"@travi/any": "3.3.0",
|
|
96
|
-
"@vitest/coverage-v8": "4.1.
|
|
96
|
+
"@vitest/coverage-v8": "4.1.8",
|
|
97
97
|
"ban-sensitive-files": "1.10.11",
|
|
98
98
|
"chai": "6.2.2",
|
|
99
99
|
"cz-conventional-changelog": "3.3.0",
|
|
100
100
|
"debug": "4.4.3",
|
|
101
101
|
"gplint": "2.5.2",
|
|
102
102
|
"husky": "9.1.7",
|
|
103
|
-
"js-yaml": "4.
|
|
103
|
+
"js-yaml": "4.2.0",
|
|
104
104
|
"lockfile-lint": "5.0.0",
|
|
105
|
-
"ls-engines": "0.
|
|
105
|
+
"ls-engines": "0.10.0",
|
|
106
106
|
"mock-fs": "5.5.0",
|
|
107
107
|
"npm-run-all2": "9.0.1",
|
|
108
108
|
"publint": "0.3.21",
|
|
@@ -110,10 +110,10 @@
|
|
|
110
110
|
"remark-toc": "9.0.0",
|
|
111
111
|
"remark-usage": "11.0.1",
|
|
112
112
|
"rimraf": "6.1.3",
|
|
113
|
-
"rollup": "4.
|
|
113
|
+
"rollup": "4.61.1",
|
|
114
114
|
"rollup-plugin-auto-external": "2.0.0",
|
|
115
115
|
"testdouble": "3.20.2",
|
|
116
|
-
"vitest": "4.1.
|
|
116
|
+
"vitest": "4.1.8",
|
|
117
117
|
"vitest-when": "0.10.0"
|
|
118
118
|
}
|
|
119
119
|
}
|
package/src/npm-config/index.js
CHANGED
package/src/npm-config/lifter.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import write from './writer.js';
|
|
1
|
+
import {loadNpmrc, writeNpmrc} from '@form8ion/javascript-core';
|
|
3
2
|
|
|
4
3
|
export default async function liftNpmConfig({projectRoot}) {
|
|
5
4
|
const {
|
|
6
5
|
provenance,
|
|
7
6
|
'engines-strict': enginesStrict,
|
|
8
7
|
...remainingProperties
|
|
9
|
-
} = await
|
|
8
|
+
} = await loadNpmrc({projectRoot});
|
|
10
9
|
|
|
11
|
-
await
|
|
10
|
+
await writeNpmrc({projectRoot, config: remainingProperties});
|
|
12
11
|
|
|
13
12
|
return {};
|
|
14
13
|
}
|
|
@@ -1,23 +1,22 @@
|
|
|
1
|
+
import {loadNpmrc, writeNpmrc} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
1
3
|
import {describe, expect, it, vi} from 'vitest';
|
|
2
4
|
import any from '@travi/any';
|
|
3
5
|
import {when} from 'vitest-when';
|
|
4
6
|
|
|
5
|
-
import read from './reader.js';
|
|
6
|
-
import write from './writer.js';
|
|
7
7
|
import liftNpmConfig from './lifter.js';
|
|
8
8
|
|
|
9
|
-
vi.mock('
|
|
10
|
-
vi.mock('./writer.js');
|
|
9
|
+
vi.mock('@form8ion/javascript-core');
|
|
11
10
|
|
|
12
11
|
describe('npm config lifter', () => {
|
|
13
12
|
it('should remove `provenance` and `engines-strict` properties from the config', async () => {
|
|
14
13
|
const projectRoot = any.string();
|
|
15
14
|
const desiredProperties = any.simpleObject();
|
|
16
|
-
when(
|
|
15
|
+
when(loadNpmrc)
|
|
17
16
|
.calledWith({projectRoot})
|
|
18
17
|
.thenResolve({...desiredProperties, provenance: true, 'engines-strict': true});
|
|
19
18
|
|
|
20
19
|
expect(await liftNpmConfig({projectRoot})).toEqual({});
|
|
21
|
-
expect(
|
|
20
|
+
expect(writeNpmrc).toHaveBeenCalledWith({projectRoot, config: desiredProperties});
|
|
22
21
|
});
|
|
23
22
|
});
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {projectTypes} from '@form8ion/javascript-core';
|
|
2
|
-
|
|
3
|
-
import write from './writer.js';
|
|
1
|
+
import {projectTypes, writeNpmrc} from '@form8ion/javascript-core';
|
|
4
2
|
|
|
5
3
|
function projectWillNotBeConsumed(projectType) {
|
|
6
4
|
return projectTypes.APPLICATION === projectType || projectTypes.CLI === projectType;
|
|
7
5
|
}
|
|
8
6
|
|
|
9
7
|
export default async function scaffoldNpmConfiguration({projectRoot, projectType}) {
|
|
10
|
-
await
|
|
8
|
+
await writeNpmrc({
|
|
11
9
|
projectRoot,
|
|
12
10
|
config: {'update-notifier': false, ...projectWillNotBeConsumed(projectType) && {'save-exact': true}}
|
|
13
11
|
});
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import {projectTypes} from '@form8ion/javascript-core';
|
|
1
|
+
import {projectTypes, writeNpmrc} from '@form8ion/javascript-core';
|
|
2
2
|
|
|
3
|
-
import {describe,
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
4
4
|
import any from '@travi/any';
|
|
5
5
|
|
|
6
|
-
import write from './writer.js';
|
|
7
6
|
import scaffoldNpmConfig from './scaffolder.js';
|
|
8
7
|
|
|
9
8
|
vi.mock('node:fs');
|
|
10
|
-
vi.mock('
|
|
9
|
+
vi.mock('@form8ion/javascript-core');
|
|
11
10
|
|
|
12
11
|
describe('npm config scaffolder', () => {
|
|
13
12
|
const projectRoot = any.string();
|
|
14
13
|
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
vi.clearAllMocks();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
14
|
it('should save exact versions of dependencies for applications', async () => {
|
|
20
15
|
await scaffoldNpmConfig({projectRoot, projectType: projectTypes.APPLICATION});
|
|
21
16
|
|
|
22
|
-
expect(
|
|
17
|
+
expect(writeNpmrc).toHaveBeenCalledWith({
|
|
23
18
|
projectRoot,
|
|
24
19
|
config: {
|
|
25
20
|
'update-notifier': false,
|
|
@@ -31,7 +26,7 @@ describe('npm config scaffolder', () => {
|
|
|
31
26
|
it('should save exact versions of dependencies for cli applications', async () => {
|
|
32
27
|
await scaffoldNpmConfig({projectRoot, projectType: projectTypes.CLI});
|
|
33
28
|
|
|
34
|
-
expect(
|
|
29
|
+
expect(writeNpmrc).toHaveBeenCalledWith({
|
|
35
30
|
projectRoot,
|
|
36
31
|
config: {
|
|
37
32
|
'update-notifier': false,
|
|
@@ -43,7 +38,7 @@ describe('npm config scaffolder', () => {
|
|
|
43
38
|
it('should allow semver ranges for dependencies of packages', async () => {
|
|
44
39
|
await scaffoldNpmConfig({projectRoot, projectType: projectTypes.PACKAGE});
|
|
45
40
|
|
|
46
|
-
expect(
|
|
41
|
+
expect(writeNpmrc).toHaveBeenCalledWith({projectRoot, config: {'update-notifier': false}});
|
|
47
42
|
});
|
|
48
43
|
|
|
49
44
|
it('should define the script to enforce peer-dependency compatibility', async () => {
|
|
@@ -122,7 +122,7 @@ describe('options schemas', () => {
|
|
|
122
122
|
expect(validateOptions(visibilitySchema, visibility)).toEqual(visibility);
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
it('should consider values other than `
|
|
125
|
+
it('should consider values other than `OSS`, `ISS` and `CS` as invalid', () => {
|
|
126
126
|
expect(() => validateOptions(visibilitySchema, any.word()))
|
|
127
127
|
.toThrowError('"value" must be one of [OSS, ISS, CS]');
|
|
128
128
|
});
|
package/src/options/validator.js
CHANGED
|
@@ -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});
|
|
@@ -8,7 +8,7 @@ describe('package access level', () => {
|
|
|
8
8
|
expect(determinePackageAccessLevelFromProjectVisibility({projectVisibility: 'OSS'})).toEqual('public');
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
it('should return `restricted` when the project visibility is `
|
|
11
|
+
it('should return `restricted` when the project visibility is `ISS` or `CS`', () => {
|
|
12
12
|
expect(determinePackageAccessLevelFromProjectVisibility({projectVisibility: any.fromList(['ISS', 'CS'])}))
|
|
13
13
|
.toEqual('restricted');
|
|
14
14
|
});
|
|
@@ -16,7 +16,7 @@ export function projectIsApplication(answers) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function packageShouldBeScoped(visibility, answers) {
|
|
19
|
-
return '
|
|
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
|
|
37
|
-
expect(scopePromptShouldBePresentedFactory('
|
|
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
|
|
51
|
-
expect(scopePromptShouldBePresentedFactory('
|
|
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
|
|
58
|
-
expect(scopePromptShouldBePresentedFactory('
|
|
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);
|
package/src/prompts/questions.js
CHANGED
|
@@ -101,7 +101,7 @@ export async function prompt(
|
|
|
101
101
|
choices: [...Object.values(projectTypes), 'Other'],
|
|
102
102
|
default: projectTypes.PACKAGE
|
|
103
103
|
},
|
|
104
|
-
...'
|
|
104
|
+
...['ISS', 'CS'].includes(visibility) ? [] : [{
|
|
105
105
|
name: questionNames.SHOULD_BE_SCOPED,
|
|
106
106
|
message: 'Should this package be scoped?',
|
|
107
107
|
type: 'confirm',
|
|
@@ -212,13 +212,13 @@ describe('prompts', () => {
|
|
|
212
212
|
.thenReturn(commonQuestions);
|
|
213
213
|
prompts.prompt.mockResolvedValue(answers);
|
|
214
214
|
|
|
215
|
-
await prompt(ciServices, {}, '
|
|
215
|
+
await prompt(ciServices, {}, 'CS', vcs, null, null, pathWithinParent, {logger});
|
|
216
216
|
|
|
217
217
|
const [questions] = prompts.prompt.mock.lastCall;
|
|
218
218
|
expect(questions.filter(question => questionNames.NODE_VERSION_CATEGORY === question.name).length).toEqual(0);
|
|
219
219
|
});
|
|
220
220
|
|
|
221
|
-
it('should not ask whether
|
|
221
|
+
it('should not ask whether closed source packages should be scoped', async () => {
|
|
222
222
|
when(execa).calledWith('npm', ['whoami']).thenResolve({stdout: any.word()});
|
|
223
223
|
npmConfFactory.mockReturnValue({get: () => undefined});
|
|
224
224
|
when(commonPrompts.questions)
|
|
@@ -226,7 +226,21 @@ describe('prompts', () => {
|
|
|
226
226
|
.thenReturn(commonQuestions);
|
|
227
227
|
prompts.prompt.mockResolvedValue(answers);
|
|
228
228
|
|
|
229
|
-
await prompt(ciServices, {}, '
|
|
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});
|
|
230
244
|
|
|
231
245
|
const [questions] = prompts.prompt.mock.lastCall;
|
|
232
246
|
expect(questions.filter(question => questionNames.SHOULD_BE_SCOPED === question.name).length).toEqual(0);
|
|
@@ -240,7 +254,7 @@ describe('prompts', () => {
|
|
|
240
254
|
.thenReturn(commonQuestions);
|
|
241
255
|
prompts.prompt.mockResolvedValue(answers);
|
|
242
256
|
|
|
243
|
-
await prompt(ciServices, {}, '
|
|
257
|
+
await prompt(ciServices, {}, 'OSS', vcs, {}, null, pathWithinParent, {logger});
|
|
244
258
|
|
|
245
259
|
const [questions] = prompts.prompt.mock.lastCall;
|
|
246
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
|
|
4
|
-
|
|
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
|
|
7
|
-
expect(scope('
|
|
8
|
-
|
|
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('
|
|
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('
|
|
20
|
+
expect(scope('OSS')()).toBe(true);
|
|
18
21
|
});
|
|
19
22
|
});
|
package/src/registries/lifter.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
import {loadNpmrc, writeNpmrc} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
scaffold as scaffoldLockfileLint,
|
|
3
5
|
test as lockfileLintIsAlreadyConfigured,
|
|
4
6
|
read as readLockfileLintConfig,
|
|
5
7
|
write as writeLockfileLintConfig
|
|
6
8
|
} from '../lockfile-lint/index.js';
|
|
7
|
-
import {read as readNpmConfig, write as writeNpmConfig} from '../npm-config/index.js';
|
|
8
9
|
import buildRegistriesConfig from './npm-config/list-builder.js';
|
|
9
10
|
import buildAllowedHostsList from '../lockfile-lint/allowed-hosts-builder.js';
|
|
10
11
|
|
|
11
12
|
async function updateRegistriesInNpmConfig(registries, projectRoot) {
|
|
12
13
|
const registriesForNpmConfig = buildRegistriesConfig(registries);
|
|
13
14
|
|
|
14
|
-
await
|
|
15
|
+
await writeNpmrc({
|
|
15
16
|
projectRoot,
|
|
16
17
|
config: {
|
|
17
|
-
...(await
|
|
18
|
+
...(await loadNpmrc({projectRoot})),
|
|
18
19
|
...registriesForNpmConfig
|
|
19
20
|
}
|
|
20
21
|
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {loadNpmrc, writeNpmrc} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
1
3
|
import any from '@travi/any';
|
|
2
4
|
import {beforeEach, describe, expect, it, vi} from 'vitest';
|
|
3
5
|
import {when} from 'vitest-when';
|
|
@@ -9,14 +11,13 @@ import {
|
|
|
9
11
|
read as readLockfileLintConfig,
|
|
10
12
|
write as writeLockfileLintConfig
|
|
11
13
|
} from '../lockfile-lint/index.js';
|
|
12
|
-
import {read as readNpmConfig, write as writeNpmConfig} from '../npm-config/index.js';
|
|
13
14
|
import buildRegistriesConfig from './npm-config/list-builder.js';
|
|
14
15
|
import liftRegistries from './lifter.js';
|
|
15
16
|
|
|
17
|
+
vi.mock('@form8ion/javascript-core');
|
|
16
18
|
vi.mock('../lockfile-lint/allowed-hosts-builder.js');
|
|
17
19
|
vi.mock('../lockfile-lint/index.js');
|
|
18
20
|
vi.mock('../registries/npm-config/list-builder.js');
|
|
19
|
-
vi.mock('../npm-config/index.js');
|
|
20
21
|
|
|
21
22
|
describe('registries lifter', () => {
|
|
22
23
|
const projectRoot = any.string();
|
|
@@ -27,7 +28,7 @@ describe('registries lifter', () => {
|
|
|
27
28
|
const existingNpmConfig = any.simpleObject();
|
|
28
29
|
|
|
29
30
|
beforeEach(() => {
|
|
30
|
-
when(
|
|
31
|
+
when(loadNpmrc).calledWith({projectRoot}).thenResolve(existingNpmConfig);
|
|
31
32
|
when(buildRegistriesConfig).calledWith(registries).thenReturn(processedRegistryDetails);
|
|
32
33
|
});
|
|
33
34
|
|
|
@@ -40,7 +41,7 @@ describe('registries lifter', () => {
|
|
|
40
41
|
|
|
41
42
|
expect(await liftRegistries({projectRoot, packageManager, configs})).toEqual({});
|
|
42
43
|
|
|
43
|
-
expect(
|
|
44
|
+
expect(writeNpmrc).toHaveBeenCalledWith({
|
|
44
45
|
projectRoot,
|
|
45
46
|
config: {...existingNpmConfig, ...processedRegistryDetails}
|
|
46
47
|
});
|
package/src/npm-config/reader.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import {parse} from 'ini';
|
|
2
|
-
import {promises as fs} from 'node:fs';
|
|
3
|
-
import {fileExists} from '@form8ion/core';
|
|
4
|
-
|
|
5
|
-
export default async function readNpmConfig({projectRoot}) {
|
|
6
|
-
const pathToConfig = `${projectRoot}/.npmrc`;
|
|
7
|
-
|
|
8
|
-
if (!(await fileExists(pathToConfig))) return {};
|
|
9
|
-
|
|
10
|
-
return parse(await fs.readFile(pathToConfig, 'utf-8'));
|
|
11
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import {promises as fs} from 'node:fs';
|
|
2
|
-
import {stringify} from 'ini';
|
|
3
|
-
import {fileExists} from '@form8ion/core';
|
|
4
|
-
|
|
5
|
-
import {describe, expect, it, vi} from 'vitest';
|
|
6
|
-
import {when} from 'vitest-when';
|
|
7
|
-
import any from '@travi/any';
|
|
8
|
-
|
|
9
|
-
import readConfig from './reader.js';
|
|
10
|
-
|
|
11
|
-
vi.mock('node:fs');
|
|
12
|
-
vi.mock('@form8ion/core');
|
|
13
|
-
|
|
14
|
-
describe('npm config reader', () => {
|
|
15
|
-
const projectRoot = any.string();
|
|
16
|
-
const pathToConfig = `${projectRoot}/.npmrc`;
|
|
17
|
-
|
|
18
|
-
it('should read the .npmrc file', async () => {
|
|
19
|
-
const existingProperties = any.simpleObject();
|
|
20
|
-
when(fileExists).calledWith(pathToConfig).thenResolve(true);
|
|
21
|
-
when(fs.readFile)
|
|
22
|
-
.calledWith(pathToConfig, 'utf-8')
|
|
23
|
-
.thenReturn(stringify(existingProperties));
|
|
24
|
-
|
|
25
|
-
expect(await readConfig({projectRoot})).toEqual(existingProperties);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should return empty when the file does not exist', async () => {
|
|
29
|
-
when(fileExists).calledWith(pathToConfig).thenResolve(false);
|
|
30
|
-
|
|
31
|
-
expect(await readConfig({projectRoot})).toEqual({});
|
|
32
|
-
});
|
|
33
|
-
});
|
package/src/npm-config/writer.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import {promises as fs} from 'node:fs';
|
|
2
|
-
import {stringify} from 'ini';
|
|
3
|
-
|
|
4
|
-
import {describe, expect, vi, it} from 'vitest';
|
|
5
|
-
import any from '@travi/any';
|
|
6
|
-
import {when} from 'vitest-when';
|
|
7
|
-
|
|
8
|
-
import write from './writer.js';
|
|
9
|
-
|
|
10
|
-
vi.mock('node:fs');
|
|
11
|
-
vi.mock('ini');
|
|
12
|
-
|
|
13
|
-
describe('npm config writer', () => {
|
|
14
|
-
it('should write the .npmrc file', async () => {
|
|
15
|
-
const projectRoot = any.string();
|
|
16
|
-
const config = any.simpleObject();
|
|
17
|
-
const stringifiedIniConfig = any.string();
|
|
18
|
-
when(stringify).calledWith(config).thenReturn(stringifiedIniConfig);
|
|
19
|
-
|
|
20
|
-
await write({projectRoot, config});
|
|
21
|
-
|
|
22
|
-
expect(fs.writeFile).toHaveBeenCalledWith(`${projectRoot}/.npmrc`, stringifiedIniConfig);
|
|
23
|
-
});
|
|
24
|
-
});
|