@atlaskit/eslint-plugin-ui-styling-standard
Version:
The eslint plugin to enforce and educate on Atlassian's UI Styling Standard
73 lines (71 loc) • 2.36 kB
JavaScript
import Ajv from 'ajv';
import { getRuleUrl } from './get-rule-url';
/**
* A single shared Ajv instance is reused across every rule instead of constructing
* a new one each time a default config is needed. Ajv's constructor is expensive
* (it compiles its own meta-schemas), so we only ever want to pay for it once.
*/
const ajv = new Ajv({
useDefaults: true
});
export const createLintRuleWithTypedConfig = rule => {
/**
* Lazily-computed, cached default config.
*
* The default config is derived purely from the rule's (static) schema, so it is
* constant for the life of the process. Compiling the schema with Ajv involves
* runtime code generation (`new Function`), which is expensive — previously this
* ran on every `getDefaultConfig()` call, i.e. once per linted file. We now compute
* it at most once per rule and reuse the result.
*/
let defaultConfig;
/**
* Gets the default config by running the same validator
* ESLint does against an empty config object with
* `useDefaults` option enabled.
*
* Any properties with a `default` property set in the schema
* will be populated with the specified default value.
*/
function getDefaultConfig() {
if (defaultConfig === undefined) {
const validate = ajv.compile(rule.meta.schema);
const config = {};
/**
* The `validate()` function mutates the config object.
*/
validate(config);
defaultConfig = config;
}
return defaultConfig;
}
return {
...rule,
meta: {
...rule.meta,
docs: {
...rule.meta.docs,
url: getRuleUrl(rule.meta.name)
},
schema: [rule.meta.schema]
},
create(context) {
/**
* The config the user has passed.
*
* If they passed a config object, even if it is missing properties,
* ESLint will have added any default values defined using the
* `default` property in the schema.
*
* https://github.com/eslint/eslint/pull/11288
*/
const userConfig = context.options[0];
/**
* If the user passed no config object at all we need to obtain
* the default ourselves.
*/
const config = userConfig !== null && userConfig !== void 0 ? userConfig : getDefaultConfig();
return rule.create(context, config);
}
};
};