markuplint 3.0.0-dev.54 → 3.0.0-dev.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,6 +121,7 @@ Need [Sponsors❤️‍🔥](https://github.com/sponsors/markuplint)
121
121
 
122
122
  [<img width="36" src="https://avatars.githubusercontent.com/u/91733847" alt="Tokitake" />](https://github.com/Tokitake)
123
123
  [<img width="36" src="https://avatars.githubusercontent.com/u/1996642" alt="yamanoku" />](https://github.com/yamanoku)
124
+ [<img width="36" src="https://avatars.githubusercontent.com/u/6581173" alt="miita" />](https://github.com/mikimhk)
124
125
 
125
126
  ## Thanks
126
127
 
@@ -0,0 +1,4 @@
1
+ import type { DefaultRules, Langs, RuleSettingMode } from './types';
2
+ import type { Config } from '@markuplint/ml-config';
3
+ export declare const langs: Record<Langs, string>;
4
+ export declare function createConfig(langs: Langs[], mode: RuleSettingMode, defaultRules: DefaultRules): Config;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createConfig = exports.langs = void 0;
4
+ const ml_config_1 = require("@markuplint/ml-config");
5
+ const extRExp = {
6
+ jsx: '\\.[jt]sx?$',
7
+ vue: '\\.vue$',
8
+ svelte: '\\.svelte$',
9
+ astro: '\\.astro$',
10
+ pug: '\\.pug$',
11
+ php: '\\.php$',
12
+ smarty: '\\.tpl$',
13
+ erb: '\\.erb$',
14
+ ejs: '\\.ejs$',
15
+ mustache: '\\.(mustache|hbs)$',
16
+ nunjucks: '\\.nunjucks$',
17
+ liquid: '\\.liquid$',
18
+ };
19
+ exports.langs = {
20
+ jsx: 'React (JSX)',
21
+ vue: 'Vue',
22
+ svelte: 'Svelte',
23
+ astro: 'Astro',
24
+ pug: 'Pug',
25
+ php: 'PHP',
26
+ smarty: 'Smarty',
27
+ erb: 'eRuby',
28
+ ejs: 'EJS',
29
+ mustache: 'Mustache/Handlebars',
30
+ nunjucks: 'Nunjucks',
31
+ liquid: 'liquid (Shopify)',
32
+ };
33
+ function createConfig(langs, mode, defaultRules) {
34
+ let config = {};
35
+ for (const lang of langs) {
36
+ config.parser = config.parser || {};
37
+ const ext = extRExp[lang];
38
+ if (!ext) {
39
+ continue;
40
+ }
41
+ config.parser[ext] = `@markuplint/${lang}-parser`;
42
+ if (lang === 'vue') {
43
+ config = (0, ml_config_1.mergeConfig)(config, {
44
+ specs: {
45
+ '\\.vue$': '@markuplint/vue-spec',
46
+ },
47
+ });
48
+ }
49
+ if (lang === 'jsx') {
50
+ config = (0, ml_config_1.mergeConfig)(config, {
51
+ specs: {
52
+ '\\.[jt]sx?$': '@markuplint/react-spec',
53
+ },
54
+ });
55
+ }
56
+ }
57
+ if (Array.isArray(mode)) {
58
+ const ruleNames = Object.keys(defaultRules);
59
+ for (const ruleName of ruleNames) {
60
+ const rule = defaultRules[ruleName];
61
+ if (!rule) {
62
+ continue;
63
+ }
64
+ if (mode.includes(rule.category)) {
65
+ if (!config.rules) {
66
+ config.rules = {};
67
+ }
68
+ config.rules[ruleName] = rule.defaultValue;
69
+ }
70
+ }
71
+ }
72
+ else if (mode === 'recommended') {
73
+ config.extends = [...(config.extends || []), 'markuplint:recommended'];
74
+ }
75
+ else {
76
+ config.rules = {};
77
+ const ruleNames = Object.keys(defaultRules);
78
+ for (const ruleName of ruleNames) {
79
+ const rule = defaultRules[ruleName];
80
+ config.rules[ruleName] = rule.defaultValue;
81
+ }
82
+ }
83
+ return config;
84
+ }
85
+ exports.createConfig = createConfig;
@@ -0,0 +1,2 @@
1
+ import type { DefaultRules } from './types';
2
+ export declare function getDefaultRules(version: string): Promise<DefaultRules>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDefaultRules = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const gray_matter_1 = tslib_1.__importDefault(require("gray-matter"));
6
+ const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
7
+ const RULES_SCHEMA_URL = 'https://raw.githubusercontent.com/markuplint/markuplint/[VERSION]/packages/@markuplint/rules/schema.json';
8
+ const RULES_README_URL = 'https://raw.githubusercontent.com/markuplint/markuplint/[VERSION]/packages/@markuplint/rules/src/[NAME]/README.md';
9
+ async function getDefaultRules(version) {
10
+ const json = await safeFetch(RULES_SCHEMA_URL, version);
11
+ const rules = {};
12
+ await Promise.all(Object.entries(json.definitions.rules.properties).map(async ([name, rule]) => {
13
+ var _a, _b, _c, _d;
14
+ const json = await safeFetch(rule.$ref.replace('/main/', '/[VERSION]/'), version);
15
+ let severity = (_c = (_b = (_a = (Array.isArray(json.oneOf) ? json.oneOf : []).find((val) => val.properties)) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.severity) === null || _c === void 0 ? void 0 : _c.default;
16
+ let category = json._category;
17
+ if (severity == null || category == null) {
18
+ const data = await getCatAndSeverityFromLegacy(version, name);
19
+ severity = data.severity;
20
+ category = data.category;
21
+ }
22
+ const defaultValue = severity === 'warning' ? false : (_d = json.definitions.value.default) !== null && _d !== void 0 ? _d : true;
23
+ rules[name] = {
24
+ defaultValue,
25
+ category,
26
+ };
27
+ }));
28
+ return rules;
29
+ }
30
+ exports.getDefaultRules = getDefaultRules;
31
+ async function safeFetch(baseUrl, version, type = 'json') {
32
+ const url = baseUrl.replace('[VERSION]', `v${version}`);
33
+ const res = await (0, node_fetch_1.default)(url);
34
+ if (!res.ok) {
35
+ return safeFetch(baseUrl, '3.0.0', type);
36
+ }
37
+ if (type === 'json') {
38
+ return (await res.json());
39
+ }
40
+ const md = await res.text();
41
+ const { data } = (0, gray_matter_1.default)(md);
42
+ return data;
43
+ }
44
+ /**
45
+ * Fallback fetching until 3.0.x
46
+ *
47
+ * @param version
48
+ * @param name
49
+ * @returns
50
+ */
51
+ async function getCatAndSeverityFromLegacy(version, name) {
52
+ const data = await safeFetch(RULES_README_URL.replace('[NAME]', name), version, 'md');
53
+ return {
54
+ category: data.category,
55
+ severity: data.severity,
56
+ };
57
+ }
@@ -5,9 +5,10 @@ const tslib_1 = require("tslib");
5
5
  const fs_1 = tslib_1.__importDefault(require("fs"));
6
6
  const path_1 = tslib_1.__importDefault(require("path"));
7
7
  const util_1 = tslib_1.__importDefault(require("util"));
8
- const ml_config_1 = require("@markuplint/ml-config");
9
8
  const util_2 = require("../../util");
10
9
  const prompt_1 = require("../prompt");
10
+ const create_config_1 = require("./create-config");
11
+ const get_default_rules_1 = require("./get-default-rules");
11
12
  const install_module_1 = require("./install-module");
12
13
  const writeFile = util_1.default.promisify(fs_1.default.writeFile);
13
14
  const ruleCategories = {
@@ -15,242 +16,57 @@ const ruleCategories = {
15
16
  message: 'Are you going to conformance check according to HTML standard?',
16
17
  },
17
18
  a11y: {
18
- message: 'Are you going to do with accessibility better practices?',
19
+ message: 'Do you want high accessibility?',
19
20
  },
20
21
  'naming-convention': {
21
22
  message: 'Are you going to set the convention about naming?',
22
23
  },
24
+ maintainability: {
25
+ message: 'Do you want high maintainability?',
26
+ },
23
27
  style: {
24
28
  message: 'Are you going to check for the code styles?',
25
29
  },
26
30
  };
27
- const defaultRules = {
28
- 'attr-duplication': {
29
- category: 'validation',
30
- default: true,
31
- },
32
- 'attr-value-quotes': {
33
- category: 'style',
34
- default: true,
35
- },
36
- 'case-sensitive-attr-name': {
37
- category: 'style',
38
- default: true,
39
- },
40
- 'case-sensitive-attr-value': {
41
- category: 'style',
42
- default: true,
43
- },
44
- 'case-sensitive-tag-name': {
45
- category: 'style',
46
- default: true,
47
- },
48
- 'character-reference': {
49
- category: 'style',
50
- default: true,
51
- },
52
- 'class-naming': {
53
- category: 'naming-convention',
54
- default: false,
55
- recommendedValue: '/.+/',
56
- },
57
- 'deprecated-attr': {
58
- category: 'validation',
59
- default: true,
60
- },
61
- 'deprecated-element': {
62
- category: 'validation',
63
- default: true,
64
- },
65
- 'disallowed-element': {
66
- category: 'validation',
67
- default: false,
68
- },
69
- doctype: {
70
- category: 'validation',
71
- default: true,
72
- },
73
- 'end-tag': {
74
- category: 'style',
75
- default: true,
76
- },
77
- 'id-duplication': {
78
- category: 'validation',
79
- default: true,
80
- },
81
- 'ineffective-attr': {
82
- category: 'validation',
83
- default: true,
84
- },
85
- 'invalid-attr': {
86
- category: 'validation',
87
- default: true,
88
- },
89
- 'label-has-control': {
90
- category: 'a11y',
91
- default: false,
92
- },
93
- 'landmark-roles': {
94
- category: 'a11y',
95
- default: true,
96
- },
97
- 'no-boolean-attr-value': {
98
- category: 'style',
99
- default: true,
100
- },
101
- 'no-default-value': {
102
- category: 'style',
103
- default: true,
104
- },
105
- 'no-empty-palpable-content': {
106
- category: 'validation',
107
- default: false,
108
- },
109
- 'no-hard-code-id': {
110
- category: 'style',
111
- default: true,
112
- },
113
- 'no-refer-to-non-existent-id': {
114
- category: 'a11y',
115
- default: true,
116
- },
117
- 'no-use-event-handler-attr': {
118
- category: 'style',
119
- default: true,
120
- },
121
- 'permitted-contents': {
122
- category: 'validation',
123
- default: true,
124
- },
125
- 'required-attr': {
126
- category: 'validation',
127
- default: true,
128
- },
129
- 'required-element': {
130
- category: 'validation',
131
- default: true,
132
- },
133
- 'required-h1': {
134
- category: 'a11y',
135
- default: true,
136
- },
137
- 'use-list': {
138
- category: 'a11y',
139
- default: false,
140
- },
141
- 'wai-aria': {
142
- category: 'a11y',
143
- default: true,
144
- },
145
- };
146
- const extRExp = {
147
- jsx: '\\.[jt]sx?$',
148
- vue: '\\.vue$',
149
- svelte: '\\.svelte$',
150
- astro: '\\.astro',
151
- pug: '\\.pug$',
152
- php: '\\.php$',
153
- erb: '\\.erb$',
154
- ejs: '\\.ejs$',
155
- mustache: '\\.(mustache|handlebars)$',
156
- nunjucks: '\\.nunjucks$',
157
- liquid: '\\.liquid$',
158
- };
159
31
  async function initialize() {
160
- let config = {};
161
32
  (0, util_2.write)((0, util_2.head)('Initialization'));
162
33
  util_2.write.break();
163
- const langs = await (0, prompt_1.multiSelect)({
34
+ const selectedLangs = await (0, prompt_1.multiSelect)({
164
35
  message: 'Which do you use template engines?',
165
- choices: [
166
- { name: 'React (JSX)', value: 'jsx' },
167
- { name: 'Vue', value: 'vue' },
168
- { name: 'Svelte', value: 'svelte' },
169
- { name: 'Astro', value: 'astro' },
170
- { name: 'Pug', value: 'pug' },
171
- { name: 'PHP', value: 'php' },
172
- { name: 'Smarty', value: 'smarty' },
173
- { name: 'eRuby', value: 'erb' },
174
- { name: 'EJS', value: 'ejs' },
175
- { name: 'Mustache/Handlebars', value: 'mustache' },
176
- { name: 'Nunjucks', value: 'nunjucks' },
177
- { name: 'liquid (Shopify)', value: 'liquid' },
178
- ],
36
+ choices: Object.entries(create_config_1.langs).map(([key, name]) => ({ name, value: key })),
179
37
  });
180
38
  const autoInstall = await (0, prompt_1.confirm)('May I install them automatically?');
181
39
  const customize = await (0, prompt_1.confirm)('Do you customize rules?');
182
- for (const lang of langs) {
183
- config.parser = config.parser || {};
184
- // @ts-ignore
185
- const ext = extRExp[lang];
186
- if (!ext) {
187
- continue;
188
- }
189
- config.parser[ext] = `@markuplint/${lang}-parser`;
190
- if (lang === 'vue') {
191
- config = (0, ml_config_1.mergeConfig)(config, {
192
- specs: {
193
- '\\.vue$': '@markuplint/vue-spec',
194
- },
195
- });
196
- }
197
- if (lang === 'jsx') {
198
- config = (0, ml_config_1.mergeConfig)(config, {
199
- specs: {
200
- '\\.[jt]sx?$': '@markuplint/react-spec',
201
- },
202
- });
203
- }
204
- }
40
+ let ruleSettingMode = 'none';
205
41
  if (customize) {
206
- const ruleNames = Object.keys(defaultRules);
207
42
  const categories = Object.keys(ruleCategories);
208
- const res = await (0, prompt_1.confirmSequence)(categories.map(catName => {
43
+ const selectedCategories = await (0, prompt_1.confirmSequence)(categories.map(catName => {
209
44
  const cat = ruleCategories[catName];
210
45
  return {
211
46
  message: cat.message,
212
47
  name: catName,
213
48
  };
214
49
  }));
215
- for (const ruleName of ruleNames) {
216
- const rule = defaultRules[ruleName];
217
- if (!rule) {
218
- continue;
219
- }
220
- if (res[rule.category]) {
221
- if (!config.rules) {
222
- config.rules = {};
223
- }
224
- config.rules[ruleName] = rule.recommendedValue || true;
225
- }
226
- }
50
+ ruleSettingMode = Object.entries(selectedCategories)
51
+ .map(([name, enabled]) => (enabled ? name : ''))
52
+ .filter((name) => !!name);
227
53
  }
228
- else {
229
- const recommended = await (0, prompt_1.confirm)('Does it import the recommended config?');
230
- if (recommended) {
231
- config.extends = [...(config.extends || []), 'markuplint:recommended'];
232
- }
233
- else {
234
- config.rules = {};
235
- const ruleNames = Object.keys(defaultRules);
236
- for (const ruleName of ruleNames) {
237
- const rule = defaultRules[ruleName];
238
- config.rules[ruleName] = rule.default;
239
- }
240
- }
54
+ else if (await (0, prompt_1.confirm)('Does it import the recommended config?')) {
55
+ ruleSettingMode = 'recommended';
56
+ }
57
+ let defaultRules = {};
58
+ if (ruleSettingMode !== 'recommended') {
59
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
60
+ const rulesVersion = require('../../../package.json').version;
61
+ defaultRules = await (0, get_default_rules_1.getDefaultRules)(rulesVersion);
241
62
  }
63
+ const config = (0, create_config_1.createConfig)(selectedLangs, ruleSettingMode, defaultRules);
242
64
  const filePath = path_1.default.resolve(process.cwd(), '.markuplintrc');
243
65
  await writeFile(filePath, JSON.stringify(config, null, 2), { encoding: 'utf-8' });
244
66
  (0, util_2.write)(`✨Created: ${filePath}`);
245
67
  if (autoInstall) {
246
68
  (0, util_2.write)('Install automatically');
247
- const modules = ['markuplint', ...langs.map(lang => `@markuplint/${lang}-parser`)];
248
- if (langs.includes('vue')) {
249
- modules.push('@markuplint/vue-spec');
250
- }
251
- if (langs.includes('jsx')) {
252
- modules.push('@markuplint/react-spec');
253
- }
69
+ const modules = (0, install_module_1.selectModules)(selectedLangs);
254
70
  const result = await (0, install_module_1.installModule)(modules, true).catch(e => new Error(e));
255
71
  if (result instanceof Error) {
256
72
  util_2.error.exit();
@@ -1,5 +1,7 @@
1
+ import type { Langs } from './types';
1
2
  export type InstallModuleResult = {
2
3
  success: boolean;
3
4
  alreadyExists: boolean;
4
5
  };
6
+ export declare function selectModules(selectedLangs: Langs[]): string[];
5
7
  export declare function installModule(module: string[], dev?: boolean): Promise<InstallModuleResult>;
@@ -1,12 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.installModule = void 0;
3
+ exports.installModule = exports.selectModules = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const child_process_1 = require("child_process");
6
6
  const cli_color_1 = tslib_1.__importDefault(require("cli-color"));
7
7
  // @ts-ignore
8
8
  const detect_installed_1 = tslib_1.__importDefault(require("detect-installed"));
9
9
  const has_yarn_1 = tslib_1.__importDefault(require("has-yarn"));
10
+ function selectModules(selectedLangs) {
11
+ const modules = ['markuplint', ...selectedLangs.map(lang => `@markuplint/${lang}-parser`)];
12
+ if (selectedLangs.includes('vue')) {
13
+ modules.push('@markuplint/vue-spec');
14
+ }
15
+ if (selectedLangs.includes('jsx')) {
16
+ modules.push('@markuplint/react-spec');
17
+ }
18
+ return modules;
19
+ }
20
+ exports.selectModules = selectModules;
10
21
  async function installModule(module, dev = false) {
11
22
  module = module.map(m => m.trim());
12
23
  const uninstallMods = [];
@@ -0,0 +1,8 @@
1
+ export type Langs = 'jsx' | 'vue' | 'svelte' | 'astro' | 'pug' | 'php' | 'smarty' | 'erb' | 'ejs' | 'mustache' | 'nunjucks' | 'liquid';
2
+ export type Category = 'validation' | 'a11y' | 'naming-convention' | 'style' | 'maintainability';
3
+ export type RuleSettingMode = Category[] | 'recommended' | 'none';
4
+ export type DefaultRules = Record<string, Rule>;
5
+ export type Rule = {
6
+ category: Category;
7
+ defaultValue: boolean | string | number;
8
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/i18n.js CHANGED
@@ -14,12 +14,13 @@ async function getLocale() {
14
14
  async function i18n(locale) {
15
15
  locale = locale || (await getLocale()) || 'en';
16
16
  const langCode = locale.split('-')[0];
17
- const localeSet = langCode
18
- ? await (_a = `@markuplint/i18n/locales/${langCode}`, Promise.resolve().then(() => tslib_1.__importStar(require(_a)))).catch(() => null)
19
- : null;
17
+ const loadLocaleSet = await (_a = `@markuplint/i18n/locales/${langCode}`, Promise.resolve().then(() => tslib_1.__importStar(require(_a)))).catch(() => null);
18
+ const localeSet = loadLocaleSet ||
19
+ // @ts-ignore
20
+ (await Promise.resolve().then(() => tslib_1.__importStar(require('@markuplint/i18n/locales/en'))));
20
21
  return {
21
- locale: langCode,
22
22
  ...localeSet,
23
+ locale: loadLocaleSet ? langCode : 'en',
23
24
  };
24
25
  }
25
26
  exports.i18n = i18n;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markuplint",
3
- "version": "3.0.0-dev.54+329808d5",
3
+ "version": "3.0.0-dev.96+3b9f1720",
4
4
  "description": "A linter for all markup developers",
5
5
  "author": "Yusuke Hirao",
6
6
  "license": "MIT",
@@ -8,6 +8,9 @@
8
8
  "repository": "git@github.com:markuplint/markuplint.git",
9
9
  "main": "lib/index.js",
10
10
  "types": "lib/index.d.ts",
11
+ "typedoc": {
12
+ "entryPoint": "./src/index.ts"
13
+ },
11
14
  "bin": {
12
15
  "markuplint": "bin/markuplint"
13
16
  },
@@ -25,16 +28,16 @@
25
28
  "execa": "5"
26
29
  },
27
30
  "dependencies": {
28
- "@markuplint/create-rule-helper": "3.0.0-dev.54+329808d5",
29
- "@markuplint/file-resolver": "3.0.0-dev.54+329808d5",
30
- "@markuplint/html-parser": "3.0.0-dev.54+329808d5",
31
- "@markuplint/html-spec": "3.0.0-dev.54+329808d5",
32
- "@markuplint/i18n": "3.0.0-dev.54+329808d5",
33
- "@markuplint/ml-ast": "3.0.0-dev.54+329808d5",
34
- "@markuplint/ml-config": "3.0.0-dev.54+329808d5",
35
- "@markuplint/ml-core": "3.0.0-dev.54+329808d5",
36
- "@markuplint/ml-spec": "3.0.0-dev.54+329808d5",
37
- "@markuplint/rules": "3.0.0-dev.54+329808d5",
31
+ "@markuplint/create-rule-helper": "3.0.0-dev.96+3b9f1720",
32
+ "@markuplint/file-resolver": "3.0.0-dev.96+3b9f1720",
33
+ "@markuplint/html-parser": "3.0.0-dev.96+3b9f1720",
34
+ "@markuplint/html-spec": "3.0.0-dev.96+3b9f1720",
35
+ "@markuplint/i18n": "3.0.0-dev.96+3b9f1720",
36
+ "@markuplint/ml-ast": "3.0.0-dev.96+3b9f1720",
37
+ "@markuplint/ml-config": "3.0.0-dev.96+3b9f1720",
38
+ "@markuplint/ml-core": "3.0.0-dev.96+3b9f1720",
39
+ "@markuplint/ml-spec": "3.0.0-dev.96+3b9f1720",
40
+ "@markuplint/rules": "3.0.0-dev.96+3b9f1720",
38
41
  "chokidar": "^3.5.3",
39
42
  "cli-color": "^2.0.3",
40
43
  "debug": "^4.3.4",
@@ -42,13 +45,15 @@
42
45
  "eastasianwidth": "^0.2.0",
43
46
  "enquirer": "^2.3.6",
44
47
  "get-stdin": "8",
48
+ "gray-matter": "^4.0.3",
45
49
  "has-yarn": "2",
46
50
  "meow": "9",
51
+ "node-fetch": "2",
47
52
  "os-locale": "5",
48
53
  "strict-event-emitter": "^0.2.8",
49
54
  "strip-ansi": "6",
50
55
  "tslib": "^2.4.1",
51
56
  "uuid": "^9.0.0"
52
57
  },
53
- "gitHead": "329808d50ff8875e24031f692a0504d00b72c4f8"
58
+ "gitHead": "3b9f17205d7754b29edf790bdbbf5e4931ba27a2"
54
59
  }