@form8ion/javascript 15.5.0 → 15.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/package.json +4 -3
- package/src/code-style/index.js +3 -0
- package/src/code-style/lifter.js +6 -0
- package/src/code-style/lifter.test.js +25 -0
- package/src/code-style/remark/index.js +3 -0
- package/src/code-style/remark/lifter.js +10 -0
- package/src/code-style/remark/lifter.test.js +28 -0
- package/src/code-style/remark/scaffolder.js +38 -0
- package/src/code-style/remark/scaffolder.test.js +102 -0
- package/src/code-style/remark/tester.js +11 -0
- package/src/code-style/remark/tester.test.js +46 -0
- package/src/code-style/scaffolder.js +26 -0
- package/src/code-style/scaffolder.test.js +87 -0
- package/src/code-style/tester.js +5 -0
- package/src/code-style/tester.test.js +23 -0
- package/src/corepack/index.js +1 -0
- package/src/corepack/lifter.js +5 -0
- package/src/corepack/lifter.test.js +22 -0
- package/src/coverage/index.js +3 -0
- package/src/coverage/lifter.js +31 -0
- package/src/coverage/lifter.test.js +58 -0
- package/src/coverage/nyc/index.js +2 -0
- package/src/coverage/nyc/remover.js +16 -0
- package/src/coverage/nyc/remover.test.js +24 -0
- package/src/coverage/nyc/tester.js +5 -0
- package/src/coverage/nyc/tester.test.js +29 -0
- package/src/coverage/scaffolder.js +7 -0
- package/src/coverage/scaffolder.test.js +32 -0
- package/src/coverage/tester.js +10 -0
- package/src/coverage/tester.test.js +50 -0
- package/src/dependencies/index.js +3 -0
- package/src/dependencies/installer.js +25 -0
- package/src/dependencies/installer.test.js +77 -0
- package/src/dependencies/package-managers.js +32 -0
- package/src/dependencies/package-managers.test.js +46 -0
- package/src/dependencies/processor.js +30 -0
- package/src/dependencies/processor.test.js +75 -0
- package/src/dependencies/remover.js +10 -0
- package/src/dependencies/remover.test.js +28 -0
- package/src/dialects/babel/config/ignore-adder.js +10 -0
- package/src/dialects/babel/config/ignore-adder.test.js +33 -0
- package/src/dialects/babel/config/index.js +3 -0
- package/src/dialects/babel/config/loader.js +5 -0
- package/src/dialects/babel/config/loader.test.js +21 -0
- package/src/dialects/babel/config/writer.js +6 -0
- package/src/dialects/babel/config/writer.test.js +20 -0
- package/src/dialects/babel/index.js +3 -0
- package/src/dialects/babel/lifter.js +7 -0
- package/src/dialects/babel/lifter.test.js +17 -0
- package/src/dialects/babel/predicate.js +5 -0
- package/src/dialects/babel/predicate.test.js +25 -0
- package/src/dialects/babel/scaffolder.js +14 -0
- package/src/dialects/babel/scaffolder.test.js +28 -0
- package/src/dialects/index.js +2 -0
- package/src/dialects/prompt-choices.js +10 -0
- package/src/dialects/prompt-choices.test.js +28 -0
- package/src/dialects/scaffolder.js +15 -0
- package/src/dialects/scaffolder.test.js +49 -0
- package/src/dialects/typescript/index.js +1 -0
- package/src/dialects/typescript/scaffolder.js +31 -0
- package/src/dialects/typescript/scaffolder.test.js +95 -0
- package/src/documentation/generation-command.js +11 -0
- package/src/documentation/generation-command.test.js +25 -0
- package/src/documentation/index.js +1 -0
- package/src/documentation/scaffolder.js +20 -0
- package/src/documentation/scaffolder.test.js +49 -0
- package/src/engines/index.js +2 -0
- package/src/engines/lifter.js +7 -0
- package/src/engines/lifter.test.js +18 -0
- package/src/engines/tester.js +7 -0
- package/src/engines/tester.test.js +37 -0
- package/src/index.js +9 -0
- package/src/lifter.js +55 -0
- package/src/lifter.test.js +96 -0
- package/src/linting/index.js +1 -0
- package/src/linting/scaffolder.js +5 -0
- package/src/linting/scaffolder.test.js +31 -0
- package/src/lockfile-lint/allowed-hosts-builder.js +6 -0
- package/src/lockfile-lint/allowed-hosts-builder.test.js +35 -0
- package/src/lockfile-lint/config.js +12 -0
- package/src/lockfile-lint/config.test.js +37 -0
- package/src/lockfile-lint/index.js +3 -0
- package/src/lockfile-lint/scaffolder.js +38 -0
- package/src/lockfile-lint/scaffolder.test.js +85 -0
- package/src/lockfile-lint/tester.js +5 -0
- package/src/lockfile-lint/tester.test.js +25 -0
- package/src/node-version/index.js +2 -0
- package/src/node-version/scaffolder.js +19 -0
- package/src/node-version/scaffolder.test.js +33 -0
- package/src/node-version/tasks.js +25 -0
- package/src/node-version/tasks.test.js +43 -0
- package/src/node-version/tester.js +5 -0
- package/src/node-version/tester.test.js +29 -0
- package/src/npm-config/index.js +5 -0
- package/src/npm-config/lifter.js +14 -0
- package/src/npm-config/lifter.test.js +23 -0
- package/src/npm-config/reader.js +11 -0
- package/src/npm-config/reader.test.js +33 -0
- package/src/npm-config/scaffolder.js +16 -0
- package/src/npm-config/scaffolder.test.js +54 -0
- package/src/npm-config/tester.js +5 -0
- package/src/npm-config/tester.test.js +29 -0
- package/src/npm-config/writer.js +6 -0
- package/src/npm-config/writer.test.js +24 -0
- package/src/options/schemas.js +14 -0
- package/src/options/schemas.test.js +147 -0
- package/src/options/validator.js +45 -0
- package/src/options/validator.test.js +79 -0
- package/src/package/details.js +18 -0
- package/src/package/details.test.js +51 -0
- package/src/package/index.js +2 -0
- package/src/package/lifter.js +47 -0
- package/src/package/lifter.test.js +100 -0
- package/src/package/package-name.js +13 -0
- package/src/package/package-name.test.js +52 -0
- package/src/package/property-sorter.js +38 -0
- package/src/package/property-sorter.test.js +56 -0
- package/src/package/scaffolder.js +32 -0
- package/src/package/scaffolder.test.js +46 -0
- package/src/package/scripts/index.js +1 -0
- package/src/package/scripts/lifter.js +14 -0
- package/src/package/scripts/lifter.test.js +31 -0
- package/src/package/scripts/script-comparator.js +46 -0
- package/src/package/scripts/script-comparator.test.js +119 -0
- package/src/package/scripts/scripts-sorter.js +7 -0
- package/src/package/scripts/scripts-sorter.test.js +20 -0
- package/src/package/scripts/test-script-updater.js +15 -0
- package/src/package/scripts/test-script-updater.test.js +32 -0
- package/src/package/vcs-host-details.js +12 -0
- package/src/package/vcs-host-details.test.js +16 -0
- package/src/package-managers/current-manager-resolver.js +21 -0
- package/src/package-managers/current-manager-resolver.test.js +51 -0
- package/src/package-managers/index.js +5 -0
- package/src/package-managers/lifter.js +7 -0
- package/src/package-managers/lifter.test.js +18 -0
- package/src/package-managers/lockfile-path-resolver.js +10 -0
- package/src/package-managers/lockfile-path-resolver.test.js +15 -0
- package/src/package-managers/npm/index.js +2 -0
- package/src/package-managers/npm/scaffolder.js +19 -0
- package/src/package-managers/npm/scaffolder.test.js +33 -0
- package/src/package-managers/npm/tester.js +11 -0
- package/src/package-managers/npm/tester.test.js +33 -0
- package/src/package-managers/scaffolder.js +11 -0
- package/src/package-managers/scaffolder.test.js +27 -0
- package/src/package-managers/tester.js +11 -0
- package/src/package-managers/tester.test.js +33 -0
- package/src/package-managers/yarn/index.js +2 -0
- package/src/package-managers/yarn/scaffolder.js +19 -0
- package/src/package-managers/yarn/scaffolder.test.js +33 -0
- package/src/package-managers/yarn/tester.js +11 -0
- package/src/package-managers/yarn/tester.test.js +33 -0
- package/src/plugins-schemas.js +4 -0
- package/src/plugins-schemas.test.js +28 -0
- package/src/project-type/application/index.js +2 -0
- package/src/project-type/application/predicate.js +3 -0
- package/src/project-type/application/predicate.test.js +14 -0
- package/src/project-type/application/scaffolder.js +24 -0
- package/src/project-type/application/scaffolder.test.js +35 -0
- package/src/project-type/cli/index.js +3 -0
- package/src/project-type/cli/lifter.js +5 -0
- package/src/project-type/cli/lifter.test.js +20 -0
- package/src/project-type/cli/scaffolder.js +52 -0
- package/src/project-type/cli/scaffolder.test.js +103 -0
- package/src/project-type/cli/tester.js +3 -0
- package/src/project-type/cli/tester.test.js +14 -0
- package/src/project-type/index.js +3 -0
- package/src/project-type/lifter.js +23 -0
- package/src/project-type/lifter.test.js +69 -0
- package/src/project-type/monorepo/index.js +1 -0
- package/src/project-type/monorepo/scaffolder.js +16 -0
- package/src/project-type/monorepo/scaffolder.test.js +27 -0
- package/src/project-type/package/build-details.js +56 -0
- package/src/project-type/package/build-details.test.js +111 -0
- package/src/project-type/package/documentation.js +34 -0
- package/src/project-type/package/documentation.test.js +106 -0
- package/src/project-type/package/index.js +3 -0
- package/src/project-type/package/lifter.js +5 -0
- package/src/project-type/package/lifter.test.js +20 -0
- package/src/project-type/package/scaffolder.js +84 -0
- package/src/project-type/package/scaffolder.test.js +267 -0
- package/src/project-type/package/tester.js +5 -0
- package/src/project-type/package/tester.test.js +28 -0
- package/src/project-type/publishable/access-level.js +3 -0
- package/src/project-type/publishable/access-level.test.js +13 -0
- package/src/project-type/publishable/badges.js +20 -0
- package/src/project-type/publishable/badges.test.js +29 -0
- package/src/project-type/publishable/bundler/index.js +1 -0
- package/src/project-type/publishable/bundler/prompt.js +16 -0
- package/src/project-type/publishable/bundler/prompt.test.js +35 -0
- package/src/project-type/publishable/bundler/scaffolder.js +8 -0
- package/src/project-type/publishable/bundler/scaffolder.test.js +33 -0
- package/src/project-type/publishable/index.js +2 -0
- package/src/project-type/publishable/lifter.js +24 -0
- package/src/project-type/publishable/lifter.test.js +49 -0
- package/src/project-type/publishable/provenance/index.js +1 -0
- package/src/project-type/publishable/provenance/lifter.js +15 -0
- package/src/project-type/publishable/provenance/lifter.test.js +56 -0
- package/src/project-type/publishable/provenance/slsa.js +17 -0
- package/src/project-type/publishable/provenance/slsa.test.js +21 -0
- package/src/project-type/publishable/registry-resolver.js +15 -0
- package/src/project-type/publishable/registry-resolver.test.js +60 -0
- package/src/project-type/publishable/scaffolder.js +7 -0
- package/src/project-type/publishable/scaffolder.test.js +23 -0
- package/src/project-type/scaffolder.js +56 -0
- package/src/project-type/scaffolder.test.js +115 -0
- package/src/project-type/tester.js +9 -0
- package/src/project-type/tester.test.js +51 -0
- package/src/project-type-plugin/index.js +1 -0
- package/src/project-type-plugin/prompt.js +16 -0
- package/src/project-type-plugin/prompt.test.js +39 -0
- package/src/project-type-plugin/scaffolder.js +28 -0
- package/src/project-type-plugin/scaffolder.test.js +70 -0
- package/src/prompts/conditionals.js +39 -0
- package/src/prompts/conditionals.test.js +95 -0
- package/src/prompts/question-names.js +17 -0
- package/src/prompts/questions.js +158 -0
- package/src/prompts/questions.test.js +247 -0
- package/src/prompts/validators.js +9 -0
- package/src/prompts/validators.test.js +19 -0
- package/src/registries/index.js +2 -0
- package/src/registries/lifter.js +43 -0
- package/src/registries/lifter.test.js +63 -0
- package/src/registries/npm-config/list-builder.js +9 -0
- package/src/registries/npm-config/list-builder.test.js +43 -0
- package/src/registries/tester.js +3 -0
- package/src/registries/tester.test.js +9 -0
- package/src/runkit/badge/index.js +1 -0
- package/src/runkit/badge/scaffolder.js +13 -0
- package/src/runkit/badge/scaffolder.test.js +22 -0
- package/src/runkit/index.js +4 -0
- package/src/runkit/lifter.js +5 -0
- package/src/runkit/lifter.test.js +17 -0
- package/src/runkit/remover.js +3 -0
- package/src/runkit/remover.test.js +9 -0
- package/src/runkit/scaffolder.js +11 -0
- package/src/runkit/scaffolder.test.js +35 -0
- package/src/runkit/tester.js +3 -0
- package/src/runkit/tester.test.js +16 -0
- package/src/scaffolder.js +155 -0
- package/src/scaffolder.test.js +239 -0
- package/src/tester.js +17 -0
- package/src/tester.test.js +37 -0
- package/src/testing/index.js +1 -0
- package/src/testing/scaffolder.js +31 -0
- package/src/testing/scaffolder.test.js +63 -0
- package/src/testing/unit/index.js +1 -0
- package/src/testing/unit/prompt.js +15 -0
- package/src/testing/unit/prompt.test.js +33 -0
- package/src/testing/unit/scaffolder.js +30 -0
- package/src/testing/unit/scaffolder.test.js +54 -0
- package/src/vcs/ignore-lists-builder.js +6 -0
- package/src/vcs/ignore-lists-builder.test.js +25 -0
- package/src/vcs/schema.js +7 -0
- package/src/vcs/schema.test.js +40 -0
- package/src/verification/index.js +1 -0
- package/src/verification/scaffolder.js +35 -0
- package/src/verification/scaffolder.test.js +56 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {info} from '@travi/cli-messages';
|
|
2
|
+
import {writePackageJson} from '@form8ion/javascript-core';
|
|
3
|
+
|
|
4
|
+
import buildPackageName from './package-name.js';
|
|
5
|
+
import buildPackageDetails from './details.js';
|
|
6
|
+
|
|
7
|
+
export default async function scaffoldPackage({
|
|
8
|
+
projectRoot,
|
|
9
|
+
projectName,
|
|
10
|
+
scope,
|
|
11
|
+
dialect,
|
|
12
|
+
license,
|
|
13
|
+
author,
|
|
14
|
+
description
|
|
15
|
+
}) {
|
|
16
|
+
info('Configuring package.json');
|
|
17
|
+
|
|
18
|
+
const packageName = buildPackageName(projectName, scope);
|
|
19
|
+
|
|
20
|
+
await writePackageJson({
|
|
21
|
+
projectRoot,
|
|
22
|
+
config: await buildPackageDetails({
|
|
23
|
+
packageName,
|
|
24
|
+
dialect,
|
|
25
|
+
license,
|
|
26
|
+
author,
|
|
27
|
+
description
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return {packageName};
|
|
32
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {writePackageJson} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
4
|
+
import any from '@travi/any';
|
|
5
|
+
import {when} from 'vitest-when';
|
|
6
|
+
|
|
7
|
+
import * as buildPackageDetails from './details.js';
|
|
8
|
+
import buildPackageName from './package-name.js';
|
|
9
|
+
import {scaffold} from './index.js';
|
|
10
|
+
|
|
11
|
+
vi.mock('@form8ion/javascript-core');
|
|
12
|
+
vi.mock('./package-name.js');
|
|
13
|
+
vi.mock('./details.js');
|
|
14
|
+
|
|
15
|
+
describe('package scaffolder', () => {
|
|
16
|
+
it('should create the package file', async () => {
|
|
17
|
+
const projectName = any.string();
|
|
18
|
+
const packageName = any.string();
|
|
19
|
+
const scope = any.word();
|
|
20
|
+
const packageDetails = any.simpleObject();
|
|
21
|
+
const projectRoot = any.string();
|
|
22
|
+
const dialect = any.word();
|
|
23
|
+
const license = any.string();
|
|
24
|
+
const author = any.simpleObject();
|
|
25
|
+
const description = any.sentence();
|
|
26
|
+
when(buildPackageName).calledWith(projectName, scope).thenReturn(packageName);
|
|
27
|
+
when(buildPackageDetails.default).calledWith({
|
|
28
|
+
packageName,
|
|
29
|
+
dialect,
|
|
30
|
+
license,
|
|
31
|
+
author,
|
|
32
|
+
description
|
|
33
|
+
}).thenResolve(packageDetails);
|
|
34
|
+
|
|
35
|
+
expect(await scaffold({
|
|
36
|
+
projectRoot,
|
|
37
|
+
projectName,
|
|
38
|
+
scope,
|
|
39
|
+
dialect,
|
|
40
|
+
license,
|
|
41
|
+
author,
|
|
42
|
+
description
|
|
43
|
+
})).toEqual({packageName});
|
|
44
|
+
expect(writePackageJson).toHaveBeenCalledWith({projectRoot, config: packageDetails});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default as lift} from './lifter.js';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import updateTestScript from './test-script-updater.js';
|
|
2
|
+
import sortScripts from './scripts-sorter.js';
|
|
3
|
+
|
|
4
|
+
export default function liftScripts({existingScripts, scripts}) {
|
|
5
|
+
return {
|
|
6
|
+
scripts: sortScripts(updateTestScript({...existingScripts, ...scripts})),
|
|
7
|
+
dependencies: {
|
|
8
|
+
javascript: {
|
|
9
|
+
development: ['npm-run-all2'],
|
|
10
|
+
remove: ['npm-run-all']
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import any from '@travi/any';
|
|
2
|
+
import {when} from 'vitest-when';
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
4
|
+
|
|
5
|
+
import updateTestScript from './test-script-updater.js';
|
|
6
|
+
import sortScripts from './scripts-sorter.js';
|
|
7
|
+
import liftScripts from './lifter.js';
|
|
8
|
+
|
|
9
|
+
vi.mock('./scripts-sorter.js');
|
|
10
|
+
vi.mock('./test-script-updater.js');
|
|
11
|
+
|
|
12
|
+
describe('package.json scripts lifter', () => {
|
|
13
|
+
it('should merge the provided scripts with the existing scripts', () => {
|
|
14
|
+
const existingScripts = any.simpleObject();
|
|
15
|
+
const scripts = any.simpleObject();
|
|
16
|
+
const updatedScripts = any.simpleObject();
|
|
17
|
+
const sortedScripts = any.simpleObject();
|
|
18
|
+
when(updateTestScript).calledWith({...existingScripts, ...scripts}).thenReturn(updatedScripts);
|
|
19
|
+
when(sortScripts).calledWith(updatedScripts).thenReturn(sortedScripts);
|
|
20
|
+
|
|
21
|
+
expect(liftScripts({existingScripts, scripts})).toEqual({
|
|
22
|
+
scripts: sortedScripts,
|
|
23
|
+
dependencies: {
|
|
24
|
+
javascript: {
|
|
25
|
+
development: ['npm-run-all2'],
|
|
26
|
+
remove: ['npm-run-all']
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
function isRelatedScript(a, b, prefix) {
|
|
2
|
+
return a.startsWith(prefix) && a.slice(prefix.length) === b;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function isPreScriptFor(a, b) {
|
|
6
|
+
return isRelatedScript(a, b, 'pre');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function isPostScriptFor(a, b) {
|
|
10
|
+
return isRelatedScript(a, b, 'post');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function stripPrefix(script) {
|
|
14
|
+
if (script.startsWith('pre')) return script.slice(3);
|
|
15
|
+
if (script.startsWith('post')) return script.slice(4);
|
|
16
|
+
return script;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getCategoryOrder(script) {
|
|
20
|
+
const base = stripPrefix(script);
|
|
21
|
+
if ('test' === base) return 0;
|
|
22
|
+
if (base.startsWith('lint:')) return 1;
|
|
23
|
+
if (base.startsWith('test:unit')) return 2;
|
|
24
|
+
if (base.startsWith('test:integration')) return 3;
|
|
25
|
+
if (base.startsWith('test:')) return 2;
|
|
26
|
+
|
|
27
|
+
return 4;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default function compareScriptNames(a, b) {
|
|
31
|
+
if (isPreScriptFor(a, b)) return -1;
|
|
32
|
+
if (isPreScriptFor(b, a)) return 1;
|
|
33
|
+
if (isPostScriptFor(a, b)) return 1;
|
|
34
|
+
if (isPostScriptFor(b, a)) return -1;
|
|
35
|
+
|
|
36
|
+
const categoryDiff = getCategoryOrder(a) - getCategoryOrder(b);
|
|
37
|
+
if (0 !== categoryDiff) return 0 > categoryDiff ? -1 : 1;
|
|
38
|
+
|
|
39
|
+
const aStripped = stripPrefix(a);
|
|
40
|
+
const bStripped = stripPrefix(b);
|
|
41
|
+
|
|
42
|
+
const aKey = aStripped !== a ? aStripped : a;
|
|
43
|
+
const bKey = bStripped !== b ? bStripped : b;
|
|
44
|
+
|
|
45
|
+
return aKey.localeCompare(bKey);
|
|
46
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {describe, it, expect} from 'vitest';
|
|
2
|
+
import any from '@travi/any';
|
|
3
|
+
|
|
4
|
+
import compareScriptNames from './script-comparator.js';
|
|
5
|
+
|
|
6
|
+
describe('script name comparator', () => {
|
|
7
|
+
const A_AFTER_B = 1;
|
|
8
|
+
const A_BEFORE_B = -1;
|
|
9
|
+
const baseScriptName = any.word();
|
|
10
|
+
|
|
11
|
+
it('should sort alphabetically if no other rules apply', async () => {
|
|
12
|
+
const a = `a${any.word()}`;
|
|
13
|
+
const b = `b${any.word()}`;
|
|
14
|
+
|
|
15
|
+
expect(compareScriptNames(a, b)).toEqual(A_BEFORE_B);
|
|
16
|
+
expect(compareScriptNames(b, a)).toEqual(A_AFTER_B);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should sort `pre` scripts ahead of their related scripts', async () => {
|
|
20
|
+
expect(compareScriptNames(`pre${baseScriptName}`, baseScriptName)).toEqual(A_BEFORE_B);
|
|
21
|
+
expect(compareScriptNames(baseScriptName, `pre${baseScriptName}`)).toEqual(A_AFTER_B);
|
|
22
|
+
|
|
23
|
+
expect(compareScriptNames('pretest', 'test')).toEqual(A_BEFORE_B);
|
|
24
|
+
expect(compareScriptNames('test', 'pretest')).toEqual(A_AFTER_B);
|
|
25
|
+
|
|
26
|
+
expect(compareScriptNames('prelint:publish', 'lint:publish')).toEqual(A_BEFORE_B);
|
|
27
|
+
expect(compareScriptNames('lint:publish', 'prelint:publish')).toEqual(A_AFTER_B);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should sort a `pre` script directly before its base script relative to unrelated scripts', async () => {
|
|
31
|
+
const baseName = `b${any.word()}`;
|
|
32
|
+
const scriptBetween = `c${any.word()}`;
|
|
33
|
+
|
|
34
|
+
expect(compareScriptNames(`pre${baseName}`, scriptBetween)).toEqual(A_BEFORE_B);
|
|
35
|
+
expect(compareScriptNames(scriptBetween, `pre${baseName}`)).toEqual(A_AFTER_B);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should sort `post` scripts after of their related scripts', async () => {
|
|
39
|
+
expect(compareScriptNames(`post${baseScriptName}`, baseScriptName)).toEqual(A_AFTER_B);
|
|
40
|
+
expect(compareScriptNames(baseScriptName, `post${baseScriptName}`)).toEqual(A_BEFORE_B);
|
|
41
|
+
|
|
42
|
+
expect(compareScriptNames('posttest', 'test')).toEqual(A_AFTER_B);
|
|
43
|
+
expect(compareScriptNames('test', 'posttest')).toEqual(A_BEFORE_B);
|
|
44
|
+
|
|
45
|
+
expect(compareScriptNames(`postlint:${any.word()}`, `test:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
46
|
+
expect(compareScriptNames(`test:${any.word()}`, `postlint:${any.word()}`)).toEqual(A_AFTER_B);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should sort the `test` script ahead of any sub-test scripts', async () => {
|
|
50
|
+
expect(compareScriptNames('test', `test:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
51
|
+
expect(compareScriptNames(`test:${any.word()}`, 'test')).toEqual(A_AFTER_B);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should sort `lint:` scripts above `test:` scripts', async () => {
|
|
55
|
+
expect(compareScriptNames(`lint:${any.word()}`, `test:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
56
|
+
expect(compareScriptNames(`test:${any.word()}`, `lint:${any.word()}`)).toEqual(A_AFTER_B);
|
|
57
|
+
|
|
58
|
+
expect(compareScriptNames(`prelint:${any.word()}`, `test:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
59
|
+
expect(compareScriptNames(`test:${any.word()}`, `prelint:${any.word()}`)).toEqual(A_AFTER_B);
|
|
60
|
+
|
|
61
|
+
expect(compareScriptNames(`lint:${any.word()}`, `pretest:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
62
|
+
expect(compareScriptNames(`pretest:${any.word()}`, `lint:${any.word()}`)).toEqual(A_AFTER_B);
|
|
63
|
+
|
|
64
|
+
expect(compareScriptNames(`prelint:${any.word()}`, `pretest:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
65
|
+
expect(compareScriptNames(`pretest:${any.word()}`, `prelint:${any.word()}`)).toEqual(A_AFTER_B);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should sort `pretest` ahead of `lint:` scripts', async () => {
|
|
69
|
+
expect(compareScriptNames('pretest', `lint:${any.word()}`)).toEqual(A_BEFORE_B);
|
|
70
|
+
expect(compareScriptNames(`lint:${any.word()}`, 'pretest')).toEqual(A_AFTER_B);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should sort subscripts alphabetically', async () => {
|
|
74
|
+
const a = `a${any.word()}`;
|
|
75
|
+
const b = `b${any.word()}`;
|
|
76
|
+
|
|
77
|
+
expect(compareScriptNames(`lint:${a}`, `lint:${b}`)).toEqual(A_BEFORE_B);
|
|
78
|
+
expect(compareScriptNames(`lint:${b}`, `lint:${a}`)).toEqual(A_AFTER_B);
|
|
79
|
+
|
|
80
|
+
expect(compareScriptNames(`test:${a}`, `test:${b}`)).toEqual(A_BEFORE_B);
|
|
81
|
+
expect(compareScriptNames(`test:${b}`, `test:${a}`)).toEqual(A_AFTER_B);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should sort undefined scripts below `lint:` scripts', async () => {
|
|
85
|
+
expect(compareScriptNames(any.word(), `lint:${any.word()}`)).toEqual(A_AFTER_B);
|
|
86
|
+
expect(compareScriptNames(`lint:${any.word()}`, any.word())).toEqual(A_BEFORE_B);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should sort `test:unit` ahead of `test:integration`', async () => {
|
|
90
|
+
expect(compareScriptNames('test:unit', 'test:integration')).toEqual(A_BEFORE_B);
|
|
91
|
+
expect(compareScriptNames('test:integration', 'test:unit')).toEqual(A_AFTER_B);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should sort `test:unit` sub-scripts after `test:unit`', async () => {
|
|
95
|
+
expect(compareScriptNames('test:unit', 'test:unit:base')).toEqual(A_BEFORE_B);
|
|
96
|
+
expect(compareScriptNames('test:unit:base', 'test:unit')).toEqual(A_AFTER_B);
|
|
97
|
+
|
|
98
|
+
expect(compareScriptNames('test:unit', 'pretest:unit:base')).toEqual(A_BEFORE_B);
|
|
99
|
+
expect(compareScriptNames('pretest:unit:base', 'test:unit')).toEqual(A_AFTER_B);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should sort `test:integration` sub-scripts after `test:integration`', async () => {
|
|
103
|
+
expect(compareScriptNames('test:integration', 'test:integration:base')).toEqual(A_BEFORE_B);
|
|
104
|
+
expect(compareScriptNames('test:integration:base', 'test:integration')).toEqual(A_AFTER_B);
|
|
105
|
+
|
|
106
|
+
expect(compareScriptNames('test:integration', 'pretest:integration:base')).toEqual(A_BEFORE_B);
|
|
107
|
+
expect(compareScriptNames('pretest:integration:base', 'test:integration')).toEqual(A_AFTER_B);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should sort `test:unit` sub-scripts ahead of `test:integration`', async () => {
|
|
111
|
+
expect(compareScriptNames('test:unit:base', 'test:integration')).toEqual(A_BEFORE_B);
|
|
112
|
+
expect(compareScriptNames('test:integration', 'test:unit:base')).toEqual(A_AFTER_B);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should sort uncategorized scripts below `test:` scripts', async () => {
|
|
116
|
+
expect(compareScriptNames(any.word(), `test:${any.word()}`)).toEqual(A_AFTER_B);
|
|
117
|
+
expect(compareScriptNames(`test:${any.word()}`, any.word())).toEqual(A_BEFORE_B);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import sortObjectKeys from 'sort-object-keys';
|
|
2
|
+
|
|
3
|
+
import {it, describe, expect, vi} from 'vitest';
|
|
4
|
+
import {when} from 'vitest-when';
|
|
5
|
+
import any from '@travi/any';
|
|
6
|
+
|
|
7
|
+
import compareScriptNames from './script-comparator.js';
|
|
8
|
+
import sortScripts from './scripts-sorter.js';
|
|
9
|
+
|
|
10
|
+
vi.mock('sort-object-keys');
|
|
11
|
+
|
|
12
|
+
describe('npm scripts sorter', () => {
|
|
13
|
+
it('should sort the scripts based on the defined order', async () => {
|
|
14
|
+
const unsortedScripts = any.simpleObject();
|
|
15
|
+
const sortedScripts = any.simpleObject();
|
|
16
|
+
when(sortObjectKeys).calledWith(unsortedScripts, compareScriptNames).thenReturn(sortedScripts);
|
|
17
|
+
|
|
18
|
+
expect(sortScripts(unsortedScripts)).toEqual(sortedScripts);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function projectWillBeTested(scripts) {
|
|
2
|
+
return Object.keys(scripts).find(scriptName => scriptName.startsWith('test:'));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function projectShouldBeBuiltForVerification(scripts) {
|
|
6
|
+
return 'run-s build' === scripts['pregenerate:md'];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function updateTestScript(scripts) {
|
|
10
|
+
return {
|
|
11
|
+
...scripts,
|
|
12
|
+
...projectShouldBeBuiltForVerification(scripts) && {pretest: 'run-s build'},
|
|
13
|
+
test: `npm-run-all --print-label --parallel lint:*${projectWillBeTested(scripts) ? ' --parallel test:*' : ''}`
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import any from '@travi/any';
|
|
2
|
+
import {describe, expect, it} from 'vitest';
|
|
3
|
+
|
|
4
|
+
import updateTestScript from './test-script-updater.js';
|
|
5
|
+
|
|
6
|
+
describe('test script updater', () => {
|
|
7
|
+
const scripts = {...any.simpleObject(), test: any.string(), [`lint:${any.word()}`]: any.string()};
|
|
8
|
+
|
|
9
|
+
it('should define the `test` script', () => {
|
|
10
|
+
expect(updateTestScript(scripts)).toEqual({...scripts, test: 'npm-run-all --print-label --parallel lint:*'});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should include a build step in the `test` script if a generate script for markdown is included', () => {
|
|
14
|
+
expect(updateTestScript({...scripts, 'pregenerate:md': 'run-s build'})).toEqual({
|
|
15
|
+
...scripts,
|
|
16
|
+
'pregenerate:md': 'run-s build',
|
|
17
|
+
pretest: 'run-s build',
|
|
18
|
+
test: 'npm-run-all --print-label --parallel lint:*'
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should include running tests in the `test` script when the project will be tested', () => {
|
|
23
|
+
const testScriptName = `test:${any.word()}`;
|
|
24
|
+
const testScriptValue = any.string();
|
|
25
|
+
|
|
26
|
+
expect(updateTestScript({...scripts, [testScriptName]: testScriptValue})).toEqual({
|
|
27
|
+
...scripts,
|
|
28
|
+
[testScriptName]: testScriptValue,
|
|
29
|
+
test: 'npm-run-all --print-label --parallel lint:* --parallel test:*'
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default function scaffoldVcsHostDetails(vcs, pathWithinParent) {
|
|
2
|
+
return vcs && 'github' === vcs.host && {
|
|
3
|
+
repository: pathWithinParent
|
|
4
|
+
? {
|
|
5
|
+
type: 'git',
|
|
6
|
+
url: `https://github.com/${vcs.owner}/${vcs.name}.git`,
|
|
7
|
+
directory: pathWithinParent
|
|
8
|
+
}
|
|
9
|
+
: `${vcs.owner}/${vcs.name}`,
|
|
10
|
+
bugs: `https://github.com/${vcs.owner}/${vcs.name}/issues`
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {describe, it, expect} from 'vitest';
|
|
2
|
+
import any from '@travi/any';
|
|
3
|
+
|
|
4
|
+
import defineVcsHostDetails from './vcs-host-details.js';
|
|
5
|
+
|
|
6
|
+
describe('vcs host details', () => {
|
|
7
|
+
it('should define the repository details when the host is github', () => {
|
|
8
|
+
const owner = any.word();
|
|
9
|
+
const name = any.word();
|
|
10
|
+
|
|
11
|
+
expect(defineVcsHostDetails({host: 'github', owner, name})).toEqual({
|
|
12
|
+
repository: `${owner}/${name}`,
|
|
13
|
+
bugs: `https://github.com/${owner}/${name}/issues`
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
3
|
+
|
|
4
|
+
import {test as npmIsUsed} from './npm/index.js';
|
|
5
|
+
import {test as yarnIsUsed} from './yarn/index.js';
|
|
6
|
+
|
|
7
|
+
export default async function resolveCurrentPackageManager({projectRoot, packageManager}) {
|
|
8
|
+
if (packageManager) return packageManager;
|
|
9
|
+
|
|
10
|
+
const {packageManager: pinnedPackageManager} = JSON.parse(await fs.readFile(`${projectRoot}/package.json`, 'utf-8'));
|
|
11
|
+
|
|
12
|
+
if (await npmIsUsed({projectRoot, pinnedPackageManager})) {
|
|
13
|
+
return packageManagers.NPM;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (await yarnIsUsed({projectRoot, pinnedPackageManager})) {
|
|
17
|
+
return packageManagers.YARN;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
throw new Error('Package-manager could not be determined');
|
|
21
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
3
|
+
|
|
4
|
+
import {beforeEach, describe, expect, it, vi} from 'vitest';
|
|
5
|
+
import any from '@travi/any';
|
|
6
|
+
import {when} from 'vitest-when';
|
|
7
|
+
|
|
8
|
+
import {test as npmIsUsed} from './npm/index.js';
|
|
9
|
+
import {test as yarnIsUsed} from './yarn/index.js';
|
|
10
|
+
import derive from './current-manager-resolver.js';
|
|
11
|
+
|
|
12
|
+
vi.mock('node:fs');
|
|
13
|
+
vi.mock('./npm/index.js');
|
|
14
|
+
vi.mock('./yarn/index.js');
|
|
15
|
+
|
|
16
|
+
describe('package manager', () => {
|
|
17
|
+
const projectRoot = any.string();
|
|
18
|
+
const pinnedPackageManager = any.word();
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
when(fs.readFile)
|
|
22
|
+
.calledWith(`${projectRoot}/package.json`, 'utf-8')
|
|
23
|
+
.thenResolve(JSON.stringify({...any.simpleObject(), packageManager: pinnedPackageManager}));
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return an already defined manager directly', async () => {
|
|
27
|
+
const packageManager = any.word();
|
|
28
|
+
|
|
29
|
+
expect(await derive({packageManager})).toEqual(packageManager);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should return `npm` when a `package-lock.json` exists', async () => {
|
|
33
|
+
when(npmIsUsed).calledWith({projectRoot, pinnedPackageManager}).thenResolve(true);
|
|
34
|
+
|
|
35
|
+
expect(await derive({projectRoot})).toEqual(packageManagers.NPM);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return `yarn` when a `yarn.lock` exists', async () => {
|
|
39
|
+
when(npmIsUsed).calledWith({projectRoot, pinnedPackageManager}).thenResolve(false);
|
|
40
|
+
when(yarnIsUsed).calledWith({projectRoot, pinnedPackageManager}).thenResolve(true);
|
|
41
|
+
|
|
42
|
+
expect(await derive({projectRoot})).toEqual(packageManagers.YARN);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should throw an error when no manager is provided and no lockfile is found', async () => {
|
|
46
|
+
when(npmIsUsed).calledWith({projectRoot, pinnedPackageManager}).thenResolve(false);
|
|
47
|
+
when(yarnIsUsed).calledWith({projectRoot, pinnedPackageManager}).thenResolve(false);
|
|
48
|
+
|
|
49
|
+
await expect(() => derive({projectRoot})).rejects.toThrowError('Package-manager could not be determined');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export {default as test} from './tester.js';
|
|
2
|
+
export {default as lift} from './lifter.js';
|
|
3
|
+
export {default as scaffold} from './scaffolder.js';
|
|
4
|
+
export {default as determineCurrent} from './current-manager-resolver.js';
|
|
5
|
+
export {default as defineLockfilePath} from './lockfile-path-resolver.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {describe, it, vi, expect, afterEach} from 'vitest';
|
|
2
|
+
|
|
3
|
+
import {lift as liftCorepack} from '../corepack/index.js';
|
|
4
|
+
import liftPackageManger from './lifter.js';
|
|
5
|
+
|
|
6
|
+
vi.mock('../corepack/index.js');
|
|
7
|
+
|
|
8
|
+
describe('package-manager lifter', () => {
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should lift package-manager details', async () => {
|
|
14
|
+
expect(await liftPackageManger()).toEqual({});
|
|
15
|
+
|
|
16
|
+
expect(liftCorepack).toHaveBeenCalled();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
export default function resolveLockfilePath(packageManager) {
|
|
4
|
+
const lockfilePaths = {
|
|
5
|
+
[packageManagers.NPM]: 'package-lock.json',
|
|
6
|
+
[packageManagers.YARN]: 'yarn.lock'
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
return lockfilePaths[packageManager];
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
import {describe, it, expect} from 'vitest';
|
|
4
|
+
|
|
5
|
+
import determineLockfilePathFor from './lockfile-path-resolver.js';
|
|
6
|
+
|
|
7
|
+
describe('package manager lockfile path resolver', () => {
|
|
8
|
+
it('should return `package-lock.json` for npm', () => {
|
|
9
|
+
expect(determineLockfilePathFor(packageManagers.NPM)).toEqual('package-lock.json');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should return `yarn.lock` for yarn', () => {
|
|
13
|
+
expect(determineLockfilePathFor(packageManagers.YARN)).toEqual('yarn.lock');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import {execa} from 'execa';
|
|
3
|
+
import {writePackageJson} from '@form8ion/javascript-core';
|
|
4
|
+
|
|
5
|
+
export default async function scaffoldNpmPackageManager({projectRoot}) {
|
|
6
|
+
const [packageContents, {stdout}] = await Promise.all([
|
|
7
|
+
fs.readFile(`${projectRoot}/package.json`, 'utf-8'),
|
|
8
|
+
execa('npm', ['--version'])
|
|
9
|
+
]);
|
|
10
|
+
const existingPackageJsonContents = JSON.parse(packageContents);
|
|
11
|
+
|
|
12
|
+
await writePackageJson({
|
|
13
|
+
projectRoot,
|
|
14
|
+
config: {
|
|
15
|
+
...existingPackageJsonContents,
|
|
16
|
+
packageManager: `npm@${stdout}`
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import {execa} from 'execa';
|
|
3
|
+
import {writePackageJson} from '@form8ion/javascript-core';
|
|
4
|
+
|
|
5
|
+
import any from '@travi/any';
|
|
6
|
+
import {vi, it, describe, expect} from 'vitest';
|
|
7
|
+
import {when} from 'vitest-when';
|
|
8
|
+
|
|
9
|
+
import scaffoldNpm from './scaffolder.js';
|
|
10
|
+
|
|
11
|
+
vi.mock('node:fs');
|
|
12
|
+
vi.mock('execa');
|
|
13
|
+
vi.mock('@form8ion/javascript-core');
|
|
14
|
+
|
|
15
|
+
describe('npm scaffolder', () => {
|
|
16
|
+
const projectRoot = any.string();
|
|
17
|
+
|
|
18
|
+
it('should scaffold the npm package manager', async () => {
|
|
19
|
+
const existingPackageContents = any.simpleObject();
|
|
20
|
+
const cliVersion = any.word();
|
|
21
|
+
when(fs.readFile)
|
|
22
|
+
.calledWith(`${projectRoot}/package.json`, 'utf-8')
|
|
23
|
+
.thenResolve(JSON.stringify(existingPackageContents));
|
|
24
|
+
when(execa).calledWith('npm', ['--version']).thenResolve({stdout: cliVersion});
|
|
25
|
+
|
|
26
|
+
await scaffoldNpm({projectRoot});
|
|
27
|
+
|
|
28
|
+
expect(writePackageJson).toHaveBeenCalledWith({
|
|
29
|
+
projectRoot,
|
|
30
|
+
config: {...existingPackageContents, packageManager: `npm@${cliVersion}`}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {fileExists} from '@form8ion/core';
|
|
2
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
3
|
+
|
|
4
|
+
import determineLockfilePath from '../lockfile-path-resolver.js';
|
|
5
|
+
|
|
6
|
+
export default function packageManagerIsNpm({projectRoot, pinnedPackageManager = ''}) {
|
|
7
|
+
const [packageManager] = pinnedPackageManager.split('@');
|
|
8
|
+
|
|
9
|
+
return packageManagers.NPM === packageManager
|
|
10
|
+
|| fileExists(`${projectRoot}/${determineLockfilePath(packageManagers.NPM)}`);
|
|
11
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {fileExists} from '@form8ion/core';
|
|
2
|
+
|
|
3
|
+
import {expect, describe, it, vi, afterEach} from 'vitest';
|
|
4
|
+
import any from '@travi/any';
|
|
5
|
+
import {when} from 'vitest-when';
|
|
6
|
+
|
|
7
|
+
import npmIsUsed from './tester.js';
|
|
8
|
+
|
|
9
|
+
vi.mock('@form8ion/core');
|
|
10
|
+
|
|
11
|
+
describe('npm predicate', () => {
|
|
12
|
+
const projectRoot = any.string();
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should return `true` is a `package-lock.json` exists', async () => {
|
|
19
|
+
when(fileExists).calledWith(`${projectRoot}/package-lock.json`).thenResolve(true);
|
|
20
|
+
|
|
21
|
+
expect(await npmIsUsed({projectRoot})).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should return `false` is a `package-lock.json` does not exist', async () => {
|
|
25
|
+
when(fileExists).calledWith(`${projectRoot}/package-lock.json`).thenResolve(false);
|
|
26
|
+
|
|
27
|
+
expect(await npmIsUsed({projectRoot})).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return true if the package manager is pinned to npm', async () => {
|
|
31
|
+
expect(await npmIsUsed({projectRoot, pinnedPackageManager: 'npm@1.2.3'})).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {scaffold as scaffoldNpm} from './npm/index.js';
|
|
2
|
+
import {scaffold as scaffoldYarn} from './yarn/index.js';
|
|
3
|
+
|
|
4
|
+
const scaffolders = {
|
|
5
|
+
npm: scaffoldNpm,
|
|
6
|
+
yarn: scaffoldYarn
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function scaffoldPackageManager({projectRoot, packageManager}) {
|
|
10
|
+
return scaffolders[packageManager]({projectRoot});
|
|
11
|
+
}
|