@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,10 @@
|
|
|
1
|
+
import {dialects} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
export default function gatherDialectInput({babelPreset, typescript}) {
|
|
4
|
+
return [
|
|
5
|
+
{name: 'Common JS (no transpilation)', value: dialects.COMMON_JS, short: 'cjs'},
|
|
6
|
+
...babelPreset ? [{name: 'Modern JavaScript (transpiled)', value: dialects.BABEL, short: 'modern'}] : [],
|
|
7
|
+
{name: 'ESM-only (no transpilation)', value: dialects.ESM, short: 'esm'},
|
|
8
|
+
...typescript ? [{name: 'TypeScript', value: dialects.TYPESCRIPT, short: 'ts'}] : []
|
|
9
|
+
];
|
|
10
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {dialects} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
import any from '@travi/any';
|
|
4
|
+
import {describe, expect, it} from 'vitest';
|
|
5
|
+
|
|
6
|
+
import buildDialectChoices from './prompt-choices.js';
|
|
7
|
+
|
|
8
|
+
describe('dialect prompt questions', () => {
|
|
9
|
+
it('should list available dialects', () => {
|
|
10
|
+
expect(buildDialectChoices({
|
|
11
|
+
...any.simpleObject(),
|
|
12
|
+
babelPreset: any.simpleObject(),
|
|
13
|
+
typescript: any.simpleObject()
|
|
14
|
+
})).toEqual([
|
|
15
|
+
{name: 'Common JS (no transpilation)', value: dialects.COMMON_JS, short: 'cjs'},
|
|
16
|
+
{name: 'Modern JavaScript (transpiled)', value: dialects.BABEL, short: 'modern'},
|
|
17
|
+
{name: 'ESM-only (no transpilation)', value: dialects.ESM, short: 'esm'},
|
|
18
|
+
{name: 'TypeScript', value: dialects.TYPESCRIPT, short: 'ts'}
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should not include babel or typescript in the choices list when configs are not provided', () => {
|
|
23
|
+
expect(buildDialectChoices(any.simpleObject())).toEqual([
|
|
24
|
+
{name: 'Common JS (no transpilation)', value: dialects.COMMON_JS, short: 'cjs'},
|
|
25
|
+
{name: 'ESM-only (no transpilation)', value: dialects.ESM, short: 'esm'}
|
|
26
|
+
]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {dialects} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
import {scaffold as scaffoldBabel} from './babel/index.js';
|
|
4
|
+
import {scaffold as scaffoldTypescript} from './typescript/index.js';
|
|
5
|
+
|
|
6
|
+
export default function scaffoldDialect({dialect, projectType, projectRoot, configs, testFilenamePattern}) {
|
|
7
|
+
switch (dialect) {
|
|
8
|
+
case dialects.BABEL:
|
|
9
|
+
return scaffoldBabel({preset: configs.babelPreset, projectRoot});
|
|
10
|
+
case dialects.TYPESCRIPT:
|
|
11
|
+
return scaffoldTypescript({config: configs.typescript, projectType, projectRoot, testFilenamePattern});
|
|
12
|
+
default:
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {dialects} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
import any from '@travi/any';
|
|
4
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
5
|
+
import {when} from 'vitest-when';
|
|
6
|
+
|
|
7
|
+
import {scaffold as scaffoldBabel} from './babel/index.js';
|
|
8
|
+
import {scaffold as scaffoldTypescript} from './typescript/index.js';
|
|
9
|
+
import scaffoldDialect from './scaffolder.js';
|
|
10
|
+
|
|
11
|
+
vi.mock('./babel/index.js');
|
|
12
|
+
vi.mock('./typescript/index.js');
|
|
13
|
+
|
|
14
|
+
describe('dialect scaffolder', () => {
|
|
15
|
+
const projectRoot = any.string();
|
|
16
|
+
|
|
17
|
+
it('should not scaffold babel or typescript when not chosen', async () => {
|
|
18
|
+
expect(await scaffoldDialect({dialect: any.word()})).toEqual({});
|
|
19
|
+
expect(scaffoldBabel).not.toHaveBeenCalled();
|
|
20
|
+
expect(scaffoldTypescript).not.toHaveBeenCalled();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should scaffold babel when chosen', async () => {
|
|
24
|
+
const babelPreset = any.word();
|
|
25
|
+
const babelResults = any.simpleObject();
|
|
26
|
+
when(scaffoldBabel).calledWith({preset: babelPreset, projectRoot}).thenResolve(babelResults);
|
|
27
|
+
|
|
28
|
+
expect(await scaffoldDialect({dialect: dialects.BABEL, configs: {babelPreset}, projectRoot}))
|
|
29
|
+
.toEqual(babelResults);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should scaffold typescript when chosen', async () => {
|
|
33
|
+
const typescriptConfigs = any.simpleObject();
|
|
34
|
+
const typescriptResults = any.simpleObject();
|
|
35
|
+
const testFilenamePattern = any.string();
|
|
36
|
+
const projectType = any.word();
|
|
37
|
+
when(scaffoldTypescript)
|
|
38
|
+
.calledWith({config: typescriptConfigs, projectType, projectRoot, testFilenamePattern})
|
|
39
|
+
.thenResolve(typescriptResults);
|
|
40
|
+
|
|
41
|
+
expect(await scaffoldDialect({
|
|
42
|
+
dialect: dialects.TYPESCRIPT,
|
|
43
|
+
projectType,
|
|
44
|
+
configs: {typescript: typescriptConfigs},
|
|
45
|
+
projectRoot,
|
|
46
|
+
testFilenamePattern
|
|
47
|
+
})).toEqual(typescriptResults);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default as scaffold} from './scaffolder.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {fileTypes, writeConfigFile} from '@form8ion/core';
|
|
2
|
+
import {projectTypes} from '@form8ion/javascript-core';
|
|
3
|
+
|
|
4
|
+
export default async function scaffoldTypescript({config, projectType, projectRoot, testFilenamePattern}) {
|
|
5
|
+
const shareableTsConfigPackage = `${config.scope}/tsconfig`;
|
|
6
|
+
|
|
7
|
+
await writeConfigFile({
|
|
8
|
+
path: projectRoot,
|
|
9
|
+
name: 'tsconfig',
|
|
10
|
+
format: fileTypes.JSON,
|
|
11
|
+
config: {
|
|
12
|
+
$schema: 'https://json.schemastore.org/tsconfig',
|
|
13
|
+
extends: shareableTsConfigPackage,
|
|
14
|
+
compilerOptions: {
|
|
15
|
+
rootDir: 'src',
|
|
16
|
+
...projectTypes.PACKAGE === projectType && {
|
|
17
|
+
outDir: 'lib',
|
|
18
|
+
declaration: true
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
include: ['src/**/*.ts'],
|
|
22
|
+
...testFilenamePattern && {exclude: [testFilenamePattern]}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
eslint: {configs: ['typescript']},
|
|
28
|
+
dependencies: {javascript: {development: ['typescript', shareableTsConfigPackage]}},
|
|
29
|
+
vcsIgnore: {files: ['tsconfig.tsbuildinfo']}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {fileTypes, writeConfigFile} from '@form8ion/core';
|
|
2
|
+
import {projectTypes} from '@form8ion/javascript-core';
|
|
3
|
+
|
|
4
|
+
import {describe, vi, afterEach, it, expect} from 'vitest';
|
|
5
|
+
import any from '@travi/any';
|
|
6
|
+
|
|
7
|
+
import scaffoldTypescriptDialect from './scaffolder.js';
|
|
8
|
+
|
|
9
|
+
vi.mock('@form8ion/core');
|
|
10
|
+
|
|
11
|
+
describe('typescript dialect scaffolder', () => {
|
|
12
|
+
const scope = `@${any.word()}`;
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should define the eslint config', async () => {
|
|
19
|
+
const {eslint: {configs}} = await scaffoldTypescriptDialect({config: {}});
|
|
20
|
+
|
|
21
|
+
expect(configs).toEqual(['typescript']);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should extend the scoped package in the tsconfig', async () => {
|
|
25
|
+
const projectRoot = any.string();
|
|
26
|
+
|
|
27
|
+
await scaffoldTypescriptDialect({config: {scope}, projectRoot});
|
|
28
|
+
|
|
29
|
+
expect(writeConfigFile).toHaveBeenCalledWith({
|
|
30
|
+
path: projectRoot,
|
|
31
|
+
name: 'tsconfig',
|
|
32
|
+
format: fileTypes.JSON,
|
|
33
|
+
config: {
|
|
34
|
+
$schema: 'https://json.schemastore.org/tsconfig',
|
|
35
|
+
extends: `${scope}/tsconfig`,
|
|
36
|
+
compilerOptions: {rootDir: 'src'},
|
|
37
|
+
include: ['src/**/*.ts']
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should define package specific details when the project is a package', async () => {
|
|
43
|
+
const projectRoot = any.string();
|
|
44
|
+
|
|
45
|
+
await scaffoldTypescriptDialect({config: {scope}, projectType: projectTypes.PACKAGE, projectRoot});
|
|
46
|
+
|
|
47
|
+
expect(writeConfigFile).toHaveBeenCalledWith({
|
|
48
|
+
path: projectRoot,
|
|
49
|
+
name: 'tsconfig',
|
|
50
|
+
format: fileTypes.JSON,
|
|
51
|
+
config: {
|
|
52
|
+
$schema: 'https://json.schemastore.org/tsconfig',
|
|
53
|
+
extends: `${scope}/tsconfig`,
|
|
54
|
+
compilerOptions: {
|
|
55
|
+
rootDir: 'src',
|
|
56
|
+
outDir: 'lib',
|
|
57
|
+
declaration: true
|
|
58
|
+
},
|
|
59
|
+
include: ['src/**/*.ts']
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should include the testFilenamePattern as an `exclude` when provided', async () => {
|
|
65
|
+
const projectRoot = any.string();
|
|
66
|
+
const testFilenamePattern = any.string();
|
|
67
|
+
|
|
68
|
+
await scaffoldTypescriptDialect({config: {scope}, projectRoot, testFilenamePattern});
|
|
69
|
+
|
|
70
|
+
expect(writeConfigFile).toHaveBeenCalledWith({
|
|
71
|
+
path: projectRoot,
|
|
72
|
+
name: 'tsconfig',
|
|
73
|
+
format: fileTypes.JSON,
|
|
74
|
+
config: {
|
|
75
|
+
$schema: 'https://json.schemastore.org/tsconfig',
|
|
76
|
+
extends: `${scope}/tsconfig`,
|
|
77
|
+
compilerOptions: {rootDir: 'src'},
|
|
78
|
+
include: ['src/**/*.ts'],
|
|
79
|
+
exclude: [testFilenamePattern]
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should define dev dependencies', async () => {
|
|
85
|
+
const {dependencies} = await scaffoldTypescriptDialect({config: {scope}});
|
|
86
|
+
|
|
87
|
+
expect(dependencies.javascript.development).toEqual(['typescript', `${scope}/tsconfig`]);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should ignore files from version control', async () => {
|
|
91
|
+
const {vcsIgnore: {files}} = await scaffoldTypescriptDialect({config: {}});
|
|
92
|
+
|
|
93
|
+
expect(files).toEqual(['tsconfig.tsbuildinfo']);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
export default function scaffoldGenerationCommand(packageManager) {
|
|
4
|
+
if (packageManagers.NPM === packageManager) return 'npm run generate:md';
|
|
5
|
+
if (packageManagers.YARN === packageManager) return 'yarn generate:md';
|
|
6
|
+
|
|
7
|
+
throw new Error(
|
|
8
|
+
`The ${packageManager} package manager is currently not supported. `
|
|
9
|
+
+ `Only ${Object.values(packageManagers).join(' and ')} are currently supported.`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {packageManagers} from '@form8ion/javascript-core';
|
|
2
|
+
|
|
3
|
+
import {describe, expect, it} from 'vitest';
|
|
4
|
+
import any from '@travi/any';
|
|
5
|
+
|
|
6
|
+
import buildCommand from './generation-command.js';
|
|
7
|
+
|
|
8
|
+
describe('documentation generation command', () => {
|
|
9
|
+
it('should return the npm variation of the command', () => {
|
|
10
|
+
expect(buildCommand(packageManagers.NPM)).toEqual('npm run generate:md');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should return the yarn variation of the command', () => {
|
|
14
|
+
expect(buildCommand(packageManagers.YARN)).toEqual('yarn generate:md');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should throw an error for unsupported package managers', () => {
|
|
18
|
+
const packageManager = any.word();
|
|
19
|
+
|
|
20
|
+
expect(() => buildCommand(packageManager)).toThrowError(
|
|
21
|
+
`The ${packageManager} package manager is currently not supported. `
|
|
22
|
+
+ `Only ${Object.values(packageManagers).join(' and ')} are currently supported.`
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default} from './scaffolder.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import buildGenerationCommand from './generation-command.js';
|
|
2
|
+
|
|
3
|
+
export default function scaffoldDocumentation({projectTypeResults, packageManager}) {
|
|
4
|
+
return {
|
|
5
|
+
toc: `Run \`${buildGenerationCommand(packageManager)}\` to generate a table of contents`,
|
|
6
|
+
...projectTypeResults.documentation,
|
|
7
|
+
contributing: `### Dependencies
|
|
8
|
+
|
|
9
|
+
\`\`\`sh
|
|
10
|
+
$ nvm install
|
|
11
|
+
$ ${packageManager} install
|
|
12
|
+
\`\`\`
|
|
13
|
+
|
|
14
|
+
### Verification
|
|
15
|
+
|
|
16
|
+
\`\`\`sh
|
|
17
|
+
$ ${packageManager} test
|
|
18
|
+
\`\`\``
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import any from '@travi/any';
|
|
2
|
+
import {beforeEach, describe, expect, it, vi} from 'vitest';
|
|
3
|
+
import {when} from 'vitest-when';
|
|
4
|
+
|
|
5
|
+
import buildDocumentationCommand from './generation-command.js';
|
|
6
|
+
import scaffoldDocumentation from './scaffolder.js';
|
|
7
|
+
|
|
8
|
+
vi.mock('./generation-command.js');
|
|
9
|
+
|
|
10
|
+
describe('documentation scaffolder', () => {
|
|
11
|
+
const packageManager = any.word();
|
|
12
|
+
const documentationGenerationCommand = any.string();
|
|
13
|
+
const tocMessage = `Run \`${documentationGenerationCommand}\` to generate a table of contents`;
|
|
14
|
+
const contributionDocumentation = `### Dependencies
|
|
15
|
+
|
|
16
|
+
\`\`\`sh
|
|
17
|
+
$ nvm install
|
|
18
|
+
$ ${packageManager} install
|
|
19
|
+
\`\`\`
|
|
20
|
+
|
|
21
|
+
### Verification
|
|
22
|
+
|
|
23
|
+
\`\`\`sh
|
|
24
|
+
$ ${packageManager} test
|
|
25
|
+
\`\`\``;
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
when(buildDocumentationCommand).calledWith(packageManager).thenReturn(documentationGenerationCommand);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should provide project-type documentation and contribution details', () => {
|
|
32
|
+
const projectTypeResults = {documentation: any.simpleObject()};
|
|
33
|
+
|
|
34
|
+
expect(scaffoldDocumentation({projectTypeResults, packageManager})).toEqual({
|
|
35
|
+
toc: tocMessage,
|
|
36
|
+
...projectTypeResults.documentation,
|
|
37
|
+
contributing: contributionDocumentation
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should not include project-type documentation when not provided', () => {
|
|
42
|
+
const projectTypeResults = {documentation: undefined};
|
|
43
|
+
|
|
44
|
+
expect(scaffoldDocumentation({projectTypeResults, packageManager})).toEqual({
|
|
45
|
+
toc: tocMessage,
|
|
46
|
+
contributing: contributionDocumentation
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default async function liftEngines({packageDetails: {name}}) {
|
|
2
|
+
return {
|
|
3
|
+
dependencies: {javascript: {development: ['ls-engines']}},
|
|
4
|
+
scripts: {'lint:engines': 'ls-engines'},
|
|
5
|
+
badges: {consumer: {node: {img: `https://img.shields.io/node/v/${name}?logo=node.js`, text: 'node'}}}
|
|
6
|
+
};
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {describe, it, expect} from 'vitest';
|
|
2
|
+
import any from '@travi/any';
|
|
3
|
+
|
|
4
|
+
import liftEngines from './lifter.js';
|
|
5
|
+
|
|
6
|
+
describe('engines lifter', () => {
|
|
7
|
+
it('should return the details for linting and communicating engines restrictions', async () => {
|
|
8
|
+
const packageName = any.word();
|
|
9
|
+
const packageDetails = {...any.simpleObject(), name: packageName};
|
|
10
|
+
|
|
11
|
+
const {scripts, badges, dependencies} = await liftEngines({packageDetails});
|
|
12
|
+
|
|
13
|
+
expect(scripts['lint:engines']).toEqual('ls-engines');
|
|
14
|
+
expect(dependencies.javascript.development).toEqual(['ls-engines']);
|
|
15
|
+
expect(badges.consumer.node)
|
|
16
|
+
.toEqual({img: `https://img.shields.io/node/v/${packageName}?logo=node.js`, text: 'node'});
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import {describe, it, expect, vi, afterEach} from 'vitest';
|
|
4
|
+
import any from '@travi/any';
|
|
5
|
+
import {when} from 'vitest-when';
|
|
6
|
+
|
|
7
|
+
import testEngines from './tester.js';
|
|
8
|
+
|
|
9
|
+
vi.mock('node:fs');
|
|
10
|
+
|
|
11
|
+
describe('engines tester', () => {
|
|
12
|
+
const projectRoot = any.string();
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should return `true` when `engines.node` is defined', async () => {
|
|
19
|
+
when(fs.readFile)
|
|
20
|
+
.calledWith(`${projectRoot}/package.json`, 'utf8')
|
|
21
|
+
.thenResolve(JSON.stringify({engines: {node: any.word()}}));
|
|
22
|
+
|
|
23
|
+
expect(await testEngines({projectRoot})).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return `false` when `engines.node` is not defined', async () => {
|
|
27
|
+
when(fs.readFile).calledWith(`${projectRoot}/package.json`, 'utf8').thenReturn(JSON.stringify({engines: {}}));
|
|
28
|
+
|
|
29
|
+
expect(await testEngines({projectRoot})).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should return `false` when `engines` is not defined', async () => {
|
|
33
|
+
when(fs.readFile).calledWith(`${projectRoot}/package.json`, 'utf8').thenReturn(JSON.stringify({}));
|
|
34
|
+
|
|
35
|
+
expect(await testEngines({projectRoot})).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
});
|
package/src/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {questionNames as languageScaffolderPromptsQuestionNames} from '@travi/language-scaffolder-prompts';
|
|
2
|
+
|
|
3
|
+
import {questionNames as jsScaffolderQuestionNames} from './prompts/question-names.js';
|
|
4
|
+
|
|
5
|
+
export {scaffold as scaffoldUnitTesting} from './testing/unit/index.js';
|
|
6
|
+
export {default as scaffold} from './scaffolder.js';
|
|
7
|
+
export {default as lift} from './lifter.js';
|
|
8
|
+
export {default as test} from './tester.js';
|
|
9
|
+
export const questionNames = {...languageScaffolderPromptsQuestionNames, ...jsScaffolderQuestionNames};
|
package/src/lifter.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import deepmerge from 'deepmerge';
|
|
3
|
+
import {info} from '@travi/cli-messages';
|
|
4
|
+
import {applyEnhancers} from '@form8ion/core';
|
|
5
|
+
import * as huskyPlugin from '@form8ion/husky';
|
|
6
|
+
import * as commitConventionPlugin from '@form8ion/commit-convention';
|
|
7
|
+
|
|
8
|
+
import * as registriesPlugin from './registries/index.js';
|
|
9
|
+
import * as coveragePlugin from './coverage/index.js';
|
|
10
|
+
import * as codeStylePlugin from './code-style/index.js';
|
|
11
|
+
import * as npmConfigPlugin from './npm-config/index.js';
|
|
12
|
+
import * as enginesEnhancer from './engines/index.js';
|
|
13
|
+
import * as projectTypes from './project-type/index.js';
|
|
14
|
+
import * as dialects from './dialects/index.js';
|
|
15
|
+
import {lift as liftPackage} from './package/index.js';
|
|
16
|
+
import * as packageManagers from './package-managers/index.js';
|
|
17
|
+
import {determineCurrent as resolvePackageManager} from './package-managers/index.js';
|
|
18
|
+
|
|
19
|
+
export default async function liftJavaScript({
|
|
20
|
+
projectRoot,
|
|
21
|
+
vcs,
|
|
22
|
+
results,
|
|
23
|
+
pathWithinParent,
|
|
24
|
+
enhancers = {},
|
|
25
|
+
configs = {}
|
|
26
|
+
}) {
|
|
27
|
+
info('Lifting JavaScript-specific details');
|
|
28
|
+
|
|
29
|
+
const [packageManager, packageContents] = await Promise.all([
|
|
30
|
+
resolvePackageManager({projectRoot, packageManager: results.packageManager}),
|
|
31
|
+
fs.readFile(`${projectRoot}/package.json`, 'utf8')
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
const enhancerResults = await applyEnhancers({
|
|
35
|
+
results,
|
|
36
|
+
enhancers: {
|
|
37
|
+
...enhancers,
|
|
38
|
+
huskyPlugin,
|
|
39
|
+
enginesEnhancer,
|
|
40
|
+
coveragePlugin,
|
|
41
|
+
commitConventionPlugin,
|
|
42
|
+
dialects,
|
|
43
|
+
codeStylePlugin,
|
|
44
|
+
npmConfigPlugin,
|
|
45
|
+
projectTypes,
|
|
46
|
+
packageManagers,
|
|
47
|
+
registriesPlugin
|
|
48
|
+
},
|
|
49
|
+
options: {packageManager, projectRoot, vcs, packageDetails: JSON.parse(packageContents), configs}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await liftPackage(deepmerge.all([{projectRoot, packageManager, vcs, pathWithinParent}, enhancerResults]));
|
|
53
|
+
|
|
54
|
+
return enhancerResults;
|
|
55
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import deepmerge from 'deepmerge';
|
|
3
|
+
import * as core from '@form8ion/core';
|
|
4
|
+
import * as huskyPlugin from '@form8ion/husky';
|
|
5
|
+
import * as commitConventionPlugin from '@form8ion/commit-convention';
|
|
6
|
+
|
|
7
|
+
import {beforeEach, describe, expect, it, vi} from 'vitest';
|
|
8
|
+
import any from '@travi/any';
|
|
9
|
+
import {when} from 'vitest-when';
|
|
10
|
+
|
|
11
|
+
import * as registriesPlugin from './registries/index.js';
|
|
12
|
+
import * as coveragePlugin from './coverage/index.js';
|
|
13
|
+
import * as codeStylePlugin from './code-style/index.js';
|
|
14
|
+
import * as npmConfigPlugin from './npm-config/index.js';
|
|
15
|
+
import * as enginesEnhancer from './engines/index.js';
|
|
16
|
+
import * as projectTypes from './project-type/index.js';
|
|
17
|
+
import * as dialects from './dialects/index.js';
|
|
18
|
+
import liftPackage from './package/lifter.js';
|
|
19
|
+
import * as packageManagers from './package-managers/index.js';
|
|
20
|
+
import {determineCurrent as packageManagerResolver} from './package-managers/index.js';
|
|
21
|
+
import lift from './lifter.js';
|
|
22
|
+
|
|
23
|
+
vi.mock('node:fs');
|
|
24
|
+
vi.mock('@form8ion/core');
|
|
25
|
+
vi.mock('./package/lifter.js');
|
|
26
|
+
vi.mock('./package-managers/index.js');
|
|
27
|
+
|
|
28
|
+
describe('lift', () => {
|
|
29
|
+
const projectRoot = any.string();
|
|
30
|
+
const scripts = any.simpleObject();
|
|
31
|
+
const tags = any.listOf(any.word);
|
|
32
|
+
const dependencies = any.simpleObject();
|
|
33
|
+
const devDependencies = any.simpleObject();
|
|
34
|
+
const packageManager = any.word();
|
|
35
|
+
const manager = any.word();
|
|
36
|
+
const enhancerResults = any.simpleObject();
|
|
37
|
+
const vcsDetails = any.simpleObject();
|
|
38
|
+
const results = {...any.simpleObject(), scripts, tags, dependencies, devDependencies, packageManager: manager};
|
|
39
|
+
const pathWithinParent = any.string();
|
|
40
|
+
const packageDetails = any.simpleObject();
|
|
41
|
+
const internalEnhancers = {
|
|
42
|
+
huskyPlugin,
|
|
43
|
+
enginesEnhancer,
|
|
44
|
+
coveragePlugin,
|
|
45
|
+
commitConventionPlugin,
|
|
46
|
+
dialects,
|
|
47
|
+
codeStylePlugin,
|
|
48
|
+
npmConfigPlugin,
|
|
49
|
+
projectTypes,
|
|
50
|
+
packageManagers,
|
|
51
|
+
registriesPlugin
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
when(packageManagerResolver)
|
|
56
|
+
.calledWith({projectRoot, packageManager: manager})
|
|
57
|
+
.thenResolve(packageManager);
|
|
58
|
+
when(fs.readFile)
|
|
59
|
+
.calledWith(`${projectRoot}/package.json`, 'utf8')
|
|
60
|
+
.thenResolve(JSON.stringify(packageDetails));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should lift results that are specific to js projects', async () => {
|
|
64
|
+
const configs = any.simpleObject();
|
|
65
|
+
when(core.applyEnhancers)
|
|
66
|
+
.calledWith({
|
|
67
|
+
results,
|
|
68
|
+
enhancers: internalEnhancers,
|
|
69
|
+
options: {projectRoot, packageManager, vcs: vcsDetails, packageDetails, configs}
|
|
70
|
+
})
|
|
71
|
+
.thenResolve(enhancerResults);
|
|
72
|
+
|
|
73
|
+
const liftResults = await lift({projectRoot, vcs: vcsDetails, results, pathWithinParent, configs});
|
|
74
|
+
|
|
75
|
+
expect(liftResults).toEqual(enhancerResults);
|
|
76
|
+
expect(liftPackage).toHaveBeenCalledWith(deepmerge.all([
|
|
77
|
+
{projectRoot, packageManager, vcs: vcsDetails, pathWithinParent},
|
|
78
|
+
enhancerResults
|
|
79
|
+
]));
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should apply provided enhancers', async () => {
|
|
83
|
+
const enhancers = any.simpleObject();
|
|
84
|
+
when(core.applyEnhancers)
|
|
85
|
+
.calledWith({
|
|
86
|
+
results,
|
|
87
|
+
enhancers: {...enhancers, ...internalEnhancers},
|
|
88
|
+
options: {projectRoot, packageManager, vcs: vcsDetails, packageDetails, configs: {}}
|
|
89
|
+
})
|
|
90
|
+
.thenResolve(enhancerResults);
|
|
91
|
+
|
|
92
|
+
const liftResults = await lift({projectRoot, vcs: vcsDetails, results, pathWithinParent, enhancers});
|
|
93
|
+
|
|
94
|
+
expect(liftResults).toEqual(enhancerResults);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {default as scaffold} from './scaffolder.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
2
|
+
import any from '@travi/any';
|
|
3
|
+
import {when} from 'vitest-when';
|
|
4
|
+
|
|
5
|
+
import {scaffold as scaffoldLockfileLint} from '../lockfile-lint/index.js';
|
|
6
|
+
import {scaffold} from './index.js';
|
|
7
|
+
|
|
8
|
+
vi.mock('../lockfile-lint');
|
|
9
|
+
|
|
10
|
+
describe('linting scaffolder', () => {
|
|
11
|
+
const pathWithinParent = any.string();
|
|
12
|
+
const projectRoot = any.string();
|
|
13
|
+
const packageManager = any.word();
|
|
14
|
+
const vcs = any.simpleObject();
|
|
15
|
+
const registries = any.simpleObject();
|
|
16
|
+
|
|
17
|
+
it('should configure linters when config definitions are provided', async () => {
|
|
18
|
+
const lockfileLintResults = any.simpleObject();
|
|
19
|
+
when(scaffoldLockfileLint)
|
|
20
|
+
.calledWith({projectRoot, packageManager, registries})
|
|
21
|
+
.thenResolve(lockfileLintResults);
|
|
22
|
+
|
|
23
|
+
expect(await scaffold({
|
|
24
|
+
projectRoot,
|
|
25
|
+
vcs,
|
|
26
|
+
packageManager,
|
|
27
|
+
pathWithinParent,
|
|
28
|
+
registries
|
|
29
|
+
})).toEqual(lockfileLintResults);
|
|
30
|
+
});
|
|
31
|
+
});
|