Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,6 @@
"packages": [
"packages/*"
]
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
100 changes: 67 additions & 33 deletions packages/hint/src/lib/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from './types';
import { Engine } from './engine';
import { AnalyzerErrorStatus } from './enums/error-status';
import { IFormatterConstructor } from './types/formatters';

import { loadResources } from './utils/resource-loader';

import { logger, UserConfig } from '@hint/utils';
Expand All @@ -26,13 +26,7 @@ import {
} from '@hint/utils-fs';
import { Problem } from '@hint/utils-types';

const initFormatters = (formatters: IFormatterConstructor[]): IFormatter[] => {
const result = formatters.map((FormatterConstructor) => {
return new FormatterConstructor();
});

return result;
};

const validateResources = (resources: HintResources) => {
if (resources.missing.length > 0 || resources.incompatible.length > 0) {
Expand All @@ -59,11 +53,23 @@ const validateConnector = (configuration: Configuration) => {
/**
* Node API.
*/
const normalizeFormatterConfigs = (formatters: CreateAnalyzerOptions['formatters'] = []) => {
return formatters.map((f) =>
typeof f === 'string'
? { name: f, options: {} }
: { name: f.name, options: f.options ?? {} }
);
};

export class Analyzer {
private configuration: Configuration;
private engine?: Engine;
private _resources: HintResources;
private formatters: IFormatter[];
//added this formatEntries
private formatterEntries!: Array<{
formatter: IFormatter;
options: FormatterOptions;
}>;
private watch: boolean | undefined;
private messages: { [name: string]: string } = {
'fetch::end': '%url% downloaded',
Expand All @@ -76,10 +82,11 @@ export class Analyzer {
'traverse::up': 'Traversing the DOM'
}

private constructor(configuration: Configuration, resources: HintResources, formatters: IFormatter[]) {

private constructor(configuration: Configuration, resources: HintResources) {
this.configuration = configuration;
this._resources = resources;
this.formatters = formatters;

this.watch = this.configuration.connector && this.configuration.connector.options && this.configuration.connector.options.watch;
}

Expand All @@ -88,29 +95,53 @@ export class Analyzer {
* @param userConfiguration User configuration to load.
* @param options Options used to initialize the configuration.
*/
public static create(userConfiguration: UserConfig, options: CreateAnalyzerOptions = {}) {
let configuration: Configuration;

if (!userConfiguration) {
throw new AnalyzerError('Missed configuration', AnalyzerErrorStatus.ConfigurationError);
}

try {
configuration = Configuration.fromConfig(userConfiguration, options);
} catch (e) {
throw new AnalyzerError(`Invalid configuration. ${(e as Error).message}.`, AnalyzerErrorStatus.ConfigurationError);
}

const resources = loadResources(configuration!);
const formatters = initFormatters(resources.formatters);
public static create(userConfiguration: UserConfig, options: CreateAnalyzerOptions = {}) {
let configuration: Configuration;

validateResources(resources);
validateConnector(configuration);
validateHints(configuration);
if (!userConfiguration) {
throw new AnalyzerError('Missed configuration', AnalyzerErrorStatus.ConfigurationError);
}

return new Analyzer(configuration, resources, formatters);
try {
configuration = Configuration.fromConfig(userConfiguration, options);
} catch (e) {
throw new AnalyzerError(`Invalid configuration. ${(e as Error).message}.`, AnalyzerErrorStatus.ConfigurationError);
}

const normalizedFormatterConfigs = normalizeFormatterConfigs(options.formatters);

const resources = loadResources(configuration);


const formatterMap = new Map<string, IFormatter>();


const formatterEntries = normalizedFormatterConfigs.map(({ name, options }) => {
const formatter = formatterMap.get(name);

if (!formatter) {
throw new AnalyzerError(
`Formatter '${name}' was not found.`,
AnalyzerErrorStatus.ConfigurationError
);
}

return { formatter, options };
});

validateResources(resources);
validateConnector(configuration);
validateHints(configuration);

const analyzer = new Analyzer(configuration, resources);
analyzer.formatterEntries = formatterEntries;

return analyzer;
}

/**
* Get the configuration file in a given directory.
* @param filePath Config file or directory where to look for the config file.
Expand Down Expand Up @@ -262,14 +293,17 @@ export class Analyzer {
* @param {Problem[]} problems Problems to format.
* @param {FormatterOptions} options Options for the formatters.
*/
public async format(problems: Problem[], options: FormatterOptions = {}): Promise<void> {
options.language = options.language || this.configuration.language;
options.resources = options.resources || this.resources;

for (const formatter of this.formatters) {
await formatter.format(problems, options);
}
public async format(problems: Problem[], options: FormatterOptions = {}): Promise<void> {
options.language = options.language || this.configuration.language;
options.resources = options.resources || this.resources;

for (const entry of this.formatterEntries) {
await entry.formatter.format(problems, {
...options,
...entry.options
});
}
}

/**
* Close the engine if a scan is still in progress.
Expand Down
4 changes: 2 additions & 2 deletions packages/hint/src/lib/cli/analyze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ const actionsToOptions = (actions: CLIOptions): CreateAnalyzerOptions => {
const options: CreateAnalyzerOptions = {
formatters: actions.formatters ? actions.formatters.split(',') : undefined,
hints: actions.hints ? actions.hints.split(',') : undefined,
watch: actions.watch
};
watch: actions.watch
};

return options;
};
Expand Down
4 changes: 3 additions & 1 deletion packages/hint/src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ const updateConfigWithOptionsValues = (config: UserConfig, options: CreateAnalyz

// If formatters are provided, use them
if (options.formatters) {
config.formatters = options.formatters;
config.formatters = options.formatters?.map((f) =>
typeof f === 'string' ? f : f.name
);
debug(`Using formatters option provided from Analyzer options: ${options.formatters.join(', ')}`);
}

Expand Down
9 changes: 8 additions & 1 deletion packages/hint/src/lib/types/analyzer.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { Problem } from '@hint/utils-types';

export type { UserConfig } from '@hint/utils';
export type FormatterConfig =
| string
| {
name: string;
options?: Record<string, unknown>;
};

export type CreateAnalyzerOptions = {
formatters?: string[];
formatters?: FormatterConfig[];
hints?: string[];
watch?: boolean;
}


export type Target = {
url: string | URL;
content?: string;
Expand Down
Loading