@markuplint/ml-config
Advanced tools
Comparing version 3.0.0-canary.34 to 3.0.0-dev.24
@@ -1,3 +0,3 @@ | ||
import type { Config, Nullable, AnyRule } from './types'; | ||
import type { Config, Nullable, AnyRule, AnyRuleV2 } from './types'; | ||
export declare function mergeConfig(a: Config, b: Config): Config; | ||
export declare function mergeRule(a: Nullable<AnyRule>, b: AnyRule): AnyRule; | ||
export declare function mergeRule(a: Nullable<AnyRule | AnyRuleV2>, b: AnyRule | AnyRuleV2): AnyRule; |
@@ -6,3 +6,3 @@ "use strict"; | ||
const deepmerge_1 = tslib_1.__importDefault(require("deepmerge")); | ||
const is_plain_object_1 = require("is-plain-object"); | ||
const utils_1 = require("./utils"); | ||
function mergeConfig(a, b) { | ||
@@ -26,3 +26,3 @@ const config = { | ||
}; | ||
deleteUndefProp(config); | ||
(0, utils_1.deleteUndefProp)(config); | ||
return config; | ||
@@ -32,38 +32,40 @@ } | ||
function mergeRule(a, b) { | ||
var _a, _b, _c; | ||
const oA = optimizeRule(a); | ||
const oB = optimizeRule(b); | ||
// Particular behavior: | ||
// | ||
// If the right-side value is false, return false. | ||
// In short; The `false` makes the rule to be disabled absolutely. | ||
if (b === false || (!isRuleConfigValue(b) && b.value === false)) { | ||
if (oB === false || (!(0, utils_1.isRuleConfigValue)(oB) && (oB === null || oB === void 0 ? void 0 : oB.value) === false)) { | ||
return false; | ||
} | ||
if (a === undefined) { | ||
return b; | ||
if (oA === undefined) { | ||
return oB !== null && oB !== void 0 ? oB : {}; | ||
} | ||
if (isRuleConfigValue(b)) { | ||
if (isRuleConfigValue(a)) { | ||
if (Array.isArray(a) && Array.isArray(b)) { | ||
return [...a, ...b]; | ||
if (oB === undefined) { | ||
return oA; | ||
} | ||
if ((0, utils_1.isRuleConfigValue)(oB)) { | ||
if ((0, utils_1.isRuleConfigValue)(oA)) { | ||
if (Array.isArray(oA) && Array.isArray(oB)) { | ||
return [...oA, ...oB]; | ||
} | ||
return b; | ||
return oB; | ||
} | ||
const value = Array.isArray(a.value) && Array.isArray(b) ? [...a.value, b] : b; | ||
const res = { | ||
...a, | ||
value, | ||
}; | ||
deleteUndefProp(res); | ||
const value = Array.isArray(oA.value) && Array.isArray(b) ? [...oA.value, oB] : oB; | ||
const res = (0, utils_1.cleanOptions)({ ...oA, value }); | ||
(0, utils_1.deleteUndefProp)(res); | ||
return res; | ||
} | ||
const severity = b.severity || (!isRuleConfigValue(a) ? a.severity : undefined); | ||
const value = b.value || (isRuleConfigValue(a) ? a : a.value); | ||
const option = mergeObject(!isRuleConfigValue(a) ? a.option : undefined, b.option); | ||
const reason = b.reason || (!isRuleConfigValue(a) ? a.reason : undefined); | ||
const severity = (_a = oB.severity) !== null && _a !== void 0 ? _a : (!(0, utils_1.isRuleConfigValue)(oA) ? oA.severity : undefined); | ||
const value = (_b = oB.value) !== null && _b !== void 0 ? _b : ((0, utils_1.isRuleConfigValue)(oA) ? oA : oA.value); | ||
const options = mergeObject(!(0, utils_1.isRuleConfigValue)(oA) ? oA.options : undefined, oB.options); | ||
const reason = (_c = oB.reason) !== null && _c !== void 0 ? _c : (!(0, utils_1.isRuleConfigValue)(oA) ? oA.reason : undefined); | ||
const res = { | ||
severity, | ||
value, | ||
option, | ||
options, | ||
reason, | ||
}; | ||
deleteUndefProp(res); | ||
(0, utils_1.deleteUndefProp)(res); | ||
return res; | ||
@@ -80,3 +82,3 @@ } | ||
const res = (0, deepmerge_1.default)(a, b); | ||
deleteUndefProp(res); | ||
(0, utils_1.deleteUndefProp)(res); | ||
return res; | ||
@@ -137,8 +139,8 @@ } | ||
if (a == null) { | ||
return b || undefined; | ||
return b && optimizeRules(b); | ||
} | ||
if (b == null) { | ||
return a || undefined; | ||
return a && optimizeRules(a); | ||
} | ||
const res = { ...a }; | ||
const res = optimizeRules(a); | ||
for (const [key, rule] of Object.entries(b)) { | ||
@@ -150,27 +152,23 @@ const merged = mergeRule(res[key], rule); | ||
} | ||
deleteUndefProp(res); | ||
(0, utils_1.deleteUndefProp)(res); | ||
return res; | ||
} | ||
function isRuleConfigValue(v) { | ||
switch (typeof v) { | ||
case 'string': | ||
case 'number': | ||
case 'boolean': { | ||
return true; | ||
function optimizeRules(rules) { | ||
const res = {}; | ||
for (const [key, rule] of Object.entries(rules)) { | ||
const _rule = optimizeRule(rule); | ||
if (_rule != null) { | ||
res[key] = _rule; | ||
} | ||
} | ||
if (v === null) { | ||
return true; | ||
} | ||
return Array.isArray(v); | ||
return res; | ||
} | ||
function deleteUndefProp(obj) { | ||
if (!(0, is_plain_object_1.isPlainObject)(obj)) { | ||
function optimizeRule(rule) { | ||
if (rule === undefined) { | ||
return; | ||
} | ||
for (const key in obj) { | ||
if (obj[key] === undefined) { | ||
delete obj[key]; | ||
} | ||
if ((0, utils_1.isRuleConfigValue)(rule)) { | ||
return rule; | ||
} | ||
return (0, utils_1.cleanOptions)(rule); | ||
} |
@@ -93,3 +93,11 @@ import type { ParserOptions } from '@markuplint/ml-ast'; | ||
export type Rule<T extends RuleConfigValue, O = void> = RuleConfig<T, O> | T | boolean; | ||
/** | ||
* @deprecated | ||
*/ | ||
export type RuleV2<T extends RuleConfigValue, O = void> = RuleConfigV2<T, O> | T | boolean; | ||
export type AnyRule = Rule<RuleConfigValue, unknown>; | ||
/** | ||
* @deprecated | ||
*/ | ||
export type AnyRuleV2 = RuleV2<RuleConfigValue, unknown>; | ||
export interface Rules { | ||
@@ -101,5 +109,20 @@ [ruleName: string]: AnyRule; | ||
value?: T; | ||
option?: O; | ||
options?: O; | ||
reason?: string; | ||
}; | ||
/** | ||
* @deprecated | ||
*/ | ||
export type RuleConfigV2<T extends RuleConfigValue, O = void> = { | ||
severity?: Severity; | ||
value?: T; | ||
reason?: string; | ||
/** | ||
* Old property | ||
* | ||
* @deprecated | ||
* @see {this.options} | ||
*/ | ||
option?: O; | ||
}; | ||
export type Severity = 'error' | 'warning' | 'info'; | ||
@@ -151,3 +174,3 @@ export type RuleConfigValue = string | number | boolean | any[] | null; | ||
value: T; | ||
option: O; | ||
options: O; | ||
reason?: string; | ||
@@ -154,0 +177,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import type { AnyRule } from './types'; | ||
import type { AnyRule, AnyRuleV2, RuleConfig, RuleConfigV2, RuleConfigValue } from './types'; | ||
/** | ||
@@ -10,2 +10,10 @@ * Return undefined if the template doesn't include the variable that is set as a property in data. | ||
export declare function provideValue(template: string, data: Record<string, string>): string | undefined; | ||
export declare function exchangeValueOnRule(rule: AnyRule, data: Record<string, string>): AnyRule | undefined; | ||
export declare function exchangeValueOnRule(rule: AnyRule | AnyRuleV2, data: Record<string, string>): AnyRule | undefined; | ||
export declare function cleanOptions(rule: RuleConfig<RuleConfigValue, unknown> | RuleConfigV2<RuleConfigValue, unknown>): RuleConfig<RuleConfigValue, unknown>; | ||
export declare function isRuleConfigValue(v: any): v is RuleConfigValue; | ||
/** | ||
* | ||
* @param obj | ||
* @returns | ||
*/ | ||
export declare function deleteUndefProp(obj: any): void; |
103
lib/utils.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.exchangeValueOnRule = exports.provideValue = void 0; | ||
exports.deleteUndefProp = exports.isRuleConfigValue = exports.cleanOptions = exports.exchangeValueOnRule = exports.provideValue = void 0; | ||
const tslib_1 = require("tslib"); | ||
const is_plain_object_1 = require("is-plain-object"); | ||
const mustache_1 = tslib_1.__importDefault(require("mustache")); | ||
@@ -29,27 +30,85 @@ /** | ||
function exchangeValueOnRule(rule, data) { | ||
if (rule != null && typeof rule === 'object' && !Array.isArray(rule)) { | ||
if (rule.value != null) { | ||
rule = { | ||
...rule, | ||
value: exchangeValue(rule.value, data), | ||
}; | ||
if (isRuleConfigValue(rule)) { | ||
return exchangeValue(rule, data); | ||
} | ||
let result = cleanOptions(rule); | ||
if (result.value != null) { | ||
result = { | ||
...result, | ||
value: exchangeValue(result.value, data), | ||
}; | ||
} | ||
const options = extractOptions(result); | ||
if (options) { | ||
result = { | ||
...result, | ||
options: exchangeOption(options, data), | ||
}; | ||
} | ||
if (result.reason != null) { | ||
const exchangedValue = exchangeValue(result.reason, data); | ||
result = { | ||
...result, | ||
reason: exchangedValue ? `${exchangedValue}` : undefined, | ||
}; | ||
} | ||
deleteUndefProp(result); | ||
return result; | ||
} | ||
exports.exchangeValueOnRule = exchangeValueOnRule; | ||
function cleanOptions(rule) { | ||
const res = { | ||
severity: rule.severity, | ||
value: rule.value, | ||
options: extractOptions(rule), | ||
reason: rule.reason, | ||
}; | ||
deleteUndefProp(res); | ||
return res; | ||
} | ||
exports.cleanOptions = cleanOptions; | ||
function isRuleConfigValue(v) { | ||
switch (typeof v) { | ||
case 'string': | ||
case 'number': | ||
case 'boolean': { | ||
return true; | ||
} | ||
if (rule.option) { | ||
rule = { | ||
...rule, | ||
option: exchangeOption(rule.option, data), | ||
}; | ||
} | ||
if (v === null) { | ||
return true; | ||
} | ||
return Array.isArray(v); | ||
} | ||
exports.isRuleConfigValue = isRuleConfigValue; | ||
/** | ||
* | ||
* @param obj | ||
* @returns | ||
*/ | ||
function deleteUndefProp(obj) { | ||
if (!(0, is_plain_object_1.isPlainObject)(obj)) { | ||
return; | ||
} | ||
for (const key in obj) { | ||
if (obj[key] === undefined) { | ||
delete obj[key]; | ||
} | ||
if (rule.reason != null) { | ||
const exchangedValue = exchangeValue(rule.reason, data); | ||
rule = { | ||
...rule, | ||
reason: exchangedValue ? `${exchangedValue}` : undefined, | ||
}; | ||
} | ||
return rule; | ||
} | ||
return exchangeValue(rule, data); | ||
} | ||
exports.exchangeValueOnRule = exchangeValueOnRule; | ||
exports.deleteUndefProp = deleteUndefProp; | ||
/** | ||
* Return options from `options` or `option` | ||
* | ||
* @param rule | ||
* @returns | ||
*/ | ||
function extractOptions(rule) { | ||
if ('options' in rule && rule.options) { | ||
return rule.options; | ||
} | ||
if ('option' in rule && rule.option) { | ||
return rule.option; | ||
} | ||
} | ||
function exchangeValue(rule, data) { | ||
@@ -56,0 +115,0 @@ if (rule == null) { |
{ | ||
"name": "@markuplint/ml-config", | ||
"version": "3.0.0-canary.34+382d1365", | ||
"version": "3.0.0-dev.24+f55f5eff", | ||
"description": "JSON Schema and TypeScript types of markuplint configure JSON", | ||
@@ -19,7 +19,7 @@ "repository": "git@github.com:markuplint/markuplint.git", | ||
"devDependencies": { | ||
"@markuplint/ml-ast": "3.0.0-canary.69+382d1365", | ||
"@types/mustache": "^4.2.1" | ||
"@markuplint/ml-ast": "3.0.0-rc.0", | ||
"@types/mustache": "^4.2.2" | ||
}, | ||
"dependencies": { | ||
"@markuplint/selector": "3.0.0-canary.2421+382d1365", | ||
"@markuplint/selector": "3.0.0-dev.24+f55f5eff", | ||
"deepmerge": "^4.2.2", | ||
@@ -29,3 +29,3 @@ "is-plain-object": "^5.0.0", | ||
}, | ||
"gitHead": "382d13653071bd02210d5430403d1a87c840398c" | ||
"gitHead": "f55f5eff289296feba26f20b0c085e0528c80ac4" | ||
} |
@@ -12,3 +12,3 @@ # @markuplint/ml-config | ||
```sh | ||
```shell | ||
$ npm install @markuplint/ml-config | ||
@@ -15,0 +15,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
542
73380