eslint-plugin-perfectionist 4.2.0 → 4.3.0
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.
- package/dist/alphabet.d.ts +176 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/dist/rules/sort-array-includes.js +2 -0
- package/dist/rules/sort-classes.js +6 -2
- package/dist/rules/sort-decorators.js +4 -0
- package/dist/rules/sort-enums.js +5 -0
- package/dist/rules/sort-exports.js +4 -0
- package/dist/rules/sort-heritage-clauses.js +4 -0
- package/dist/rules/sort-imports.js +5 -0
- package/dist/rules/sort-interfaces.js +1 -0
- package/dist/rules/sort-intersection-types.js +4 -0
- package/dist/rules/sort-jsx-props.js +4 -0
- package/dist/rules/sort-maps.js +4 -0
- package/dist/rules/sort-modules.js +6 -2
- package/dist/rules/sort-named-exports.js +4 -0
- package/dist/rules/sort-named-imports.js +4 -0
- package/dist/rules/sort-object-types.js +10 -11
- package/dist/rules/sort-objects.js +32 -5
- package/dist/rules/sort-switch-case.js +4 -0
- package/dist/rules/sort-union-types.js +4 -0
- package/dist/rules/sort-variable-declarations.js +4 -0
- package/dist/utils/alphabet.js +385 -0
- package/dist/utils/common-json-schemas.js +16 -1
- package/dist/utils/compare.js +88 -38
- package/dist/utils/convert-boolean-to-sign.js +4 -0
- package/dist/{rules → utils}/get-custom-groups-compare-options.js +1 -0
- package/dist/utils/get-matching-context-options.js +18 -0
- package/dist/utils/get-settings.js +1 -0
- package/dist/utils/is-node-function-type.js +15 -0
- package/dist/utils/validate-custom-sort-configuration.js +11 -0
- package/dist/{rules → utils}/validate-generated-groups-configuration.js +1 -1
- package/package.json +7 -3
- package/readme.md +4 -3
|
@@ -5,13 +5,15 @@ Object.defineProperties(exports, {
|
|
|
5
5
|
})
|
|
6
6
|
const commonJsonSchemas = require('../utils/common-json-schemas.js')
|
|
7
7
|
const validateNewlinesAndPartitionConfiguration = require('../utils/validate-newlines-and-partition-configuration.js')
|
|
8
|
-
const validateGeneratedGroupsConfiguration = require('
|
|
9
|
-
const
|
|
8
|
+
const validateGeneratedGroupsConfiguration = require('../utils/validate-generated-groups-configuration.js')
|
|
9
|
+
const validateCustomSortConfiguration = require('../utils/validate-custom-sort-configuration.js')
|
|
10
|
+
const getCustomGroupsCompareOptions = require('../utils/get-custom-groups-compare-options.js')
|
|
10
11
|
const generatePredefinedGroups = require('../utils/generate-predefined-groups.js')
|
|
11
12
|
const getEslintDisabledLines = require('../utils/get-eslint-disabled-lines.js')
|
|
12
13
|
const sortObjectTypes_types = require('./sort-object-types.types.js')
|
|
13
14
|
const isNodeEslintDisabled = require('../utils/is-node-eslint-disabled.js')
|
|
14
15
|
const isPartitionComment = require('../utils/is-partition-comment.js')
|
|
16
|
+
const isNodeFunctionType = require('../utils/is-node-function-type.js')
|
|
15
17
|
const sortNodesByGroups = require('../utils/sort-nodes-by-groups.js')
|
|
16
18
|
const getCommentsBefore = require('../utils/get-comments-before.js')
|
|
17
19
|
const makeNewlinesFixes = require('../utils/make-newlines-fixes.js')
|
|
@@ -43,6 +45,7 @@ let defaultOptions = {
|
|
|
43
45
|
ignoreCase: true,
|
|
44
46
|
customGroups: {},
|
|
45
47
|
locales: 'en-US',
|
|
48
|
+
alphabet: '',
|
|
46
49
|
order: 'asc',
|
|
47
50
|
groups: [],
|
|
48
51
|
}
|
|
@@ -79,6 +82,7 @@ let jsonSchema = {
|
|
|
79
82
|
specialCharacters: commonJsonSchemas.specialCharactersJsonSchema,
|
|
80
83
|
newlinesBetween: commonJsonSchemas.newlinesBetweenJsonSchema,
|
|
81
84
|
ignoreCase: commonJsonSchemas.ignoreCaseJsonSchema,
|
|
85
|
+
alphabet: commonJsonSchemas.alphabetJsonSchema,
|
|
82
86
|
locales: commonJsonSchemas.localesJsonSchema,
|
|
83
87
|
groups: commonJsonSchemas.groupsJsonSchema,
|
|
84
88
|
order: commonJsonSchemas.orderJsonSchema,
|
|
@@ -143,6 +147,7 @@ let sortObjectTypeElements = ({
|
|
|
143
147
|
settings,
|
|
144
148
|
defaultOptions,
|
|
145
149
|
)
|
|
150
|
+
validateCustomSortConfiguration.validateCustomSortConfiguration(options)
|
|
146
151
|
validateGeneratedGroupsConfiguration.validateGeneratedGroupsConfiguration({
|
|
147
152
|
customGroups: options.customGroups,
|
|
148
153
|
selectors: sortObjectTypes_types.allSelectors,
|
|
@@ -166,7 +171,7 @@ let sortObjectTypeElements = ({
|
|
|
166
171
|
})
|
|
167
172
|
let formattedMembers = elements.reduce(
|
|
168
173
|
(accumulator, typeElement) => {
|
|
169
|
-
var _a, _b, _c, _d
|
|
174
|
+
var _a, _b, _c, _d
|
|
170
175
|
if (typeElement.type === 'TSCallSignatureDeclaration') {
|
|
171
176
|
accumulator.push([])
|
|
172
177
|
return accumulator
|
|
@@ -216,13 +221,7 @@ let sortObjectTypeElements = ({
|
|
|
216
221
|
if (typeElement.type === 'TSIndexSignature') {
|
|
217
222
|
selectors.push('index-signature')
|
|
218
223
|
}
|
|
219
|
-
if (
|
|
220
|
-
typeElement.type === 'TSMethodSignature' ||
|
|
221
|
-
(typeElement.type === 'TSPropertySignature' &&
|
|
222
|
-
((_d = typeElement.typeAnnotation) == null
|
|
223
|
-
? void 0
|
|
224
|
-
: _d.typeAnnotation.type) === 'TSFunctionType')
|
|
225
|
-
) {
|
|
224
|
+
if (isNodeFunctionType.isNodeFunctionType(typeElement)) {
|
|
226
225
|
selectors.push('method')
|
|
227
226
|
}
|
|
228
227
|
if (typeElement.loc.start.line !== typeElement.loc.end.line) {
|
|
@@ -304,7 +303,7 @@ let sortObjectTypeElements = ({
|
|
|
304
303
|
) {
|
|
305
304
|
accumulator.push([])
|
|
306
305
|
}
|
|
307
|
-
;(
|
|
306
|
+
;(_d = accumulator.at(-1)) == null ? void 0 : _d.push(sortingNode)
|
|
308
307
|
return accumulator
|
|
309
308
|
},
|
|
310
309
|
[[]],
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
const commonJsonSchemas = require('../utils/common-json-schemas.js')
|
|
3
3
|
const sortNodesByDependencies = require('../utils/sort-nodes-by-dependencies.js')
|
|
4
4
|
const validateNewlinesAndPartitionConfiguration = require('../utils/validate-newlines-and-partition-configuration.js')
|
|
5
|
+
const validateCustomSortConfiguration = require('../utils/validate-custom-sort-configuration.js')
|
|
5
6
|
const validateGroupsConfiguration = require('../utils/validate-groups-configuration.js')
|
|
7
|
+
const getMatchingContextOptions = require('../utils/get-matching-context-options.js')
|
|
6
8
|
const getEslintDisabledLines = require('../utils/get-eslint-disabled-lines.js')
|
|
7
9
|
const isNodeEslintDisabled = require('../utils/is-node-eslint-disabled.js')
|
|
8
10
|
const isPartitionComment = require('../utils/is-partition-comment.js')
|
|
@@ -33,11 +35,13 @@ let defaultOptions = {
|
|
|
33
35
|
objectDeclarations: true,
|
|
34
36
|
styledComponents: true,
|
|
35
37
|
destructureOnly: false,
|
|
38
|
+
useConfigurationIf: {},
|
|
36
39
|
type: 'alphabetical',
|
|
37
40
|
ignorePattern: [],
|
|
38
41
|
ignoreCase: true,
|
|
39
42
|
customGroups: {},
|
|
40
43
|
locales: 'en-US',
|
|
44
|
+
alphabet: '',
|
|
41
45
|
order: 'asc',
|
|
42
46
|
groups: [],
|
|
43
47
|
}
|
|
@@ -48,11 +52,20 @@ const sortObjects = createEslintRule.createEslintRule({
|
|
|
48
52
|
return
|
|
49
53
|
}
|
|
50
54
|
let settings = getSettings.getSettings(context.settings)
|
|
55
|
+
let sourceCode = getSourceCode.getSourceCode(context)
|
|
56
|
+
let matchedContextOptions =
|
|
57
|
+
getMatchingContextOptions.getMatchingContextOptions({
|
|
58
|
+
nodeNames: nodeObject.properties
|
|
59
|
+
.map(property => getNodeName({ sourceCode, property }))
|
|
60
|
+
.filter(nodeName => nodeName !== null),
|
|
61
|
+
contextOptions: context.options,
|
|
62
|
+
})
|
|
51
63
|
let options = complete.complete(
|
|
52
|
-
|
|
64
|
+
matchedContextOptions,
|
|
53
65
|
settings,
|
|
54
66
|
defaultOptions,
|
|
55
67
|
)
|
|
68
|
+
validateCustomSortConfiguration.validateCustomSortConfiguration(options)
|
|
56
69
|
validateGroupsConfiguration.validateGroupsConfiguration(
|
|
57
70
|
options.groups,
|
|
58
71
|
['multiline', 'method', 'unknown'],
|
|
@@ -130,7 +143,6 @@ const sortObjects = createEslintRule.createEslintRule({
|
|
|
130
143
|
) {
|
|
131
144
|
return
|
|
132
145
|
}
|
|
133
|
-
let sourceCode = getSourceCode.getSourceCode(context)
|
|
134
146
|
let eslintDisabledLines = getEslintDisabledLines.getEslintDisabledLines({
|
|
135
147
|
ruleName: context.id,
|
|
136
148
|
sourceCode,
|
|
@@ -382,8 +394,8 @@ const sortObjects = createEslintRule.createEslintRule({
|
|
|
382
394
|
}
|
|
383
395
|
},
|
|
384
396
|
meta: {
|
|
385
|
-
schema:
|
|
386
|
-
{
|
|
397
|
+
schema: {
|
|
398
|
+
items: {
|
|
387
399
|
properties: {
|
|
388
400
|
destructuredObjects: {
|
|
389
401
|
oneOf: [
|
|
@@ -430,10 +442,12 @@ const sortObjects = createEslintRule.createEslintRule({
|
|
|
430
442
|
type: 'boolean',
|
|
431
443
|
},
|
|
432
444
|
partitionByNewLine: commonJsonSchemas.partitionByNewLineJsonSchema,
|
|
445
|
+
useConfigurationIf: commonJsonSchemas.useConfigurationIfJsonSchema,
|
|
433
446
|
specialCharacters: commonJsonSchemas.specialCharactersJsonSchema,
|
|
434
447
|
newlinesBetween: commonJsonSchemas.newlinesBetweenJsonSchema,
|
|
435
448
|
customGroups: commonJsonSchemas.customGroupsJsonSchema,
|
|
436
449
|
ignoreCase: commonJsonSchemas.ignoreCaseJsonSchema,
|
|
450
|
+
alphabet: commonJsonSchemas.alphabetJsonSchema,
|
|
437
451
|
locales: commonJsonSchemas.localesJsonSchema,
|
|
438
452
|
groups: commonJsonSchemas.groupsJsonSchema,
|
|
439
453
|
order: commonJsonSchemas.orderJsonSchema,
|
|
@@ -442,7 +456,9 @@ const sortObjects = createEslintRule.createEslintRule({
|
|
|
442
456
|
additionalProperties: false,
|
|
443
457
|
type: 'object',
|
|
444
458
|
},
|
|
445
|
-
|
|
459
|
+
uniqueItems: true,
|
|
460
|
+
type: 'array',
|
|
461
|
+
},
|
|
446
462
|
messages: {
|
|
447
463
|
unexpectedObjectsGroupOrder:
|
|
448
464
|
'Expected "{{right}}" ({{rightGroup}}) to come before "{{left}}" ({{leftGroup}}).',
|
|
@@ -465,4 +481,15 @@ const sortObjects = createEslintRule.createEslintRule({
|
|
|
465
481
|
defaultOptions: [defaultOptions],
|
|
466
482
|
name: 'sort-objects',
|
|
467
483
|
})
|
|
484
|
+
let getNodeName = ({ sourceCode, property }) => {
|
|
485
|
+
if (property.type === 'SpreadElement' || property.type === 'RestElement') {
|
|
486
|
+
return null
|
|
487
|
+
}
|
|
488
|
+
if (property.key.type === 'Identifier') {
|
|
489
|
+
return property.key.name
|
|
490
|
+
} else if (property.key.type === 'Literal') {
|
|
491
|
+
return `${property.key.value}`
|
|
492
|
+
}
|
|
493
|
+
return sourceCode.getText(property.key)
|
|
494
|
+
}
|
|
468
495
|
module.exports = sortObjects
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const commonJsonSchemas = require('../utils/common-json-schemas.js')
|
|
3
|
+
const validateCustomSortConfiguration = require('../utils/validate-custom-sort-configuration.js')
|
|
3
4
|
const makeCommentAfterFixes = require('../utils/make-comment-after-fixes.js')
|
|
4
5
|
const createEslintRule = require('../utils/create-eslint-rule.js')
|
|
5
6
|
const getSourceCode = require('../utils/get-source-code.js')
|
|
@@ -16,6 +17,7 @@ let defaultOptions = {
|
|
|
16
17
|
type: 'alphabetical',
|
|
17
18
|
ignoreCase: true,
|
|
18
19
|
locales: 'en-US',
|
|
20
|
+
alphabet: '',
|
|
19
21
|
order: 'asc',
|
|
20
22
|
}
|
|
21
23
|
const sortSwitchCase = createEslintRule.createEslintRule({
|
|
@@ -30,6 +32,7 @@ const sortSwitchCase = createEslintRule.createEslintRule({
|
|
|
30
32
|
settings,
|
|
31
33
|
defaultOptions,
|
|
32
34
|
)
|
|
35
|
+
validateCustomSortConfiguration.validateCustomSortConfiguration(options)
|
|
33
36
|
let sourceCode = getSourceCode.getSourceCode(context)
|
|
34
37
|
let isDiscriminantTrue =
|
|
35
38
|
switchNode.discriminant.type === 'Literal' &&
|
|
@@ -218,6 +221,7 @@ const sortSwitchCase = createEslintRule.createEslintRule({
|
|
|
218
221
|
properties: {
|
|
219
222
|
specialCharacters: commonJsonSchemas.specialCharactersJsonSchema,
|
|
220
223
|
ignoreCase: commonJsonSchemas.ignoreCaseJsonSchema,
|
|
224
|
+
alphabet: commonJsonSchemas.alphabetJsonSchema,
|
|
221
225
|
locales: commonJsonSchemas.localesJsonSchema,
|
|
222
226
|
order: commonJsonSchemas.orderJsonSchema,
|
|
223
227
|
type: commonJsonSchemas.typeJsonSchema,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const commonJsonSchemas = require('../utils/common-json-schemas.js')
|
|
3
3
|
const validateNewlinesAndPartitionConfiguration = require('../utils/validate-newlines-and-partition-configuration.js')
|
|
4
|
+
const validateCustomSortConfiguration = require('../utils/validate-custom-sort-configuration.js')
|
|
4
5
|
const validateGroupsConfiguration = require('../utils/validate-groups-configuration.js')
|
|
5
6
|
const getEslintDisabledLines = require('../utils/get-eslint-disabled-lines.js')
|
|
6
7
|
const isNodeEslintDisabled = require('../utils/is-node-eslint-disabled.js')
|
|
@@ -28,6 +29,7 @@ let defaultOptions = {
|
|
|
28
29
|
type: 'alphabetical',
|
|
29
30
|
ignoreCase: true,
|
|
30
31
|
locales: 'en-US',
|
|
32
|
+
alphabet: '',
|
|
31
33
|
order: 'asc',
|
|
32
34
|
groups: [],
|
|
33
35
|
}
|
|
@@ -40,6 +42,7 @@ const sortUnionTypes = createEslintRule.createEslintRule({
|
|
|
40
42
|
settings,
|
|
41
43
|
defaultOptions,
|
|
42
44
|
)
|
|
45
|
+
validateCustomSortConfiguration.validateCustomSortConfiguration(options)
|
|
43
46
|
validateGroupsConfiguration.validateGroupsConfiguration(
|
|
44
47
|
options.groups,
|
|
45
48
|
[
|
|
@@ -249,6 +252,7 @@ const sortUnionTypes = createEslintRule.createEslintRule({
|
|
|
249
252
|
specialCharacters: commonJsonSchemas.specialCharactersJsonSchema,
|
|
250
253
|
newlinesBetween: commonJsonSchemas.newlinesBetweenJsonSchema,
|
|
251
254
|
ignoreCase: commonJsonSchemas.ignoreCaseJsonSchema,
|
|
255
|
+
alphabet: commonJsonSchemas.alphabetJsonSchema,
|
|
252
256
|
locales: commonJsonSchemas.localesJsonSchema,
|
|
253
257
|
groups: commonJsonSchemas.groupsJsonSchema,
|
|
254
258
|
order: commonJsonSchemas.orderJsonSchema,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const commonJsonSchemas = require('../utils/common-json-schemas.js')
|
|
3
3
|
const sortNodesByDependencies = require('../utils/sort-nodes-by-dependencies.js')
|
|
4
|
+
const validateCustomSortConfiguration = require('../utils/validate-custom-sort-configuration.js')
|
|
4
5
|
const getEslintDisabledLines = require('../utils/get-eslint-disabled-lines.js')
|
|
5
6
|
const isNodeEslintDisabled = require('../utils/is-node-eslint-disabled.js')
|
|
6
7
|
const isPartitionComment = require('../utils/is-partition-comment.js')
|
|
@@ -23,6 +24,7 @@ let defaultOptions = {
|
|
|
23
24
|
type: 'alphabetical',
|
|
24
25
|
ignoreCase: true,
|
|
25
26
|
locales: 'en-US',
|
|
27
|
+
alphabet: '',
|
|
26
28
|
order: 'asc',
|
|
27
29
|
}
|
|
28
30
|
const sortVariableDeclarations = createEslintRule.createEslintRule({
|
|
@@ -37,6 +39,7 @@ const sortVariableDeclarations = createEslintRule.createEslintRule({
|
|
|
37
39
|
settings,
|
|
38
40
|
defaultOptions,
|
|
39
41
|
)
|
|
42
|
+
validateCustomSortConfiguration.validateCustomSortConfiguration(options)
|
|
40
43
|
let sourceCode = getSourceCode.getSourceCode(context)
|
|
41
44
|
let eslintDisabledLines = getEslintDisabledLines.getEslintDisabledLines({
|
|
42
45
|
ruleName: context.id,
|
|
@@ -231,6 +234,7 @@ const sortVariableDeclarations = createEslintRule.createEslintRule({
|
|
|
231
234
|
partitionByNewLine: commonJsonSchemas.partitionByNewLineJsonSchema,
|
|
232
235
|
specialCharacters: commonJsonSchemas.specialCharactersJsonSchema,
|
|
233
236
|
ignoreCase: commonJsonSchemas.ignoreCaseJsonSchema,
|
|
237
|
+
alphabet: commonJsonSchemas.alphabetJsonSchema,
|
|
234
238
|
locales: commonJsonSchemas.localesJsonSchema,
|
|
235
239
|
order: commonJsonSchemas.orderJsonSchema,
|
|
236
240
|
type: commonJsonSchemas.typeJsonSchema,
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
var __defProp = Object.defineProperty
|
|
3
|
+
var __defNormalProp = (obj, key, value) =>
|
|
4
|
+
key in obj
|
|
5
|
+
? __defProp(obj, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value,
|
|
10
|
+
})
|
|
11
|
+
: (obj[key] = value)
|
|
12
|
+
var __publicField = (obj, key, value) =>
|
|
13
|
+
__defNormalProp(obj, typeof key !== 'symbol' ? key + '' : key, value)
|
|
14
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
|
|
15
|
+
const naturalOrderby = require('natural-orderby')
|
|
16
|
+
const convertBooleanToSign = require('./convert-boolean-to-sign.js')
|
|
17
|
+
class Alphabet {
|
|
18
|
+
constructor(characters) {
|
|
19
|
+
__publicField(this, '_characters', [])
|
|
20
|
+
this._characters = characters
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generates an alphabet from the given characters.
|
|
24
|
+
* @param {string|string[]} values - The characters to generate the alphabet from
|
|
25
|
+
* @returns {Alphabet} - The wrapped alphabet
|
|
26
|
+
*/
|
|
27
|
+
static generateFrom(values) {
|
|
28
|
+
let arrayValues = typeof values === 'string' ? [...values] : values
|
|
29
|
+
if (arrayValues.length !== new Set(arrayValues).size) {
|
|
30
|
+
throw new Error('The alphabet must not contain repeated characters')
|
|
31
|
+
}
|
|
32
|
+
if (arrayValues.some(value => value.length !== 1)) {
|
|
33
|
+
throw new Error('The alphabet must contain single characters')
|
|
34
|
+
}
|
|
35
|
+
return new Alphabet(
|
|
36
|
+
arrayValues.map(value =>
|
|
37
|
+
Alphabet._convertCodepointToCharacter(value.codePointAt(0)),
|
|
38
|
+
),
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generates an alphabet containing relevant characters from the Unicode
|
|
43
|
+
* standard. Contains the Unicode planes 0 and 1.
|
|
44
|
+
* @returns {Alphabet} - The generated alphabet
|
|
45
|
+
*/
|
|
46
|
+
static generateRecommendedAlphabet() {
|
|
47
|
+
return Alphabet._generateAlphabetToRange(131071 + 1)
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generates an alphabet containing all characters from the Unicode standard
|
|
51
|
+
* except for irrelevant Unicode planes.
|
|
52
|
+
* Contains the Unicode planes 0, 1, 2 and 3.
|
|
53
|
+
* @returns {Alphabet} - The generated alphabet
|
|
54
|
+
*/
|
|
55
|
+
static generateCompleteAlphabet() {
|
|
56
|
+
return Alphabet._generateAlphabetToRange(262143 + 1)
|
|
57
|
+
}
|
|
58
|
+
static _convertCodepointToCharacter(codePoint) {
|
|
59
|
+
let character = String.fromCodePoint(codePoint)
|
|
60
|
+
let lowercaseCharacter = character.toLowerCase()
|
|
61
|
+
let uppercaseCharacter = character.toUpperCase()
|
|
62
|
+
return {
|
|
63
|
+
value: character,
|
|
64
|
+
codePoint,
|
|
65
|
+
...(lowercaseCharacter === character
|
|
66
|
+
? null
|
|
67
|
+
: {
|
|
68
|
+
lowercaseCharacterCodePoint: lowercaseCharacter.codePointAt(0),
|
|
69
|
+
}),
|
|
70
|
+
...(uppercaseCharacter === character
|
|
71
|
+
? null
|
|
72
|
+
: {
|
|
73
|
+
uppercaseCharacterCodePoint: uppercaseCharacter.codePointAt(0),
|
|
74
|
+
}),
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generates an alphabet containing relevant characters from the Unicode
|
|
79
|
+
* standard.
|
|
80
|
+
* @param {number} maxCodePoint - The maximum code point to generate the
|
|
81
|
+
* alphabet to
|
|
82
|
+
* @returns {Alphabet} - The generated alphabet
|
|
83
|
+
*/
|
|
84
|
+
static _generateAlphabetToRange(maxCodePoint) {
|
|
85
|
+
let totalCharacters = Array.from({ length: maxCodePoint }, (_, i) =>
|
|
86
|
+
Alphabet._convertCodepointToCharacter(i),
|
|
87
|
+
)
|
|
88
|
+
return new Alphabet(totalCharacters)
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* For each character with a lower and upper case, permutes the two cases
|
|
92
|
+
* so that the alphabet is ordered by the case priority entered.
|
|
93
|
+
* @param {string} casePriority - The case to prioritize
|
|
94
|
+
* @returns {Alphabet} - The same alphabet instance with the cases prioritized
|
|
95
|
+
* @example
|
|
96
|
+
* Alphabet.generateFrom('aAbBcdCD')
|
|
97
|
+
* .prioritizeCase('uppercase')
|
|
98
|
+
* // Returns 'AaBbCDcd'
|
|
99
|
+
*/
|
|
100
|
+
prioritizeCase(casePriority) {
|
|
101
|
+
let charactersWithCase = this._getCharactersWithCase()
|
|
102
|
+
let parsedIndexes = /* @__PURE__ */ new Set()
|
|
103
|
+
let indexByCodePoints = this._characters.reduce(
|
|
104
|
+
(indexByCodePoint, character, index) => {
|
|
105
|
+
indexByCodePoint[character.codePoint] = index
|
|
106
|
+
return indexByCodePoint
|
|
107
|
+
},
|
|
108
|
+
{},
|
|
109
|
+
)
|
|
110
|
+
for (let { character, index } of charactersWithCase) {
|
|
111
|
+
if (parsedIndexes.has(index)) {
|
|
112
|
+
continue
|
|
113
|
+
}
|
|
114
|
+
parsedIndexes.add(index)
|
|
115
|
+
let otherCharacterIndex =
|
|
116
|
+
indexByCodePoints[
|
|
117
|
+
character.uppercaseCharacterCodePoint ??
|
|
118
|
+
character.lowercaseCharacterCodePoint
|
|
119
|
+
]
|
|
120
|
+
if (otherCharacterIndex === void 0) {
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
parsedIndexes.add(otherCharacterIndex)
|
|
124
|
+
let isCharacterUppercase = !character.uppercaseCharacterCodePoint
|
|
125
|
+
if (isCharacterUppercase) {
|
|
126
|
+
if (
|
|
127
|
+
(casePriority === 'uppercase' && index < otherCharacterIndex) ||
|
|
128
|
+
(casePriority === 'lowercase' && index > otherCharacterIndex)
|
|
129
|
+
) {
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
if (
|
|
134
|
+
(casePriority === 'uppercase' && index > otherCharacterIndex) ||
|
|
135
|
+
(casePriority === 'lowercase' && index < otherCharacterIndex)
|
|
136
|
+
) {
|
|
137
|
+
continue
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
this._characters[index] = this._characters[otherCharacterIndex]
|
|
141
|
+
this._characters[otherCharacterIndex] = character
|
|
142
|
+
}
|
|
143
|
+
return this
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Adds specific characters to the end of the alphabet.
|
|
147
|
+
* @param {string|string[]} values - The characters to push to the alphabet
|
|
148
|
+
* @returns {Alphabet} - The same alphabet instance without the specified
|
|
149
|
+
* characters
|
|
150
|
+
* @example
|
|
151
|
+
* Alphabet.generateFrom('ab')
|
|
152
|
+
* .pushCharacters('cd')
|
|
153
|
+
* // Returns 'abcd'
|
|
154
|
+
*/
|
|
155
|
+
pushCharacters(values) {
|
|
156
|
+
let arrayValues = typeof values === 'string' ? [...values] : values
|
|
157
|
+
let valuesSet = new Set(arrayValues)
|
|
158
|
+
let valuesAlreadyExisting = this._characters.filter(({ value }) =>
|
|
159
|
+
valuesSet.has(value),
|
|
160
|
+
)
|
|
161
|
+
if (valuesAlreadyExisting.length > 0) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`The alphabet already contains the characters ${valuesAlreadyExisting
|
|
164
|
+
.slice(0, 5)
|
|
165
|
+
.map(({ value }) => value)
|
|
166
|
+
.join(', ')}`,
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
if (arrayValues.some(value => value.length !== 1)) {
|
|
170
|
+
throw new Error('Only single characters may be pushed')
|
|
171
|
+
}
|
|
172
|
+
this._characters.push(
|
|
173
|
+
...[...valuesSet].map(value =>
|
|
174
|
+
Alphabet._convertCodepointToCharacter(value.codePointAt(0)),
|
|
175
|
+
),
|
|
176
|
+
)
|
|
177
|
+
return this
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Permutes characters with cases so that all characters with the entered case
|
|
181
|
+
* are put before the other characters.
|
|
182
|
+
* @param {string} caseToComeFirst - The case to put before the other
|
|
183
|
+
* characters
|
|
184
|
+
* @returns {Alphabet} - The same alphabet instance with all characters with
|
|
185
|
+
* case before all the characters with the other case
|
|
186
|
+
*/
|
|
187
|
+
placeAllWithCaseBeforeAllWithOtherCase(caseToComeFirst) {
|
|
188
|
+
let charactersWithCase = this._getCharactersWithCase()
|
|
189
|
+
let orderedCharacters = [
|
|
190
|
+
...charactersWithCase.filter(character =>
|
|
191
|
+
caseToComeFirst === 'uppercase'
|
|
192
|
+
? !character.character.uppercaseCharacterCodePoint
|
|
193
|
+
: character.character.uppercaseCharacterCodePoint,
|
|
194
|
+
),
|
|
195
|
+
...charactersWithCase.filter(character =>
|
|
196
|
+
caseToComeFirst === 'uppercase'
|
|
197
|
+
? character.character.uppercaseCharacterCodePoint
|
|
198
|
+
: !character.character.uppercaseCharacterCodePoint,
|
|
199
|
+
),
|
|
200
|
+
]
|
|
201
|
+
for (let [i, element] of charactersWithCase.entries()) {
|
|
202
|
+
this._characters[element.index] = orderedCharacters[i].character
|
|
203
|
+
}
|
|
204
|
+
return this
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Places a specific character right before another character in the alphabet.
|
|
208
|
+
* @param {object} params - The parameters for the operation
|
|
209
|
+
* @param {string} params.characterBefore - The character to come before
|
|
210
|
+
* characterAfter
|
|
211
|
+
* @param {string} params.characterAfter - The target character
|
|
212
|
+
* @returns {Alphabet} - The same alphabet instance with the specific
|
|
213
|
+
* character prioritized
|
|
214
|
+
* @example
|
|
215
|
+
* Alphabet.generateFrom('ab-cd/')
|
|
216
|
+
* .placeCharacterBefore({ characterBefore: '/', characterAfter: '-' })
|
|
217
|
+
* // Returns 'ab/-cd'
|
|
218
|
+
*/
|
|
219
|
+
placeCharacterBefore({ characterBefore, characterAfter }) {
|
|
220
|
+
return this._placeCharacterBeforeOrAfter({
|
|
221
|
+
characterBefore,
|
|
222
|
+
characterAfter,
|
|
223
|
+
type: 'before',
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Places a specific character right after another character in the alphabet.
|
|
228
|
+
* @param {object} params - The parameters for the operation
|
|
229
|
+
* @param {string} params.characterBefore - The target character
|
|
230
|
+
* @param {string} params.characterAfter - The character to come after
|
|
231
|
+
* characterBefore
|
|
232
|
+
* @returns {Alphabet} - The same alphabet instance with the specific
|
|
233
|
+
* character prioritized
|
|
234
|
+
* @example
|
|
235
|
+
* Alphabet.generateFrom('ab-cd/')
|
|
236
|
+
* .placeCharacterAfter({ characterBefore: '/', characterAfter: '-' })
|
|
237
|
+
* // Returns 'abcd/-'
|
|
238
|
+
*/
|
|
239
|
+
placeCharacterAfter({ characterBefore, characterAfter }) {
|
|
240
|
+
return this._placeCharacterBeforeOrAfter({
|
|
241
|
+
characterBefore,
|
|
242
|
+
characterAfter,
|
|
243
|
+
type: 'after',
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Removes specific characters from the alphabet by their range.
|
|
248
|
+
* @param {object} range - The Unicode range to remove characters from
|
|
249
|
+
* @param {number} range.start - The starting Unicode codepoint
|
|
250
|
+
* @param {number} range.end - The ending Unicode codepoint
|
|
251
|
+
* @returns {Alphabet} - The same alphabet instance without the characters
|
|
252
|
+
* from the specified range
|
|
253
|
+
*/
|
|
254
|
+
removeUnicodeRange({ start, end }) {
|
|
255
|
+
this._characters = this._characters.filter(
|
|
256
|
+
({ codePoint }) => codePoint < start || codePoint > end,
|
|
257
|
+
)
|
|
258
|
+
return this
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Sorts the alphabet by the sorting function provided.
|
|
262
|
+
* @param {Function} sortingFunction - The sorting function to use
|
|
263
|
+
* @returns {Alphabet} - The same alphabet instance sorted by the sorting function provided
|
|
264
|
+
*/
|
|
265
|
+
sortBy(sortingFunction) {
|
|
266
|
+
this._characters.sort((a, b) => sortingFunction(a.value, b.value))
|
|
267
|
+
return this
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Removes specific characters from the alphabet.
|
|
271
|
+
* @param {string|string[]} values - The characters to remove from the
|
|
272
|
+
* alphabet
|
|
273
|
+
* @returns {Alphabet} - The same alphabet instance without the specified
|
|
274
|
+
* characters
|
|
275
|
+
* @example
|
|
276
|
+
* Alphabet.generateFrom('abcd')
|
|
277
|
+
* .removeCharacters('dcc')
|
|
278
|
+
* // Returns 'ab'
|
|
279
|
+
*/
|
|
280
|
+
removeCharacters(values) {
|
|
281
|
+
this._characters = this._characters.filter(
|
|
282
|
+
({ value }) => !values.includes(value),
|
|
283
|
+
)
|
|
284
|
+
return this
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Sorts the alphabet by the natural order of the characters using
|
|
288
|
+
* `natural-orderby`.
|
|
289
|
+
* @param {string} locale - The locale to use for sorting
|
|
290
|
+
* @returns {Alphabet} - The same alphabet instance sorted by the natural
|
|
291
|
+
* order of the characters
|
|
292
|
+
*/
|
|
293
|
+
sortByNaturalSort(locale) {
|
|
294
|
+
let naturalCompare = naturalOrderby.compare({
|
|
295
|
+
locale,
|
|
296
|
+
})
|
|
297
|
+
return this.sortBy((a, b) => naturalCompare(a, b))
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Sorts the alphabet by the character code point.
|
|
301
|
+
* @returns {Alphabet} - The same alphabet instance sorted by the character
|
|
302
|
+
* code point
|
|
303
|
+
*/
|
|
304
|
+
sortByCharCodeAt() {
|
|
305
|
+
return this.sortBy((a, b) =>
|
|
306
|
+
convertBooleanToSign.convertBooleanToSign(
|
|
307
|
+
a.charCodeAt(0) > b.charCodeAt(0),
|
|
308
|
+
),
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Sorts the alphabet by the locale order of the characters.
|
|
313
|
+
* @param {Intl.LocalesArgument} locales - The locales to use for sorting
|
|
314
|
+
* @returns {Alphabet} - The same alphabet instance sorted by the locale
|
|
315
|
+
* order of the characters
|
|
316
|
+
*/
|
|
317
|
+
sortByLocaleCompare(locales) {
|
|
318
|
+
return this.sortBy((a, b) => a.localeCompare(b, locales))
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Retrieves the characters from the alphabet.
|
|
322
|
+
* @returns {string} The characters from the alphabet
|
|
323
|
+
*/
|
|
324
|
+
getCharacters() {
|
|
325
|
+
return this._characters.map(({ value }) => value).join('')
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Reverses the alphabet.
|
|
329
|
+
* @returns {Alphabet} - The same alphabet instance reversed
|
|
330
|
+
* @example
|
|
331
|
+
* Alphabet.generateFrom('ab')
|
|
332
|
+
* .reverse()
|
|
333
|
+
* // Returns 'ba'
|
|
334
|
+
*/
|
|
335
|
+
reverse() {
|
|
336
|
+
this._characters.reverse()
|
|
337
|
+
return this
|
|
338
|
+
}
|
|
339
|
+
_placeCharacterBeforeOrAfter({ characterBefore, characterAfter, type }) {
|
|
340
|
+
let indexOfCharacterAfter = this._characters.findIndex(
|
|
341
|
+
({ value }) => value === characterAfter,
|
|
342
|
+
)
|
|
343
|
+
let indexOfCharacterBefore = this._characters.findIndex(
|
|
344
|
+
({ value }) => value === characterBefore,
|
|
345
|
+
)
|
|
346
|
+
if (indexOfCharacterAfter === -1) {
|
|
347
|
+
throw new Error(`Character ${characterAfter} not found in alphabet`)
|
|
348
|
+
}
|
|
349
|
+
if (indexOfCharacterBefore === -1) {
|
|
350
|
+
throw new Error(`Character ${characterBefore} not found in alphabet`)
|
|
351
|
+
}
|
|
352
|
+
if (indexOfCharacterBefore <= indexOfCharacterAfter) {
|
|
353
|
+
return this
|
|
354
|
+
}
|
|
355
|
+
this._characters.splice(
|
|
356
|
+
type === 'before' ? indexOfCharacterAfter : indexOfCharacterBefore + 1,
|
|
357
|
+
0,
|
|
358
|
+
this._characters[
|
|
359
|
+
type === 'before' ? indexOfCharacterBefore : indexOfCharacterAfter
|
|
360
|
+
],
|
|
361
|
+
)
|
|
362
|
+
this._characters.splice(
|
|
363
|
+
type === 'before' ? indexOfCharacterBefore + 1 : indexOfCharacterAfter,
|
|
364
|
+
1,
|
|
365
|
+
)
|
|
366
|
+
return this
|
|
367
|
+
}
|
|
368
|
+
_getCharactersWithCase() {
|
|
369
|
+
return this._characters
|
|
370
|
+
.map((character, index) => {
|
|
371
|
+
if (
|
|
372
|
+
!character.uppercaseCharacterCodePoint &&
|
|
373
|
+
!character.lowercaseCharacterCodePoint
|
|
374
|
+
) {
|
|
375
|
+
return null
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
character,
|
|
379
|
+
index,
|
|
380
|
+
}
|
|
381
|
+
})
|
|
382
|
+
.filter(element => element !== null)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
exports.Alphabet = Alphabet
|