markuplint 3.0.0-canary.3 → 3.0.0-dev.176

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.
Files changed (44) hide show
  1. package/README.md +8 -6
  2. package/lib/api/lint.d.ts +2 -2
  3. package/lib/api/ml-engine.d.ts +24 -23
  4. package/lib/api/ml-engine.js +37 -18
  5. package/lib/api/types.d.ts +33 -37
  6. package/lib/api/v1.d.ts +44 -44
  7. package/lib/api/v1.js +4 -7
  8. package/lib/cli/bootstrap.d.ts +3 -2
  9. package/lib/cli/bootstrap.js +1 -1
  10. package/lib/cli/command.d.ts +6 -2
  11. package/lib/cli/command.js +2 -2
  12. package/lib/cli/create-rule/index.js +48 -19
  13. package/lib/cli/index.js +1 -1
  14. package/lib/cli/init/create-config.d.ts +8 -0
  15. package/lib/cli/init/create-config.js +95 -0
  16. package/lib/cli/init/get-default-rules.d.ts +3 -0
  17. package/lib/cli/init/get-default-rules.js +57 -0
  18. package/lib/cli/init/index.js +23 -207
  19. package/lib/cli/init/install-module.d.ts +5 -3
  20. package/lib/cli/init/install-module.js +16 -2
  21. package/lib/cli/init/types.d.ts +20 -0
  22. package/lib/cli/init/types.js +2 -0
  23. package/lib/cli/output.d.ts +1 -1
  24. package/lib/cli/output.js +6 -2
  25. package/lib/cli/prompt.d.ts +18 -13
  26. package/lib/cli/search/index.d.ts +1 -1
  27. package/lib/cli/search/index.js +2 -1
  28. package/lib/global-settings.d.ts +1 -1
  29. package/lib/i18n.js +8 -7
  30. package/lib/reporter/github-reporter.d.ts +2 -0
  31. package/lib/reporter/github-reporter.js +23 -0
  32. package/lib/reporter/index.d.ts +1 -0
  33. package/lib/reporter/index.js +1 -0
  34. package/lib/reporter/simple-reporter.js +1 -1
  35. package/lib/reporter/standard-reporter.js +5 -4
  36. package/lib/testing-tool/index.d.ts +44 -26
  37. package/lib/types.d.ts +18 -19
  38. package/lib/util.d.ts +3 -5
  39. package/lib/util.js +9 -7
  40. package/package.json +25 -21
  41. package/media/screenshot01.png +0 -0
  42. package/test/plugin001.js +0 -24
  43. package/tsconfig.test.json +0 -3
  44. package/tsconfig.tsbuildinfo +0 -1
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![GitHub Stars](https://img.shields.io/github/stars/markuplint.svg)](https://github.com/markuplint/markuplint)
8
8
  [![Follow us on Twitter](https://img.shields.io/twitter/follow/markuplint?label=Follow)](https://twitter.com/intent/user?screen_name=markuplint)
9
9
 
10
- **Peace of mind in your markup** - A linter for all markup developers.
10
+ **Peace of mind in your markup** - An HTML linter for all markup developers.
11
11
 
12
12
  ## Features
13
13
 
@@ -47,7 +47,7 @@ Add a command to the `scripts` option on `package.json`:
47
47
  ```json
48
48
  {
49
49
  "scripts": {
50
- "html:lint": "markuplint **/*.html"
50
+ "lint:html": "markuplint **/*.html"
51
51
  }
52
52
  }
53
53
  ```
@@ -57,9 +57,9 @@ If you want to change the target path, you can change it for your project.
57
57
  Execute the script:
58
58
 
59
59
  ```
60
- $ npm run html:lint
60
+ $ npm run lint:html
61
61
  # or
62
- $ yarn html:lint
62
+ $ yarn lint:html
63
63
  ```
64
64
 
65
65
  ### Command line options
@@ -74,7 +74,7 @@ Usage
74
74
  Options
75
75
  --config, -c FILE_PATH A configuration file path.
76
76
  --fix, Fix HTML.
77
- --format, -f FORMAT Output format. Support "JSON", "Simple" and "Standard". Default: "Standard".
77
+ --format, -f FORMAT Output format. Support "JSON", "Simple", "GitHub" and "Standard". Default: "Standard".
78
78
  --no-search-config No search a configure file automatically.
79
79
  --ignore-ext Evaluate files that are received even though the type of extension.
80
80
  --no-import-preset-rules No import preset rules.
@@ -119,7 +119,9 @@ Need [Sponsors❤️‍🔥](https://github.com/sponsors/markuplint)
119
119
 
120
120
  ### Personal Supporters
121
121
 
122
- [<img width="36" src="https://avatars.githubusercontent.com/u/91733847?v=4" alt="Tokitake" />](https://github.com/Tokitake)
122
+ [<img width="36" src="https://avatars.githubusercontent.com/u/91733847" alt="Tokitake" />](https://github.com/Tokitake)
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)
123
125
 
124
126
  ## Thanks
125
127
 
package/lib/api/lint.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MLResultInfo } from '../types';
2
1
  import type { APIOptions } from './types';
2
+ import type { MLResultInfo } from '../types';
3
3
  import type { Target } from '@markuplint/file-resolver';
4
- export declare function lint(targetList: Target[], options?: APIOptions): Promise<MLResultInfo[]>;
4
+ export declare function lint(targetList: readonly Readonly<Target>[], options?: APIOptions): Promise<MLResultInfo[]>;
@@ -1,30 +1,31 @@
1
- import type { MLResultInfo } from '../types';
2
1
  import type { APIOptions, MLEngineEventMap } from './types';
2
+ import type { MLResultInfo } from '../types';
3
3
  import type { MLFile, Target } from '@markuplint/file-resolver';
4
+ import type { PlainData } from '@markuplint/ml-config';
4
5
  import type { Document, RuleConfigValue } from '@markuplint/ml-core';
5
- import { StrictEventEmitter } from 'strict-event-emitter';
6
+ import { Emitter } from 'strict-event-emitter';
6
7
  type MLEngineOptions = {
7
- debug?: boolean;
8
- watch?: boolean;
8
+ readonly debug?: boolean;
9
+ readonly watch?: boolean;
9
10
  };
10
- export default class MLEngine extends StrictEventEmitter<MLEngineEventMap> {
11
- #private;
12
- static toMLFile(target: Target): Promise<MLFile>;
13
- constructor(file: MLFile, options?: APIOptions & MLEngineOptions);
14
- get document(): Document<RuleConfigValue, unknown> | null;
15
- close(): Promise<void>;
16
- exec(): Promise<MLResultInfo | null>;
17
- setCode(code: string): Promise<void>;
18
- watchMode(enable: boolean): void;
19
- private createCore;
20
- private i18n;
21
- private onChange;
22
- private provide;
23
- private resolveConfig;
24
- private resolveParser;
25
- private resolveRules;
26
- private resolveRuleset;
27
- private resolveSchemas;
28
- private setup;
11
+ export default class MLEngine extends Emitter<MLEngineEventMap> {
12
+ #private;
13
+ static toMLFile(target: Target): Promise<MLFile | undefined>;
14
+ constructor(file: Readonly<MLFile>, options?: APIOptions & MLEngineOptions);
15
+ get document(): Document<RuleConfigValue, PlainData> | null;
16
+ close(): Promise<void>;
17
+ exec(): Promise<MLResultInfo | null>;
18
+ setCode(code: string): Promise<void>;
19
+ watchMode(enable: boolean): void;
20
+ private createCore;
21
+ private i18n;
22
+ private onChange;
23
+ private provide;
24
+ private resolveConfig;
25
+ private resolveParser;
26
+ private resolveRules;
27
+ private resolveRuleset;
28
+ private resolveSchemas;
29
+ private setup;
29
30
  }
30
31
  export {};
@@ -10,7 +10,8 @@ const debug_1 = require("../debug");
10
10
  const i18n_1 = require("../i18n");
11
11
  const log = debug_1.log.extend('ml-engine');
12
12
  const fileLog = log.extend('file');
13
- class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
13
+ const configLog = log.extend('config');
14
+ class MLEngine extends strict_event_emitter_1.Emitter {
14
15
  static async toMLFile(target) {
15
16
  const files = await (0, file_resolver_1.resolveFiles)([target]);
16
17
  return files[0];
@@ -78,7 +79,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
78
79
  fixedCode,
79
80
  };
80
81
  }
81
- const debugMap = ('debugMap' in core.document && core.document.debugMap()) || null;
82
+ const debugMap = 'debugMap' in core.document ? core.document.debugMap() : null;
82
83
  this.emit('lint', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, sourceCode, violations, fixedCode, debugMap);
83
84
  log('exec: end');
84
85
  return {
@@ -149,7 +150,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
149
150
  await this.exec();
150
151
  }
151
152
  async provide(cache = true) {
152
- var _a, _b, _c;
153
+ var _a, _b, _c, _d;
153
154
  const configSet = await this.resolveConfig(cache);
154
155
  fileLog('Fetched Config files: %O', configSet.files);
155
156
  fileLog('Resolved Config: %O', configSet.config);
@@ -161,7 +162,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
161
162
  return null;
162
163
  }
163
164
  // Exclude
164
- const excludeFiles = configSet.config.excludeFiles || [];
165
+ const excludeFiles = (_a = configSet.config.excludeFiles) !== null && _a !== void 0 ? _a : [];
165
166
  for (const excludeFile of excludeFiles) {
166
167
  if (tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").matches(excludeFile)) {
167
168
  this.emit('exclude', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, excludeFile);
@@ -170,7 +171,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
170
171
  }
171
172
  }
172
173
  const { parser, parserOptions, matched } = await this.resolveParser(configSet);
173
- const checkingExt = !((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.ignoreExt);
174
+ const checkingExt = !((_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _b === void 0 ? void 0 : _b.ignoreExt);
174
175
  if (checkingExt && !matched) {
175
176
  this.emit('log', 'ext-unmatched', `Avoided linting because a file is unmatched by the extension: ${tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path}`);
176
177
  fileLog('Avoided linting because a file is unmatched by the extension: %s', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path);
@@ -180,7 +181,7 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
180
181
  fileLog('Resolved ruleset: %O', ruleset);
181
182
  const schemas = await this.resolveSchemas(configSet);
182
183
  if (fileLog.enabled) {
183
- if (schemas[0].cites.length) {
184
+ if (schemas[0].cites.length > 0) {
184
185
  const [, ...additionalSpecs] = schemas;
185
186
  fileLog('Resolved schemas: HTML Standard');
186
187
  for (const additionalSpec of additionalSpecs) {
@@ -193,14 +194,14 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
193
194
  }
194
195
  const rules = await this.resolveRules(configSet.plugins, ruleset);
195
196
  fileLog('Resolved rules: %O', rules);
196
- const locale = await (0, i18n_1.i18n)((_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _b === void 0 ? void 0 : _b.locale);
197
+ const locale = await (0, i18n_1.i18n)((_c = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _c === void 0 ? void 0 : _c.locale);
197
198
  if (fileLog.enabled) {
198
199
  fileLog('Loaded %d rules: %O', rules.length, rules.map(r => r.name));
199
200
  }
200
201
  return {
201
202
  parser,
202
203
  parserOptions,
203
- pretenders: (_c = configSet.config.pretenders) !== null && _c !== void 0 ? _c : [],
204
+ pretenders: (_d = configSet.config.pretenders) !== null && _d !== void 0 ? _d : [],
204
205
  ruleset,
205
206
  schemas,
206
207
  rules,
@@ -209,23 +210,37 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
209
210
  };
210
211
  }
211
212
  async resolveConfig(cache) {
212
- var _a, _b, _c, _d, _e, _f;
213
+ var _a, _b, _c, _d, _e, _f, _g;
213
214
  const defaultConfigKey = ((_a = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _a === void 0 ? void 0 : _a.defaultConfig) && tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").set((_b = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _b === void 0 ? void 0 : _b.defaultConfig);
215
+ configLog('defaultConfigKey: %s', defaultConfigKey !== null && defaultConfigKey !== void 0 ? defaultConfigKey : 'N/A');
216
+ this.emit('log', 'defaultConfigKey', defaultConfigKey !== null && defaultConfigKey !== void 0 ? defaultConfigKey : 'N/A');
214
217
  const configFilePathsFromTarget = ((_c = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _c === void 0 ? void 0 : _c.noSearchConfig)
215
218
  ? defaultConfigKey !== null && defaultConfigKey !== void 0 ? defaultConfigKey : null
216
- : (await tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").search(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f"))) || defaultConfigKey;
217
- this.emit('log', 'configFilePathsFromTarget', configFilePathsFromTarget || 'null');
218
- const configKey = ((_d = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _d === void 0 ? void 0 : _d.config) && tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").set(tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f").config);
219
- this.emit('log', 'configKey', configKey || 'null');
220
- const configSet = await tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").resolve(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f"), [configFilePathsFromTarget, (_e = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _e === void 0 ? void 0 : _e.configFile, configKey], cache);
219
+ : (_d = (await tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").search(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f")))) !== null && _d !== void 0 ? _d : defaultConfigKey;
220
+ configLog('configFilePathsFromTarget: %s', configFilePathsFromTarget !== null && configFilePathsFromTarget !== void 0 ? configFilePathsFromTarget : 'N/A');
221
+ this.emit('log', 'configFilePathsFromTarget', configFilePathsFromTarget !== null && configFilePathsFromTarget !== void 0 ? configFilePathsFromTarget : 'N/A');
222
+ const configKey = ((_e = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _e === void 0 ? void 0 : _e.config) && tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").set(tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f").config);
223
+ configLog('option.config: %s', configKey !== null && configKey !== void 0 ? configKey : 'N/A');
224
+ this.emit('log', 'option.config', configFilePathsFromTarget !== null && configFilePathsFromTarget !== void 0 ? configFilePathsFromTarget : 'N/A');
225
+ let defaultRecommended = null;
226
+ if (!defaultConfigKey && !configFilePathsFromTarget && !configKey) {
227
+ // No configured
228
+ // Default: set recommended
229
+ defaultRecommended = tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").set({ extends: ['markuplint:recommended'] });
230
+ }
231
+ configLog('defaultRecommended: %s', defaultRecommended !== null && defaultRecommended !== void 0 ? defaultRecommended : 'N/A');
232
+ this.emit('log', 'defaultRecommended', defaultRecommended !== null && defaultRecommended !== void 0 ? defaultRecommended : 'N/A');
233
+ const configSet = await tslib_1.__classPrivateFieldGet(this, _MLEngine_configProvider, "f").resolve(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f"), [configFilePathsFromTarget, (_f = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _f === void 0 ? void 0 : _f.configFile, configKey, defaultRecommended], cache);
221
234
  this.emit('config', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, configSet);
222
- if ((_f = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _f === void 0 ? void 0 : _f.watch) {
235
+ if ((_g = tslib_1.__classPrivateFieldGet(this, _MLEngine_options, "f")) === null || _g === void 0 ? void 0 : _g.watch) {
223
236
  // It doesn't watch the main HTML file because it may is watched and managed by a language server or text editor or more.
224
237
  tslib_1.__classPrivateFieldGet(this, _MLEngine_watcher, "f").add(Array.from(configSet.files));
225
238
  }
226
239
  return configSet;
227
240
  }
228
- async resolveParser(configSet) {
241
+ async resolveParser(
242
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
243
+ configSet) {
229
244
  const parser = await (0, file_resolver_1.resolveParser)(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f"), configSet.config.parser, configSet.config.parserOptions);
230
245
  this.emit('parser', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, parser.parserModName);
231
246
  fileLog('Fetched Parser module: %s', parser.parserModName);
@@ -240,12 +255,16 @@ class MLEngine extends strict_event_emitter_1.StrictEventEmitter {
240
255
  this.emit('rules', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, rules);
241
256
  return rules;
242
257
  }
243
- resolveRuleset(configSet) {
258
+ resolveRuleset(
259
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
260
+ configSet) {
244
261
  const ruleset = (0, ml_core_1.convertRuleset)(configSet.config);
245
262
  this.emit('ruleset', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, ruleset);
246
263
  return ruleset;
247
264
  }
248
- async resolveSchemas(configSet) {
265
+ async resolveSchemas(
266
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
267
+ configSet) {
249
268
  const { schemas } = await (0, file_resolver_1.resolveSpecs)(tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, configSet.config.specs);
250
269
  this.emit('schemas', tslib_1.__classPrivateFieldGet(this, _MLEngine_file, "f").path, schemas);
251
270
  return schemas;
@@ -1,44 +1,40 @@
1
1
  import type { ConfigSet } from '@markuplint/file-resolver';
2
2
  import type { LocaleSet } from '@markuplint/i18n';
3
- import type { MLMarkupLanguageParser, ParserOptions } from '@markuplint/ml-ast';
4
- import type { Config, Pretender, Violation } from '@markuplint/ml-config';
3
+ import type { Config, Violation } from '@markuplint/ml-config';
5
4
  import type { AnyMLRule, MLSchema, Ruleset } from '@markuplint/ml-core';
6
5
  export type APIOptions = {
7
- configFile?: string;
8
- config?: Config;
9
- defaultConfig?: Config;
10
- noSearchConfig?: boolean;
11
- locale?: string;
12
- fix?: boolean;
13
- ignoreExt?: boolean;
14
- rules?: AnyMLRule[];
15
- importPresetRules?: boolean;
16
- /**
17
- * @deprecated
18
- */
19
- autoLoad?: boolean;
20
- };
21
- export type MLFabric = {
22
- ruleset: Ruleset;
23
- rules: AnyMLRule[];
24
- schemas: MLSchema;
25
- parser: MLMarkupLanguageParser;
26
- parserOptions: ParserOptions;
27
- pretenders: Pretender[];
28
- locale: LocaleSet;
29
- configErrors?: Error[];
6
+ readonly configFile?: string;
7
+ readonly config?: Config;
8
+ readonly defaultConfig?: Config;
9
+ readonly noSearchConfig?: boolean;
10
+ readonly locale?: string;
11
+ readonly fix?: boolean;
12
+ readonly ignoreExt?: boolean;
13
+ readonly rules?: readonly Readonly<AnyMLRule>[];
14
+ readonly importPresetRules?: boolean;
15
+ /**
16
+ * @deprecated
17
+ */
18
+ readonly autoLoad?: boolean;
30
19
  };
31
20
  export type MLEngineEventMap = {
32
- log: (phase: string, message: string) => void;
33
- config: (filePath: string, config: ConfigSet, message?: string) => void;
34
- exclude: (filePath: string, setting: string, message?: string) => void;
35
- parser: (filePath: string, parser: string, message?: string) => void;
36
- ruleset: (filePath: string, ruleset: Ruleset, message?: string) => void;
37
- schemas: (filePath: string, schemas: MLSchema, message?: string) => void;
38
- rules: (filePath: string, rules: AnyMLRule[], message?: string) => void;
39
- i18n: (filePath: string, locale: LocaleSet, message?: string) => void;
40
- code: (filePath: string, sourceCode: string, message?: string) => void;
41
- lint: (filePath: string, sourceCode: string, violations: Violation[], fixedCode: string, debug: string[] | null, message?: string) => void;
42
- 'lint-error': (filePath: string, sourceCode: string, error: Error) => void;
43
- 'config-errors': (filePath: string, errors: Error[]) => void;
21
+ log: [phase: string, message: string];
22
+ config: [filePath: string, config: ConfigSet, message?: string];
23
+ exclude: [filePath: string, setting: string, message?: string];
24
+ parser: [filePath: string, parser: string, message?: string];
25
+ ruleset: [filePath: string, ruleset: Ruleset, message?: string];
26
+ schemas: [filePath: string, schemas: MLSchema, message?: string];
27
+ rules: [filePath: string, rules: readonly Readonly<AnyMLRule>[], message?: string];
28
+ i18n: [filePath: string, locale: LocaleSet, message?: string];
29
+ code: [filePath: string, sourceCode: string, message?: string];
30
+ lint: [
31
+ filePath: string,
32
+ sourceCode: string,
33
+ violations: readonly Violation[],
34
+ fixedCode: string,
35
+ debug: readonly string[] | null,
36
+ message?: string,
37
+ ];
38
+ 'lint-error': [filePath: string, sourceCode: string, error: Readonly<Error>];
39
+ 'config-errors': [filePath: string, errors: readonly Readonly<Error>[]];
44
40
  };
package/lib/api/v1.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Config, RuleConfigValue } from '@markuplint/ml-config';
1
+ import type { Config, PlainData, RuleConfigValue } from '@markuplint/ml-config';
2
2
  import type { MLRule } from '@markuplint/ml-core';
3
3
  /**
4
4
  * @deprecated
@@ -6,46 +6,46 @@ import type { MLRule } from '@markuplint/ml-core';
6
6
  * @returns
7
7
  */
8
8
  export declare function lint_v1(options: {
9
- /**
10
- * Glob pattern
11
- */
12
- files?: string | string[];
13
- /**
14
- * Target source code of evaluation
15
- */
16
- sourceCodes?: string | string[];
17
- /**
18
- * File names when `sourceCodes`
19
- */
20
- names?: string | string[];
21
- /**
22
- * Workspace path when `sourceCodes`
23
- */
24
- workspace?: string;
25
- /**
26
- * Configure file or object
27
- */
28
- config?: string | Config;
29
- /**
30
- * The config applied when not resolved from files or set it explicitly.
31
- */
32
- defaultConfig?: Config;
33
- /**
34
- * Rules (default: `@markuplint/rules`)
35
- */
36
- rules?: MLRule<RuleConfigValue, unknown>[];
37
- /**
38
- * Auto resolve rules
39
- *
40
- * Auto importing form *node_modules* when set `@markuplint/rule-{RULE_NAME}` or `markuplint-rule-{RULE_NAME}` in config rules
41
- */
42
- rulesAutoResolve?: boolean;
43
- /**
44
- * Auto fix
45
- */
46
- fix?: boolean;
47
- /**
48
- * Locale
49
- */
50
- locale?: string;
51
- }): Promise<import("..").MLResultInfo[]>;
9
+ /**
10
+ * Glob pattern
11
+ */
12
+ readonly files?: string | readonly string[];
13
+ /**
14
+ * Target source code of evaluation
15
+ */
16
+ readonly sourceCodes?: string | readonly string[];
17
+ /**
18
+ * File names when `sourceCodes`
19
+ */
20
+ readonly names?: string | readonly string[];
21
+ /**
22
+ * Workspace path when `sourceCodes`
23
+ */
24
+ readonly workspace?: string;
25
+ /**
26
+ * Configure file or object
27
+ */
28
+ readonly config?: string | Config;
29
+ /**
30
+ * The config applied when not resolved from files or set it explicitly.
31
+ */
32
+ readonly defaultConfig?: Config;
33
+ /**
34
+ * Rules (default: `@markuplint/rules`)
35
+ */
36
+ readonly rules?: readonly Readonly<MLRule<RuleConfigValue, PlainData>>[];
37
+ /**
38
+ * Auto resolve rules
39
+ *
40
+ * Auto importing form *node_modules* when set `@markuplint/rule-{RULE_NAME}` or `markuplint-rule-{RULE_NAME}` in config rules
41
+ */
42
+ readonly rulesAutoResolve?: boolean;
43
+ /**
44
+ * Auto fix
45
+ */
46
+ readonly fix?: boolean;
47
+ /**
48
+ * Locale
49
+ */
50
+ readonly locale?: string;
51
+ }): Promise<import('..').MLResultInfo[]>;
package/lib/api/v1.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.lint_v1 = void 0;
4
+ const shared_1 = require("@markuplint/shared");
4
5
  const lint_1 = require("./lint");
5
6
  /**
6
7
  * @deprecated
@@ -9,12 +10,8 @@ const lint_1 = require("./lint");
9
10
  */
10
11
  async function lint_v1(options) {
11
12
  var _a;
12
- const filePathList = options.files ? (Array.isArray(options.files) ? options.files : [options.files]) : [];
13
- const codes = options.sourceCodes
14
- ? Array.isArray(options.sourceCodes)
15
- ? options.sourceCodes
16
- : [options.sourceCodes]
17
- : [];
13
+ const filePathList = (0, shared_1.toNoEmptyStringArrayFromStringOrArray)(options.files);
14
+ const codes = (0, shared_1.toNoEmptyStringArrayFromStringOrArray)(options.sourceCodes);
18
15
  const files = [
19
16
  ...filePathList,
20
17
  ...codes.map((code, i) => {
@@ -37,7 +34,7 @@ async function lint_v1(options) {
37
34
  const result = await (0, lint_1.lint)(files, {
38
35
  config,
39
36
  configFile,
40
- noSearchConfig: !options.files,
37
+ noSearchConfig: filePathList.length === 0,
41
38
  rules: options.rules,
42
39
  autoLoad: (_a = options.rulesAutoResolve) !== null && _a !== void 0 ? _a : true,
43
40
  locale: options.locale,
@@ -1,5 +1,6 @@
1
+ import type { ReadonlyDeep } from 'type-fest';
1
2
  import meow from 'meow';
2
- export declare const help = "\nUsage\n\t$ markuplint <HTML file paths (glob format)>\n\t$ <stdout> | markuplint\n\nOptions\n\t--config, -c FILE_PATH A configuration file path.\n\t--fix, Fix HTML.\n\t--format, -f FORMAT Output format. Support \"JSON\", \"Simple\" and \"Standard\". Default: \"Standard\".\n\t--no-search-config No search a configure file automatically.\n\t--ignore-ext Evaluate files that are received even though the type of extension.\n\t--no-import-preset-rules No import preset rules.\n\t--locale Locale of the message of violation. Default is an OS setting.\n\t--no-color, Output no color.\n\t--problem-only, -p Output only problems, without passeds.\n\t--verbose Output with detailed information.\n\n\t--init Initialize settings interactively.\n\t--create-rule Add the scaffold of a custom rule.\n\t--search Search lines of codes that include the target element by selectors.\n\n\t--help, -h Show help.\n\t--version, -v Show version.\n\nExamples\n\t$ markuplint verifyee.html --config path/to/.markuplintrc\n\t$ cat verifyee.html | markuplint\n";
3
+ export declare const help = "\nUsage\n\t$ markuplint <HTML file paths (glob format)>\n\t$ <stdout> | markuplint\n\nOptions\n\t--config, -c FILE_PATH A configuration file path.\n\t--fix, Fix HTML.\n\t--format, -f FORMAT Output format. Support \"JSON\", \"Simple\", \"GitHub\" and \"Standard\". Default: \"Standard\".\n\t--no-search-config No search a configure file automatically.\n\t--ignore-ext Evaluate files that are received even though the type of extension.\n\t--no-import-preset-rules No import preset rules.\n\t--locale Locale of the message of violation. Default is an OS setting.\n\t--no-color, Output no color.\n\t--problem-only, -p Output only problems, without passeds.\n\t--verbose Output with detailed information.\n\n\t--init Initialize settings interactively.\n\t--create-rule Add the scaffold of a custom rule.\n\t--search Search lines of codes that include the target element by selectors.\n\n\t--help, -h Show help.\n\t--version, -v Show version.\n\nExamples\n\t$ markuplint verifyee.html --config path/to/.markuplintrc\n\t$ cat verifyee.html | markuplint\n";
3
4
  export declare const cli: meow.Result<{
4
5
  config: {
5
6
  type: "string";
@@ -53,4 +54,4 @@ export declare const cli: meow.Result<{
53
54
  type: "string";
54
55
  };
55
56
  }>;
56
- export type CLIOptions = typeof cli.flags;
57
+ export type CLIOptions = ReadonlyDeep<typeof cli.flags>;
@@ -11,7 +11,7 @@ Usage
11
11
  Options
12
12
  --config, -c FILE_PATH A configuration file path.
13
13
  --fix, Fix HTML.
14
- --format, -f FORMAT Output format. Support "JSON", "Simple" and "Standard". Default: "Standard".
14
+ --format, -f FORMAT Output format. Support "JSON", "Simple", "GitHub" and "Standard". Default: "Standard".
15
15
  --no-search-config No search a configure file automatically.
16
16
  --ignore-ext Evaluate files that are received even though the type of extension.
17
17
  --no-import-preset-rules No import preset rules.
@@ -1,4 +1,8 @@
1
- import type { APIOptions } from '../api/types';
2
1
  import type { CLIOptions } from './bootstrap';
2
+ import type { APIOptions } from '../api/types';
3
3
  import type { Target } from '@markuplint/file-resolver';
4
- export declare function command(files: Target[], options: CLIOptions, apiOptions?: APIOptions): Promise<boolean>;
4
+ export declare function command(
5
+ files: readonly Readonly<Target>[],
6
+ options: CLIOptions,
7
+ apiOptions?: APIOptions,
8
+ ): Promise<boolean>;
@@ -20,7 +20,7 @@ async function command(files, options, apiOptions) {
20
20
  const fileList = await (0, file_resolver_1.resolveFiles)(files);
21
21
  if (debug_1.log.enabled) {
22
22
  (0, debug_1.log)('File list: %O', fileList.map(f => f.path));
23
- (0, debug_1.log)('Config: %s', configFile || 'N/A');
23
+ (0, debug_1.log)('Config: %s', configFile !== null && configFile !== void 0 ? configFile : 'N/A');
24
24
  (0, debug_1.log)('Fix option: %s', fix);
25
25
  }
26
26
  const format = (_a = options.format) === null || _a === void 0 ? void 0 : _a.toLowerCase().trim();
@@ -41,7 +41,7 @@ async function command(files, options, apiOptions) {
41
41
  if (!result) {
42
42
  continue;
43
43
  }
44
- if (!hasError && result.violations.length) {
44
+ if (!hasError && result.violations.length > 0) {
45
45
  hasError = true;
46
46
  }
47
47
  if (fix) {
@@ -2,23 +2,59 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createRule = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const node_path_1 = require("node:path");
5
6
  const create_rule_helper_1 = require("@markuplint/create-rule-helper");
6
7
  const cli_color_1 = tslib_1.__importDefault(require("cli-color"));
7
8
  const util_1 = require("../../util");
8
9
  const install_module_1 = require("../init/install-module");
9
10
  const prompt_1 = require("../prompt");
11
+ const icons = {
12
+ README: '📝',
13
+ index: '📜',
14
+ schema: '⚙️ ',
15
+ package: '🎁',
16
+ tsconfig: '💎',
17
+ };
10
18
  async function createRule() {
19
+ var _a;
11
20
  (0, util_1.write)((0, util_1.head)('Create a rule'));
12
21
  util_1.write.break();
22
+ const firstChoices = [
23
+ { name: 'Add the rule to this project', value: 'ADD_TO_PROJECT' },
24
+ { name: 'Create the rule and publish it as a package', value: 'PUBLISH_AS_PACKAGE' },
25
+ ];
26
+ if (await (0, create_rule_helper_1.isMarkuplintRepo)()) {
27
+ firstChoices.push({ name: 'Contribute the new rule to markuplint core rules', value: 'CONTRIBUTE_TO_CORE' });
28
+ }
13
29
  const purpose = await (0, prompt_1.select)({
14
30
  message: 'What purpose do you create the rule for?',
15
- choices: [
16
- { name: 'Add the rule to this project', value: 'ADD_TO_PROJECT' },
17
- { name: 'Create the rule and publish it as a package', value: 'PUBLISH_AS_PACKAGE' },
18
- { name: 'Contribute the new rule to markuplint core rules', value: 'CONTRIBUTE_TO_CORE' },
19
- ],
31
+ choices: firstChoices,
20
32
  });
21
- const name = await (0, prompt_1.input)('What is the name?', /^[a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*$/i);
33
+ const dirQuestion = purpose === 'ADD_TO_PROJECT' ? 'What is the directory name?' : 'What is the plugin name?';
34
+ const pluginName = purpose === 'CONTRIBUTE_TO_CORE' ? '' : await (0, prompt_1.input)(dirQuestion, /^[a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*$/i);
35
+ const ruleName = await (0, prompt_1.input)('What is the rule name?', /^[a-z][a-z0-9]*(?:-[a-z][a-z0-9]*)*$/i);
36
+ const core = purpose === 'CONTRIBUTE_TO_CORE'
37
+ ? {
38
+ description: await (0, prompt_1.input)('Description:'),
39
+ category: await (0, prompt_1.select)({
40
+ message: 'Category:',
41
+ choices: [
42
+ { name: 'Conformance checking', value: 'validation' },
43
+ { name: 'Accessibility', value: 'a11y' },
44
+ { name: 'Naming Convention', value: 'naming-convention' },
45
+ { name: 'Maintainability', value: 'maintainability' },
46
+ { name: 'Style', value: 'style' },
47
+ ],
48
+ }),
49
+ severity: await (0, prompt_1.select)({
50
+ message: 'Severity:',
51
+ choices: [
52
+ { name: 'error', value: 'error' },
53
+ { name: 'warning', value: 'warning' },
54
+ ],
55
+ }),
56
+ }
57
+ : undefined;
22
58
  const lang = purpose === 'CONTRIBUTE_TO_CORE'
23
59
  ? 'TYPESCRIPT'
24
60
  : await (0, prompt_1.select)({
@@ -29,21 +65,14 @@ async function createRule() {
29
65
  ],
30
66
  });
31
67
  const needTest = purpose === 'CONTRIBUTE_TO_CORE' ? true : await (0, prompt_1.confirm)('Do you need the test?', { initial: true });
32
- const result = await (0, create_rule_helper_1.createRuleHelper)({ purpose, name, lang, needTest });
33
- output(name, '📝', 'README.md', result.readme);
34
- output(name, '📜', 'index', result.main);
35
- if (result.test) {
36
- output(name, '🖍 ', 'index.spec', result.test);
37
- }
38
- if (result.schemaJson) {
39
- output(name, '⚙️ ', 'schema.json', result.schemaJson);
68
+ const result = await (0, create_rule_helper_1.createRuleHelper)({ purpose, pluginName, ruleName, lang, needTest, core });
69
+ for (const file of result.files) {
70
+ output(pluginName || 'core', file.test ? '🖍 ' : (_a = icons[file.name]) !== null && _a !== void 0 ? _a : '🛡 ', file.fileName, (0, node_path_1.resolve)(file.destDir, file.fileName + file.ext));
40
71
  }
41
- if (result.packageJson) {
42
- output(name, '🎁 ', 'package.json', result.packageJson);
43
- if (result.tsConfig) {
44
- output(name, '💎 ', 'tsconfig.json', result.tsConfig);
45
- }
72
+ if (result.dependencies.length > 0) {
46
73
  await (0, install_module_1.installModule)(result.dependencies);
74
+ }
75
+ if (result.devDependencies.length > 0) {
47
76
  await (0, install_module_1.installModule)(result.devDependencies, true);
48
77
  }
49
78
  }
package/lib/cli/index.js CHANGED
@@ -34,7 +34,7 @@ const search_1 = tslib_1.__importDefault(require("./search"));
34
34
  return;
35
35
  }
36
36
  const files = bootstrap_1.cli.input;
37
- if (files.length) {
37
+ if (files.length > 0) {
38
38
  if (bootstrap_1.cli.flags.search) {
39
39
  await (0, search_1.default)(files, bootstrap_1.cli.flags, bootstrap_1.cli.flags.search).catch(err => {
40
40
  process.stderr.write(err + '\n');
@@ -0,0 +1,8 @@
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(
5
+ langs: readonly Langs[],
6
+ mode: RuleSettingMode,
7
+ defaultRules: DefaultRules,
8
+ ): Config;