@form8ion/eslint-config-extender 10.0.3 → 11.0.0-beta.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/example.js +32 -12
- package/lib/index.mjs +24 -9
- package/lib/index.mjs.map +1 -1
- package/package.json +27 -24
- package/src/constants.js +2 -0
- package/src/high-level.js +37 -0
- package/src/high-level.test.js +48 -0
- package/src/index.js +3 -0
- package/src/language-handler-prompt.js +13 -0
- package/src/language-handler-prompt.test.js +26 -0
- package/src/scaffold.js +40 -0
- package/src/scaffold.test.js +58 -0
package/example.js
CHANGED
|
@@ -4,6 +4,7 @@ import {resolve} from 'node:path';
|
|
|
4
4
|
import stubbedFs from 'mock-fs';
|
|
5
5
|
import * as td from 'testdouble';
|
|
6
6
|
import any from '@travi/any';
|
|
7
|
+
import {promptConstants} from '@form8ion/project';
|
|
7
8
|
|
|
8
9
|
// remark-usage-ignore-next 13
|
|
9
10
|
const stubbedNodeModules = stubbedFs.load(resolve('node_modules'));
|
|
@@ -21,7 +22,6 @@ td.when(execa('npm', ['whoami'])).thenResolve({stdout: any.word()});
|
|
|
21
22
|
td.when(execa('npm', ['--version'])).thenResolve({stdout: any.word()});
|
|
22
23
|
|
|
23
24
|
const {packageManagers} = await import('@form8ion/javascript-core');
|
|
24
|
-
const githubPlugin = await import('@form8ion/github');
|
|
25
25
|
const {questionNames: projectQuestionNames} = await import('@form8ion/project');
|
|
26
26
|
const javascriptPlugin = await import('@form8ion/javascript');
|
|
27
27
|
const {scaffold, extendEslintConfig} = await import('./lib/index.mjs');
|
|
@@ -47,15 +47,6 @@ stubbedFs({node_modules: stubbedNodeModules});
|
|
|
47
47
|
await extendEslintConfig(
|
|
48
48
|
{
|
|
49
49
|
decisions: {
|
|
50
|
-
[projectQuestionNames.PROJECT_NAME]: 'eslint-config-foo',
|
|
51
|
-
[projectQuestionNames.DESCRIPTION]: 'a description of the project',
|
|
52
|
-
[projectQuestionNames.VISIBILITY]: 'Public',
|
|
53
|
-
[projectQuestionNames.LICENSE]: 'MIT',
|
|
54
|
-
[projectQuestionNames.COPYRIGHT_HOLDER]: 'John Smith',
|
|
55
|
-
[projectQuestionNames.COPYRIGHT_YEAR]: '2022',
|
|
56
|
-
[projectQuestionNames.GIT_REPO]: true,
|
|
57
|
-
[projectQuestionNames.REPO_HOST]: 'GitHub',
|
|
58
|
-
[projectQuestionNames.REPO_OWNER]: 'org-name',
|
|
59
50
|
[javascriptPlugin.questionNames.AUTHOR_NAME]: 'John Smith',
|
|
60
51
|
[javascriptPlugin.questionNames.AUTHOR_EMAIL]: 'john@smith.org',
|
|
61
52
|
[javascriptPlugin.questionNames.AUTHOR_URL]: 'https://smith.org',
|
|
@@ -65,7 +56,15 @@ stubbedFs({node_modules: stubbedNodeModules});
|
|
|
65
56
|
[javascriptPlugin.questionNames.CI_SERVICE]: 'Other',
|
|
66
57
|
[javascriptPlugin.questionNames.PROVIDE_EXAMPLE]: false
|
|
67
58
|
},
|
|
68
|
-
plugins: {
|
|
59
|
+
plugins: {
|
|
60
|
+
vcsHosts: {
|
|
61
|
+
foo: {
|
|
62
|
+
scaffold: ({projectName}) => ({
|
|
63
|
+
vcs: {name: projectName, host: any.url(), owner: any.word(), ssh_url: any.url()}
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
69
68
|
},
|
|
70
69
|
decisions => ({
|
|
71
70
|
...javascriptPlugin,
|
|
@@ -75,6 +74,27 @@ stubbedFs({node_modules: stubbedNodeModules});
|
|
|
75
74
|
configs: {},
|
|
76
75
|
plugins: {unitTestFrameworks: {}}
|
|
77
76
|
})
|
|
78
|
-
})
|
|
77
|
+
}),
|
|
78
|
+
{
|
|
79
|
+
prompt: ({id}) => {
|
|
80
|
+
switch (id) {
|
|
81
|
+
case promptConstants.ids.BASE_DETAILS:
|
|
82
|
+
return {
|
|
83
|
+
[projectQuestionNames.PROJECT_NAME]: 'eslint-config-foo',
|
|
84
|
+
[projectQuestionNames.DESCRIPTION]: 'a description of the project',
|
|
85
|
+
[projectQuestionNames.VISIBILITY]: 'Public',
|
|
86
|
+
[projectQuestionNames.LICENSE]: 'MIT',
|
|
87
|
+
[projectQuestionNames.COPYRIGHT_HOLDER]: 'John Smith',
|
|
88
|
+
[projectQuestionNames.COPYRIGHT_YEAR]: '2022'
|
|
89
|
+
};
|
|
90
|
+
case promptConstants.ids.GIT_REPOSITORY:
|
|
91
|
+
return {[projectQuestionNames.GIT_REPO]: true};
|
|
92
|
+
case promptConstants.ids.REPOSITORY_HOST:
|
|
93
|
+
return {[projectQuestionNames.REPO_HOST]: 'foo'};
|
|
94
|
+
default:
|
|
95
|
+
throw new Error(`Unknown prompt: ${id}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
79
99
|
);
|
|
80
100
|
})();
|
package/lib/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { write } from '@form8ion/config-file';
|
|
|
4
4
|
import deepmerge from 'deepmerge';
|
|
5
5
|
import { questionNames as questionNames$1 } from '@form8ion/javascript';
|
|
6
6
|
import { dialects } from '@form8ion/javascript-core';
|
|
7
|
-
import { scaffold as scaffold$1
|
|
7
|
+
import { promptConstants, questionNames, scaffold as scaffold$1 } from '@form8ion/project';
|
|
8
8
|
|
|
9
9
|
async function scaffold ({projectRoot, scope, projectName}) {
|
|
10
10
|
const configShortName = projectName.substring('eslint-config-'.length);
|
|
@@ -44,19 +44,30 @@ async function scaffold ({projectRoot, scope, projectName}) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const PLUGIN_NAME = 'ESLint Config';
|
|
47
|
+
const JAVASCRIPT_LANGUAGE_CHOICE = 'JavaScript';
|
|
47
48
|
|
|
48
|
-
function
|
|
49
|
-
|
|
49
|
+
function injectLanguageChoiceIntoPrompt(prompt) {
|
|
50
|
+
return promptOptions => {
|
|
51
|
+
const {id} = promptOptions;
|
|
52
|
+
|
|
53
|
+
if (promptConstants.ids.PROJECT_LANGUAGE === id) {
|
|
54
|
+
return {[questionNames.PROJECT_LANGUAGE]: JAVASCRIPT_LANGUAGE_CHOICE};
|
|
55
|
+
}
|
|
56
|
+
return prompt(promptOptions);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function extendEslintConfig(options, javascriptPluginFactory, dependencies) {
|
|
61
|
+
const {decisions, ...otherOptions} = options;
|
|
50
62
|
|
|
51
63
|
return scaffold$1(
|
|
52
64
|
deepmerge(
|
|
53
|
-
|
|
65
|
+
otherOptions,
|
|
54
66
|
{
|
|
55
|
-
decisions: {[questionNames.PROJECT_LANGUAGE]: javaScriptLanguageChoice},
|
|
56
67
|
plugins: {
|
|
57
68
|
languages: {
|
|
58
|
-
[
|
|
59
|
-
...
|
|
69
|
+
[JAVASCRIPT_LANGUAGE_CHOICE]: javascriptPluginFactory({
|
|
70
|
+
...decisions,
|
|
60
71
|
[questionNames$1.PROJECT_TYPE]: 'Package',
|
|
61
72
|
[questionNames$1.PROJECT_TYPE_CHOICE]: PLUGIN_NAME,
|
|
62
73
|
[questionNames$1.UNIT_TESTS]: false,
|
|
@@ -68,9 +79,13 @@ function highLevel (options, javascriptPluginFactory) {
|
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
81
|
}
|
|
71
|
-
)
|
|
82
|
+
),
|
|
83
|
+
{
|
|
84
|
+
...dependencies,
|
|
85
|
+
prompt: injectLanguageChoiceIntoPrompt(dependencies.prompt)
|
|
86
|
+
}
|
|
72
87
|
);
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
export { PLUGIN_NAME,
|
|
90
|
+
export { PLUGIN_NAME, extendEslintConfig, scaffold };
|
|
76
91
|
//# sourceMappingURL=index.mjs.map
|
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/scaffold.js","../src/constants.js","../src/high-level.js"],"sourcesContent":["import {promises as fs} from 'node:fs';\nimport {fileTypes} from '@form8ion/core';\nimport {write} from '@form8ion/config-file';\n\nexport default async function ({projectRoot, scope, projectName}) {\n const configShortName = projectName.substring('eslint-config-'.length);\n\n await Promise.all([\n write({\n format: fileTypes.YAML,\n path: projectRoot,\n name: 'eslint',\n config: {root: true, extends: [`@${scope}`, '.']}\n }),\n fs.writeFile(\n `${projectRoot}/index.js`,\n `module.exports = {extends: '@form8ion/${configShortName}'};\\n`\n ),\n fs.writeFile(\n `${projectRoot}/example.js`,\n `module.exports = {\n extends: [\n '@${scope}',\n '@${scope}/${configShortName}'\n ]\n};\n`\n )\n ]);\n\n return {\n scripts: {'lint:js': 'eslint .'},\n dependencies: {javascript: {production: [`@form8ion/${projectName}`], development: [`@${scope}/eslint-config`]}},\n nextSteps: [\n {summary: 'Save the extended `@form8ion` eslint-config as an exact version'},\n {summary: 'Document saving this config using the dev flag'},\n {summary: 'Link to the extended `@form8ion` config in the README'}\n ]\n };\n}\n","export const PLUGIN_NAME = 'ESLint Config';\n","import deepmerge from 'deepmerge';\nimport {questionNames as jsQuestionNames} from '@form8ion/javascript';\nimport {dialects} from '@form8ion/javascript-core';\nimport {
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/scaffold.js","../src/constants.js","../src/language-handler-prompt.js","../src/high-level.js"],"sourcesContent":["import {promises as fs} from 'node:fs';\nimport {fileTypes} from '@form8ion/core';\nimport {write} from '@form8ion/config-file';\n\nexport default async function ({projectRoot, scope, projectName}) {\n const configShortName = projectName.substring('eslint-config-'.length);\n\n await Promise.all([\n write({\n format: fileTypes.YAML,\n path: projectRoot,\n name: 'eslint',\n config: {root: true, extends: [`@${scope}`, '.']}\n }),\n fs.writeFile(\n `${projectRoot}/index.js`,\n `module.exports = {extends: '@form8ion/${configShortName}'};\\n`\n ),\n fs.writeFile(\n `${projectRoot}/example.js`,\n `module.exports = {\n extends: [\n '@${scope}',\n '@${scope}/${configShortName}'\n ]\n};\n`\n )\n ]);\n\n return {\n scripts: {'lint:js': 'eslint .'},\n dependencies: {javascript: {production: [`@form8ion/${projectName}`], development: [`@${scope}/eslint-config`]}},\n nextSteps: [\n {summary: 'Save the extended `@form8ion` eslint-config as an exact version'},\n {summary: 'Document saving this config using the dev flag'},\n {summary: 'Link to the extended `@form8ion` config in the README'}\n ]\n };\n}\n","export const PLUGIN_NAME = 'ESLint Config';\nexport const JAVASCRIPT_LANGUAGE_CHOICE = 'JavaScript';\n","import {promptConstants, questionNames as projectQuestionNames} from '@form8ion/project';\nimport {JAVASCRIPT_LANGUAGE_CHOICE} from './constants.js';\n\nexport default function injectLanguageChoiceIntoPrompt(prompt) {\n return promptOptions => {\n const {id} = promptOptions;\n\n if (promptConstants.ids.PROJECT_LANGUAGE === id) {\n return {[projectQuestionNames.PROJECT_LANGUAGE]: JAVASCRIPT_LANGUAGE_CHOICE};\n }\n return prompt(promptOptions);\n };\n}\n","import deepmerge from 'deepmerge';\nimport {questionNames as jsQuestionNames} from '@form8ion/javascript';\nimport {dialects} from '@form8ion/javascript-core';\nimport {scaffold} from '@form8ion/project';\n\nimport {JAVASCRIPT_LANGUAGE_CHOICE, PLUGIN_NAME} from './constants.js';\nimport injectLanguageChoiceIntoPrompt from './language-handler-prompt.js';\n\nexport default function extendEslintConfig(options, javascriptPluginFactory, dependencies) {\n const {decisions, ...otherOptions} = options;\n\n return scaffold(\n deepmerge(\n otherOptions,\n {\n plugins: {\n languages: {\n [JAVASCRIPT_LANGUAGE_CHOICE]: javascriptPluginFactory({\n ...decisions,\n [jsQuestionNames.PROJECT_TYPE]: 'Package',\n [jsQuestionNames.PROJECT_TYPE_CHOICE]: PLUGIN_NAME,\n [jsQuestionNames.UNIT_TESTS]: false,\n [jsQuestionNames.INTEGRATION_TESTS]: false,\n [jsQuestionNames.CONFIGURE_LINTING]: false,\n [jsQuestionNames.DIALECT]: dialects.COMMON_JS,\n [jsQuestionNames.SHOULD_BE_SCOPED]: true\n })\n }\n }\n }\n ),\n {\n ...dependencies,\n prompt: injectLanguageChoiceIntoPrompt(dependencies.prompt)\n }\n );\n}\n"],"names":["fs","projectQuestionNames","scaffold","jsQuestionNames"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"name": "@form8ion/eslint-config-extender",
|
|
3
3
|
"description": "shareable ESLint config scaffolder for extending another config",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "11.0.0-beta.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": "^
|
|
8
|
+
"node": "^20.19.0 || >=22.14.0"
|
|
9
9
|
},
|
|
10
10
|
"author": "Matt Travi <npm@travi.org> (https://matt.travi.org)",
|
|
11
11
|
"repository": "form8ion/eslint-config-extender",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"main": "lib/index.mjs",
|
|
17
17
|
"sideEffects": false,
|
|
18
18
|
"scripts": {
|
|
19
|
-
"
|
|
19
|
+
"pretest": "run-s build",
|
|
20
|
+
"test": "npm-run-all --print-label --parallel lint:* --parallel test:*",
|
|
20
21
|
"lint:lockfile": "lockfile-lint",
|
|
21
22
|
"lint:js": "eslint . --cache",
|
|
22
23
|
"lint:md": "remark . --frail",
|
|
@@ -47,52 +48,54 @@
|
|
|
47
48
|
},
|
|
48
49
|
"files": [
|
|
49
50
|
"example.js",
|
|
50
|
-
"lib/"
|
|
51
|
+
"lib/",
|
|
52
|
+
"src/"
|
|
51
53
|
],
|
|
52
54
|
"publishConfig": {
|
|
53
55
|
"access": "public",
|
|
54
56
|
"provenance": true
|
|
55
57
|
},
|
|
56
|
-
"packageManager": "npm@11.
|
|
58
|
+
"packageManager": "npm@11.6.2+sha512.ee22b335fcbc95662cdf3ab8a053daf045d9cf9c6df6040d28965abb707512b2c16fa6c5eec049d34c74f78f390cebd14f697919eadb97756564d4f9eccc4954",
|
|
57
59
|
"dependencies": {
|
|
58
60
|
"@form8ion/config-file": "^1.1.2",
|
|
59
61
|
"@form8ion/core": "^4.7.1",
|
|
60
62
|
"@form8ion/javascript": "^14.0.0-beta.1",
|
|
61
63
|
"@form8ion/javascript-core": "^12.0.0",
|
|
62
|
-
"@form8ion/project": "^
|
|
64
|
+
"@form8ion/project": "^22.0.0-beta.8",
|
|
63
65
|
"deepmerge": "^4.2.2"
|
|
64
66
|
},
|
|
65
67
|
"devDependencies": {
|
|
66
|
-
"@cucumber/cucumber": "11.
|
|
67
|
-
"@form8ion/commitlint-config": "2.0.
|
|
68
|
-
"@form8ion/eslint-config": "7.0.
|
|
68
|
+
"@cucumber/cucumber": "11.3.0",
|
|
69
|
+
"@form8ion/commitlint-config": "2.0.8",
|
|
70
|
+
"@form8ion/eslint-config": "7.0.13",
|
|
69
71
|
"@form8ion/eslint-config-cucumber": "1.4.1",
|
|
70
|
-
"@form8ion/
|
|
71
|
-
"@form8ion/remark-lint-preset": "6.0.
|
|
72
|
-
"@travi/any": "3.1.
|
|
73
|
-
"ban-sensitive-files": "1.10.
|
|
72
|
+
"@form8ion/eslint-config-vitest": "1.0.0",
|
|
73
|
+
"@form8ion/remark-lint-preset": "6.0.7",
|
|
74
|
+
"@travi/any": "3.1.3",
|
|
75
|
+
"ban-sensitive-files": "1.10.11",
|
|
74
76
|
"c8": "10.1.3",
|
|
75
|
-
"chai": "
|
|
76
|
-
"cross-env": "
|
|
77
|
+
"chai": "6.2.0",
|
|
78
|
+
"cross-env": "10.1.0",
|
|
77
79
|
"cz-conventional-changelog": "3.3.0",
|
|
78
|
-
"debug": "4.4.
|
|
80
|
+
"debug": "4.4.3",
|
|
79
81
|
"gherkin-lint": "4.2.4",
|
|
80
82
|
"husky": "9.1.7",
|
|
81
|
-
"jest-when": "3.7.0",
|
|
82
83
|
"js-yaml": "4.1.0",
|
|
83
|
-
"lockfile-lint": "4.14.
|
|
84
|
+
"lockfile-lint": "4.14.1",
|
|
84
85
|
"ls-engines": "0.9.3",
|
|
85
|
-
"mock-fs": "5.
|
|
86
|
-
"nock": "14.0.
|
|
87
|
-
"npm-run-all2": "
|
|
88
|
-
"publint": "0.3.
|
|
86
|
+
"mock-fs": "5.5.0",
|
|
87
|
+
"nock": "14.0.10",
|
|
88
|
+
"npm-run-all2": "8.0.4",
|
|
89
|
+
"publint": "0.3.15",
|
|
89
90
|
"remark-cli": "12.0.1",
|
|
90
91
|
"remark-toc": "9.0.0",
|
|
91
92
|
"remark-usage": "11.0.1",
|
|
92
93
|
"rimraf": "6.0.1",
|
|
93
|
-
"rollup": "4.
|
|
94
|
+
"rollup": "4.52.5",
|
|
94
95
|
"rollup-plugin-auto-external": "2.0.0",
|
|
96
|
+
"simple-git": "3.28.0",
|
|
95
97
|
"testdouble": "3.20.2",
|
|
96
|
-
"vitest": "
|
|
98
|
+
"vitest": "4.0.4",
|
|
99
|
+
"vitest-when": "0.9.0"
|
|
97
100
|
}
|
|
98
101
|
}
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import deepmerge from 'deepmerge';
|
|
2
|
+
import {questionNames as jsQuestionNames} from '@form8ion/javascript';
|
|
3
|
+
import {dialects} from '@form8ion/javascript-core';
|
|
4
|
+
import {scaffold} from '@form8ion/project';
|
|
5
|
+
|
|
6
|
+
import {JAVASCRIPT_LANGUAGE_CHOICE, PLUGIN_NAME} from './constants.js';
|
|
7
|
+
import injectLanguageChoiceIntoPrompt from './language-handler-prompt.js';
|
|
8
|
+
|
|
9
|
+
export default function extendEslintConfig(options, javascriptPluginFactory, dependencies) {
|
|
10
|
+
const {decisions, ...otherOptions} = options;
|
|
11
|
+
|
|
12
|
+
return scaffold(
|
|
13
|
+
deepmerge(
|
|
14
|
+
otherOptions,
|
|
15
|
+
{
|
|
16
|
+
plugins: {
|
|
17
|
+
languages: {
|
|
18
|
+
[JAVASCRIPT_LANGUAGE_CHOICE]: javascriptPluginFactory({
|
|
19
|
+
...decisions,
|
|
20
|
+
[jsQuestionNames.PROJECT_TYPE]: 'Package',
|
|
21
|
+
[jsQuestionNames.PROJECT_TYPE_CHOICE]: PLUGIN_NAME,
|
|
22
|
+
[jsQuestionNames.UNIT_TESTS]: false,
|
|
23
|
+
[jsQuestionNames.INTEGRATION_TESTS]: false,
|
|
24
|
+
[jsQuestionNames.CONFIGURE_LINTING]: false,
|
|
25
|
+
[jsQuestionNames.DIALECT]: dialects.COMMON_JS,
|
|
26
|
+
[jsQuestionNames.SHOULD_BE_SCOPED]: true
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
{
|
|
33
|
+
...dependencies,
|
|
34
|
+
prompt: injectLanguageChoiceIntoPrompt(dependencies.prompt)
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as projectScaffolder from '@form8ion/project';
|
|
2
|
+
import * as javascriptScaffolder from '@form8ion/javascript';
|
|
3
|
+
import {dialects} from '@form8ion/javascript-core';
|
|
4
|
+
|
|
5
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
6
|
+
import any from '@travi/any';
|
|
7
|
+
import {when} from 'vitest-when';
|
|
8
|
+
|
|
9
|
+
import {JAVASCRIPT_LANGUAGE_CHOICE, PLUGIN_NAME} from './constants.js';
|
|
10
|
+
import injectLanguageChoiceIntoPrompt from './language-handler-prompt.js';
|
|
11
|
+
import extendEslintConfig from './high-level.js';
|
|
12
|
+
|
|
13
|
+
vi.mock('@form8ion/project');
|
|
14
|
+
vi.mock('./language-handler-prompt.js');
|
|
15
|
+
|
|
16
|
+
describe('high-level scaffolder', () => {
|
|
17
|
+
it('should execute the project-scaffolder', async () => {
|
|
18
|
+
const prompt = () => undefined;
|
|
19
|
+
const enhancedPrompt = () => undefined;
|
|
20
|
+
const dependencies = {...any.simpleObject(), prompt};
|
|
21
|
+
const providedDecisions = any.simpleObject();
|
|
22
|
+
const optionsWithoutDecisions = any.simpleObject();
|
|
23
|
+
const options = {...optionsWithoutDecisions, decisions: providedDecisions};
|
|
24
|
+
const jsPlugin = {scaffold: any.simpleObject()};
|
|
25
|
+
const javascriptPluginFactory = vi.fn();
|
|
26
|
+
when(javascriptPluginFactory).calledWith({
|
|
27
|
+
...providedDecisions,
|
|
28
|
+
[javascriptScaffolder.questionNames.PROJECT_TYPE]: 'Package',
|
|
29
|
+
[javascriptScaffolder.questionNames.PROJECT_TYPE_CHOICE]: PLUGIN_NAME,
|
|
30
|
+
[javascriptScaffolder.questionNames.UNIT_TESTS]: false,
|
|
31
|
+
[javascriptScaffolder.questionNames.INTEGRATION_TESTS]: false,
|
|
32
|
+
[javascriptScaffolder.questionNames.CONFIGURE_LINTING]: false,
|
|
33
|
+
[javascriptScaffolder.questionNames.DIALECT]: dialects.COMMON_JS,
|
|
34
|
+
[javascriptScaffolder.questionNames.SHOULD_BE_SCOPED]: true
|
|
35
|
+
}).thenReturn(jsPlugin);
|
|
36
|
+
when(injectLanguageChoiceIntoPrompt).calledWith(prompt).thenReturn(enhancedPrompt);
|
|
37
|
+
|
|
38
|
+
await extendEslintConfig(options, javascriptPluginFactory, dependencies);
|
|
39
|
+
|
|
40
|
+
expect(projectScaffolder.scaffold).toHaveBeenCalledWith(
|
|
41
|
+
{
|
|
42
|
+
...optionsWithoutDecisions,
|
|
43
|
+
plugins: {languages: {[JAVASCRIPT_LANGUAGE_CHOICE]: jsPlugin}}
|
|
44
|
+
},
|
|
45
|
+
{...dependencies, prompt: enhancedPrompt}
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
});
|
package/src/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {promptConstants, questionNames as projectQuestionNames} from '@form8ion/project';
|
|
2
|
+
import {JAVASCRIPT_LANGUAGE_CHOICE} from './constants.js';
|
|
3
|
+
|
|
4
|
+
export default function injectLanguageChoiceIntoPrompt(prompt) {
|
|
5
|
+
return promptOptions => {
|
|
6
|
+
const {id} = promptOptions;
|
|
7
|
+
|
|
8
|
+
if (promptConstants.ids.PROJECT_LANGUAGE === id) {
|
|
9
|
+
return {[projectQuestionNames.PROJECT_LANGUAGE]: JAVASCRIPT_LANGUAGE_CHOICE};
|
|
10
|
+
}
|
|
11
|
+
return prompt(promptOptions);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {promptConstants, questionNames as projectQuestionNames} from '@form8ion/project';
|
|
2
|
+
|
|
3
|
+
import {describe, it, vi, expect} from 'vitest';
|
|
4
|
+
import {when} from 'vitest-when';
|
|
5
|
+
import any from '@travi/any';
|
|
6
|
+
|
|
7
|
+
import injectLanguageChoiceIntoPrompt from './language-handler-prompt.js';
|
|
8
|
+
import {JAVASCRIPT_LANGUAGE_CHOICE} from './constants.js';
|
|
9
|
+
|
|
10
|
+
describe('language choice handler prompt', () => {
|
|
11
|
+
it('should call the provided prompt handler for other prompts', async () => {
|
|
12
|
+
const promptOptions = {...any.simpleObject(), id: any.word()};
|
|
13
|
+
const prompt = vi.fn();
|
|
14
|
+
const answers = any.simpleObject();
|
|
15
|
+
when(prompt).calledWith(promptOptions).thenResolve(answers);
|
|
16
|
+
|
|
17
|
+
expect(await injectLanguageChoiceIntoPrompt(prompt)(promptOptions)).toEqual(answers);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should define the language choice as JavaScript for the language handler prompt', async () => {
|
|
21
|
+
expect(await injectLanguageChoiceIntoPrompt(() => undefined)({
|
|
22
|
+
...any.simpleObject(),
|
|
23
|
+
id: promptConstants.ids.PROJECT_LANGUAGE
|
|
24
|
+
})).toEqual({[projectQuestionNames.PROJECT_LANGUAGE]: JAVASCRIPT_LANGUAGE_CHOICE});
|
|
25
|
+
});
|
|
26
|
+
});
|
package/src/scaffold.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import {fileTypes} from '@form8ion/core';
|
|
3
|
+
import {write} from '@form8ion/config-file';
|
|
4
|
+
|
|
5
|
+
export default async function ({projectRoot, scope, projectName}) {
|
|
6
|
+
const configShortName = projectName.substring('eslint-config-'.length);
|
|
7
|
+
|
|
8
|
+
await Promise.all([
|
|
9
|
+
write({
|
|
10
|
+
format: fileTypes.YAML,
|
|
11
|
+
path: projectRoot,
|
|
12
|
+
name: 'eslint',
|
|
13
|
+
config: {root: true, extends: [`@${scope}`, '.']}
|
|
14
|
+
}),
|
|
15
|
+
fs.writeFile(
|
|
16
|
+
`${projectRoot}/index.js`,
|
|
17
|
+
`module.exports = {extends: '@form8ion/${configShortName}'};\n`
|
|
18
|
+
),
|
|
19
|
+
fs.writeFile(
|
|
20
|
+
`${projectRoot}/example.js`,
|
|
21
|
+
`module.exports = {
|
|
22
|
+
extends: [
|
|
23
|
+
'@${scope}',
|
|
24
|
+
'@${scope}/${configShortName}'
|
|
25
|
+
]
|
|
26
|
+
};
|
|
27
|
+
`
|
|
28
|
+
)
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
scripts: {'lint:js': 'eslint .'},
|
|
33
|
+
dependencies: {javascript: {production: [`@form8ion/${projectName}`], development: [`@${scope}/eslint-config`]}},
|
|
34
|
+
nextSteps: [
|
|
35
|
+
{summary: 'Save the extended `@form8ion` eslint-config as an exact version'},
|
|
36
|
+
{summary: 'Document saving this config using the dev flag'},
|
|
37
|
+
{summary: 'Link to the extended `@form8ion` config in the README'}
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {promises as fs} from 'node:fs';
|
|
2
|
+
import {fileTypes} from '@form8ion/core';
|
|
3
|
+
import {write} from '@form8ion/config-file';
|
|
4
|
+
|
|
5
|
+
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
|
6
|
+
import any from '@travi/any';
|
|
7
|
+
|
|
8
|
+
import scaffold from './scaffold.js';
|
|
9
|
+
|
|
10
|
+
describe('scaffold', () => {
|
|
11
|
+
const projectRoot = any.string();
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.mock('node:fs');
|
|
15
|
+
vi.mock('@form8ion/config-file');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
vi.clearAllMocks();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should extend the chosen form8ion config', async () => {
|
|
23
|
+
const scope = any.word();
|
|
24
|
+
const configShortName = any.word();
|
|
25
|
+
const projectName = `eslint-config-${configShortName}`;
|
|
26
|
+
|
|
27
|
+
const {scripts, dependencies, nextSteps} = await scaffold({projectRoot, projectName, scope});
|
|
28
|
+
|
|
29
|
+
expect(write).toHaveBeenCalledWith({
|
|
30
|
+
path: projectRoot,
|
|
31
|
+
format: fileTypes.YAML,
|
|
32
|
+
name: 'eslint',
|
|
33
|
+
config: {root: true, extends: [`@${scope}`, '.']}
|
|
34
|
+
});
|
|
35
|
+
expect(fs.writeFile).toHaveBeenCalledWith(
|
|
36
|
+
`${projectRoot}/index.js`,
|
|
37
|
+
`module.exports = {extends: '@form8ion/${configShortName}'};\n`
|
|
38
|
+
);
|
|
39
|
+
expect(fs.writeFile).toHaveBeenCalledWith(
|
|
40
|
+
`${projectRoot}/example.js`,
|
|
41
|
+
`module.exports = {
|
|
42
|
+
extends: [
|
|
43
|
+
'@${scope}',
|
|
44
|
+
'@${scope}/${configShortName}'
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
`
|
|
48
|
+
);
|
|
49
|
+
expect(scripts).toEqual({'lint:js': 'eslint .'});
|
|
50
|
+
expect(dependencies.javascript.production).toEqual([`@form8ion/${projectName}`]);
|
|
51
|
+
expect(dependencies.javascript.development).toEqual([`@${scope}/eslint-config`]);
|
|
52
|
+
expect(nextSteps).toEqual([
|
|
53
|
+
{summary: 'Save the extended `@form8ion` eslint-config as an exact version'},
|
|
54
|
+
{summary: 'Document saving this config using the dev flag'},
|
|
55
|
+
{summary: 'Link to the extended `@form8ion` config in the README'}
|
|
56
|
+
]);
|
|
57
|
+
});
|
|
58
|
+
});
|