Permalink
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/eslint/lib/rules/sort-keys.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
187 lines (163 sloc)
5.3 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileoverview Rule to require object keys to be sorted | |
* @author Toru Nagashima | |
*/ | |
"use strict"; | |
//------------------------------------------------------------------------------ | |
// Requirements | |
//------------------------------------------------------------------------------ | |
const astUtils = require("./utils/ast-utils"), | |
naturalCompare = require("natural-compare"); | |
//------------------------------------------------------------------------------ | |
// Helpers | |
//------------------------------------------------------------------------------ | |
/** | |
* Gets the property name of the given `Property` node. | |
* | |
* - If the property's key is an `Identifier` node, this returns the key's name | |
* whether it's a computed property or not. | |
* - If the property has a static name, this returns the static name. | |
* - Otherwise, this returns null. | |
* @param {ASTNode} node The `Property` node to get. | |
* @returns {string|null} The property name or null. | |
* @private | |
*/ | |
function getPropertyName(node) { | |
const staticName = astUtils.getStaticPropertyName(node); | |
if (staticName !== null) { | |
return staticName; | |
} | |
return node.key.name || null; | |
} | |
/** | |
* Functions which check that the given 2 names are in specific order. | |
* | |
* Postfix `I` is meant insensitive. | |
* Postfix `N` is meant natural. | |
* @private | |
*/ | |
const isValidOrders = { | |
asc(a, b) { | |
return a <= b; | |
}, | |
ascI(a, b) { | |
return a.toLowerCase() <= b.toLowerCase(); | |
}, | |
ascN(a, b) { | |
return naturalCompare(a, b) <= 0; | |
}, | |
ascIN(a, b) { | |
return naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0; | |
}, | |
desc(a, b) { | |
return isValidOrders.asc(b, a); | |
}, | |
descI(a, b) { | |
return isValidOrders.ascI(b, a); | |
}, | |
descN(a, b) { | |
return isValidOrders.ascN(b, a); | |
}, | |
descIN(a, b) { | |
return isValidOrders.ascIN(b, a); | |
} | |
}; | |
//------------------------------------------------------------------------------ | |
// Rule Definition | |
//------------------------------------------------------------------------------ | |
module.exports = { | |
meta: { | |
type: "suggestion", | |
docs: { | |
description: "require object keys to be sorted", | |
category: "Stylistic Issues", | |
recommended: false, | |
url: "https://eslint.org/docs/rules/sort-keys" | |
}, | |
schema: [ | |
{ | |
enum: ["asc", "desc"] | |
}, | |
{ | |
type: "object", | |
properties: { | |
caseSensitive: { | |
type: "boolean", | |
default: true | |
}, | |
natural: { | |
type: "boolean", | |
default: false | |
}, | |
minKeys: { | |
type: "integer", | |
minimum: 2, | |
default: 2 | |
} | |
}, | |
additionalProperties: false | |
} | |
], | |
messages: { | |
sortKeys: "Expected object keys to be in {{natural}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'." | |
} | |
}, | |
create(context) { | |
// Parse options. | |
const order = context.options[0] || "asc"; | |
const options = context.options[1]; | |
const insensitive = options && options.caseSensitive === false; | |
const natural = options && options.natural; | |
const minKeys = options && options.minKeys; | |
const isValidOrder = isValidOrders[ | |
order + (insensitive ? "I" : "") + (natural ? "N" : "") | |
]; | |
// The stack to save the previous property's name for each object literals. | |
let stack = null; | |
return { | |
ObjectExpression(node) { | |
stack = { | |
upper: stack, | |
prevName: null, | |
numKeys: node.properties.length | |
}; | |
}, | |
"ObjectExpression:exit"() { | |
stack = stack.upper; | |
}, | |
SpreadElement(node) { | |
if (node.parent.type === "ObjectExpression") { | |
stack.prevName = null; | |
} | |
}, | |
Property(node) { | |
if (node.parent.type === "ObjectPattern") { | |
return; | |
} | |
const prevName = stack.prevName; | |
const numKeys = stack.numKeys; | |
const thisName = getPropertyName(node); | |
if (thisName !== null) { | |
stack.prevName = thisName; | |
} | |
if (prevName === null || thisName === null || numKeys < minKeys) { | |
return; | |
} | |
if (!isValidOrder(prevName, thisName)) { | |
context.report({ | |
node, | |
loc: node.key.loc, | |
messageId: "sortKeys", | |
data: { | |
thisName, | |
prevName, | |
order, | |
insensitive: insensitive ? "insensitive " : "", | |
natural: natural ? "natural " : "" | |
} | |
}); | |
} | |
} | |
}; | |
} | |
}; |