diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2024-01-31 08:38:30 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-31 13:38:30 +0000 |
commit | 87ed7c8affd3ade9d3cd2d9ed1a61dd5f224e473 (patch) | |
tree | be727294e31ef21e8a3f634734610e69e4a155ac /ext/js/background | |
parent | 3e419aa562aab03ca20421aaf7e4d1a39194a5b4 (diff) |
Module refactoring (#588)
* Convert PronunciationGenerator into static functions
* Convert DictionaryDataUtil into static functions
* Convert AnkiNoteDataCreator into static functions
* Convert MediaUtil into static functions
* Convert RegexUtil into static functions
* Convert StringUtil into static functions
* Convert ArrayBufferUtil into static functions
* Convert AnkiUtil into static functions
* Convert PermissionsUtil into static functions
* Convert ProfileConditionsUtil into static functions
Diffstat (limited to 'ext/js/background')
-rw-r--r-- | ext/js/background/backend.js | 38 | ||||
-rw-r--r-- | ext/js/background/offscreen-proxy.js | 4 | ||||
-rw-r--r-- | ext/js/background/offscreen.js | 4 | ||||
-rw-r--r-- | ext/js/background/profile-conditions-util.js | 662 |
4 files changed, 347 insertions, 361 deletions
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 0773dc4b..b95626f5 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -26,19 +26,19 @@ import {ExtensionError} from '../core/extension-error.js'; import {readResponseJson} from '../core/json.js'; import {log} from '../core/logger.js'; import {clone, deferPromise, isObject, promiseTimeout} from '../core/utilities.js'; -import {AnkiUtil} from '../data/anki-util.js'; +import {isNoteDataValid} from '../data/anki-util.js'; import {OptionsUtil} from '../data/options-util.js'; -import {PermissionsUtil} from '../data/permissions-util.js'; -import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js'; +import {getAllPermissions, hasPermissions, hasRequiredPermissionsForOptions} from '../data/permissions-util.js'; +import {arrayBufferToBase64} from '../data/sandbox/array-buffer-util.js'; import {DictionaryDatabase} from '../dictionary/dictionary-database.js'; import {Environment} from '../extension/environment.js'; import {ObjectPropertyAccessor} from '../general/object-property-accessor.js'; import {distributeFuriganaInflected, isCodePointJapanese, isStringPartiallyJapanese, convertKatakanaToHiragana as jpConvertKatakanaToHiragana} from '../language/japanese.js'; import {Translator} from '../language/translator.js'; import {AudioDownloader} from '../media/audio-downloader.js'; -import {MediaUtil} from '../media/media-util.js'; +import {getFileExtensionFromAudioMediaType, getFileExtensionFromImageMediaType} from '../media/media-util.js'; import {ClipboardReaderProxy, DictionaryDatabaseProxy, OffscreenProxy, TranslatorProxy} from './offscreen-proxy.js'; -import {ProfileConditionsUtil} from './profile-conditions-util.js'; +import {createSchema, normalizeContext} from './profile-conditions-util.js'; import {RequestBuilder} from './request-builder.js'; import {injectStylesheet} from './script-manager.js'; @@ -95,8 +95,6 @@ export class Backend { this._options = null; /** @type {import('../data/json-schema.js').JsonSchema[]} */ this._profileConditionsSchemaCache = []; - /** @type {ProfileConditionsUtil} */ - this._profileConditionsUtil = new ProfileConditionsUtil(); /** @type {?string} */ this._defaultAnkiFieldTemplates = null; /** @type {RequestBuilder} */ @@ -138,8 +136,6 @@ export class Backend { this._logErrorLevel = null; /** @type {?chrome.permissions.Permissions} */ this._permissions = null; - /** @type {PermissionsUtil} */ - this._permissionsUtil = new PermissionsUtil(); /** @type {Map<string, (() => void)[]>} */ this._applicationReadyHandlers = new Map(); @@ -259,7 +255,7 @@ export class Backend { try { this._prepareInternalSync(); - this._permissions = await this._permissionsUtil.getAllPermissions(); + this._permissions = await getAllPermissions(); this._defaultBrowserActionTitle = await this._getBrowserIconTitle(); this._badgePrepareDelayTimer = setTimeout(() => { this._badgePrepareDelayTimer = null; @@ -545,7 +541,7 @@ export class Backend { for (let i = 0; i < notes.length; ++i) { const note = notes[i]; let canAdd = canAddArray[i]; - const valid = AnkiUtil.isNoteDataValid(note); + const valid = isNoteDataValid(note); if (!valid) { canAdd = false; } const info = {canAdd, valid, noteIds: null}; results.push(info); @@ -815,7 +811,7 @@ export class Backend { let permissionsOkay = false; try { - permissionsOkay = await this._permissionsUtil.hasPermissions({permissions: ['nativeMessaging']}); + permissionsOkay = await hasPermissions({permissions: ['nativeMessaging']}); } catch (e) { // NOP } @@ -1302,7 +1298,7 @@ export class Backend { * @returns {?import('settings').Profile} */ _getProfileFromContext(options, optionsContext) { - const normalizedOptionsContext = this._profileConditionsUtil.normalizeContext(optionsContext); + const normalizedOptionsContext = normalizeContext(optionsContext); let index = 0; for (const profile of options.profiles) { @@ -1312,7 +1308,7 @@ export class Backend { if (index < this._profileConditionsSchemaCache.length) { schema = this._profileConditionsSchemaCache[index]; } else { - schema = this._profileConditionsUtil.createSchema(conditionGroups); + schema = createSchema(conditionGroups); this._profileConditionsSchemaCache.push(schema); } @@ -2128,7 +2124,7 @@ export class Backend { return null; } - let extension = contentType !== null ? MediaUtil.getFileExtensionFromAudioMediaType(contentType) : null; + let extension = contentType !== null ? getFileExtensionFromAudioMediaType(contentType) : null; if (extension === null) { extension = '.mp3'; } let fileName = this._generateAnkiNoteMediaFileName('yomitan_audio', extension, timestamp, definitionDetails); fileName = fileName.replace(/\]/g, ''); @@ -2147,7 +2143,7 @@ export class Backend { const dataUrl = await this._getScreenshot(tabId, frameId, format, quality); const {mediaType, data} = this._getDataUrlInfo(dataUrl); - const extension = MediaUtil.getFileExtensionFromImageMediaType(mediaType); + const extension = getFileExtensionFromImageMediaType(mediaType); if (extension === null) { throw new Error('Unknown media type for screenshot image'); } @@ -2169,7 +2165,7 @@ export class Backend { } const {mediaType, data} = this._getDataUrlInfo(dataUrl); - const extension = MediaUtil.getFileExtensionFromImageMediaType(mediaType); + const extension = getFileExtensionFromImageMediaType(mediaType); if (extension === null) { throw new Error('Unknown media type for clipboard image'); } @@ -2215,7 +2211,7 @@ export class Backend { let fileName = null; if (media !== null) { const {content, mediaType} = media; - const extension = MediaUtil.getFileExtensionFromImageMediaType(mediaType); + const extension = getFileExtensionFromImageMediaType(mediaType); fileName = this._generateAnkiNoteMediaFileName( `yomitan_dictionary_media_${i + 1}`, extension !== null ? extension : '', @@ -2611,7 +2607,7 @@ export class Backend { * @returns {Promise<void>} */ async _checkPermissions() { - this._permissions = await this._permissionsUtil.getAllPermissions(); + this._permissions = await getAllPermissions(); this._updateBadge(); } @@ -2628,7 +2624,7 @@ export class Backend { */ _hasRequiredPermissionsForSettings(options) { if (!this._canObservePermissionsChanges()) { return true; } - return this._permissions === null || this._permissionsUtil.hasRequiredPermissionsForOptions(this._permissions, options); + return this._permissions === null || hasRequiredPermissionsForOptions(this._permissions, options); } /** @@ -2663,7 +2659,7 @@ export class Backend { const results = []; for (const item of await this._dictionaryDatabase.getMedia(targets)) { const {content, dictionary, height, mediaType, path, width} = item; - const content2 = ArrayBufferUtil.arrayBufferToBase64(content); + const content2 = arrayBufferToBase64(content); results.push({content: content2, dictionary, height, mediaType, path, width}); } return results; diff --git a/ext/js/background/offscreen-proxy.js b/ext/js/background/offscreen-proxy.js index 80ff31c0..716deddd 100644 --- a/ext/js/background/offscreen-proxy.js +++ b/ext/js/background/offscreen-proxy.js @@ -18,7 +18,7 @@ import {ExtensionError} from '../core/extension-error.js'; import {isObject} from '../core/utilities.js'; -import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js'; +import {base64ToArrayBuffer} from '../data/sandbox/array-buffer-util.js'; export class OffscreenProxy { /** @@ -144,7 +144,7 @@ export class DictionaryDatabaseProxy { */ async getMedia(targets) { const serializedMedia = /** @type {import('dictionary-database').Media<string>[]} */ (await this._offscreen.sendMessagePromise({action: 'databaseGetMediaOffscreen', params: {targets}})); - const media = serializedMedia.map((m) => ({...m, content: ArrayBufferUtil.base64ToArrayBuffer(m.content)})); + const media = serializedMedia.map((m) => ({...m, content: base64ToArrayBuffer(m.content)})); return media; } } diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js index ef05508a..b203e326 100644 --- a/ext/js/background/offscreen.js +++ b/ext/js/background/offscreen.js @@ -18,7 +18,7 @@ import {ClipboardReader} from '../comm/clipboard-reader.js'; import {createApiMap, invokeApiMapHandler} from '../core/api-map.js'; -import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js'; +import {arrayBufferToBase64} from '../data/sandbox/array-buffer-util.js'; import {DictionaryDatabase} from '../dictionary/dictionary-database.js'; import {Translator} from '../language/translator.js'; @@ -110,7 +110,7 @@ export class Offscreen { /** @type {import('offscreen').ApiHandler<'databaseGetMediaOffscreen'>} */ async _getMediaHandler({targets}) { const media = await this._dictionaryDatabase.getMedia(targets); - const serializedMedia = media.map((m) => ({...m, content: ArrayBufferUtil.arrayBufferToBase64(m.content)})); + const serializedMedia = media.map((m) => ({...m, content: arrayBufferToBase64(m.content)})); return serializedMedia; } diff --git a/ext/js/background/profile-conditions-util.js b/ext/js/background/profile-conditions-util.js index f3be226d..e2d58725 100644 --- a/ext/js/background/profile-conditions-util.js +++ b/ext/js/background/profile-conditions-util.js @@ -18,379 +18,369 @@ import {JsonSchema} from '../data/json-schema.js'; +/** @type {RegExp} */ +const splitPattern = /[,;\s]+/; +/** @type {Map<string, {operators: Map<string, import('profile-conditions-util').CreateSchemaFunction>}>} */ +const descriptors = new Map([ + [ + 'popupLevel', + { + operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ + ['equal', createSchemaPopupLevelEqual.bind(this)], + ['notEqual', createSchemaPopupLevelNotEqual.bind(this)], + ['lessThan', createSchemaPopupLevelLessThan.bind(this)], + ['greaterThan', createSchemaPopupLevelGreaterThan.bind(this)], + ['lessThanOrEqual', createSchemaPopupLevelLessThanOrEqual.bind(this)], + ['greaterThanOrEqual', createSchemaPopupLevelGreaterThanOrEqual.bind(this)] + ])) + } + ], + [ + 'url', + { + operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ + ['matchDomain', createSchemaUrlMatchDomain.bind(this)], + ['matchRegExp', createSchemaUrlMatchRegExp.bind(this)] + ])) + } + ], + [ + 'modifierKeys', + { + operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ + ['are', createSchemaModifierKeysAre.bind(this)], + ['areNot', createSchemaModifierKeysAreNot.bind(this)], + ['include', createSchemaModifierKeysInclude.bind(this)], + ['notInclude', createSchemaModifierKeysNotInclude.bind(this)] + ])) + } + ], + [ + 'flags', + { + operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ + ['are', createSchemaFlagsAre.bind(this)], + ['areNot', createSchemaFlagsAreNot.bind(this)], + ['include', createSchemaFlagsInclude.bind(this)], + ['notInclude', createSchemaFlagsNotInclude.bind(this)] + ])) + } + ] +]); + /** - * Utility class to help processing profile conditions. + * Creates a new JSON schema descriptor for the given set of condition groups. + * @param {import('settings').ProfileConditionGroup[]} conditionGroups An array of condition groups. + * For a profile match, all of the items must return successfully in at least one of the groups. + * @returns {JsonSchema} A new `JsonSchema` object. */ -export class ProfileConditionsUtil { - /** - * Creates a new instance. - */ - constructor() { - /** @type {RegExp} */ - this._splitPattern = /[,;\s]+/; - /** @type {Map<string, {operators: Map<string, import('profile-conditions-util').CreateSchemaFunction>}>} */ - this._descriptors = new Map([ - [ - 'popupLevel', - { - operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ - ['equal', this._createSchemaPopupLevelEqual.bind(this)], - ['notEqual', this._createSchemaPopupLevelNotEqual.bind(this)], - ['lessThan', this._createSchemaPopupLevelLessThan.bind(this)], - ['greaterThan', this._createSchemaPopupLevelGreaterThan.bind(this)], - ['lessThanOrEqual', this._createSchemaPopupLevelLessThanOrEqual.bind(this)], - ['greaterThanOrEqual', this._createSchemaPopupLevelGreaterThanOrEqual.bind(this)] - ])) - } - ], - [ - 'url', - { - operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ - ['matchDomain', this._createSchemaUrlMatchDomain.bind(this)], - ['matchRegExp', this._createSchemaUrlMatchRegExp.bind(this)] - ])) - } - ], - [ - 'modifierKeys', - { - operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ - ['are', this._createSchemaModifierKeysAre.bind(this)], - ['areNot', this._createSchemaModifierKeysAreNot.bind(this)], - ['include', this._createSchemaModifierKeysInclude.bind(this)], - ['notInclude', this._createSchemaModifierKeysNotInclude.bind(this)] - ])) - } - ], - [ - 'flags', - { - operators: new Map(/** @type {import('profile-conditions-util').OperatorMapArray} */ ([ - ['are', this._createSchemaFlagsAre.bind(this)], - ['areNot', this._createSchemaFlagsAreNot.bind(this)], - ['include', this._createSchemaFlagsInclude.bind(this)], - ['notInclude', this._createSchemaFlagsNotInclude.bind(this)] - ])) - } - ] - ]); - } +export function createSchema(conditionGroups) { + const anyOf = []; + for (const {conditions} of conditionGroups) { + const allOf = []; + for (const {type, operator, value} of conditions) { + const conditionDescriptor = descriptors.get(type); + if (typeof conditionDescriptor === 'undefined') { continue; } - /** - * Creates a new JSON schema descriptor for the given set of condition groups. - * @param {import('settings').ProfileConditionGroup[]} conditionGroups An array of condition groups. - * For a profile match, all of the items must return successfully in at least one of the groups. - * @returns {JsonSchema} A new `JsonSchema` object. - */ - createSchema(conditionGroups) { - const anyOf = []; - for (const {conditions} of conditionGroups) { - const allOf = []; - for (const {type, operator, value} of conditions) { - const conditionDescriptor = this._descriptors.get(type); - if (typeof conditionDescriptor === 'undefined') { continue; } + const createSchema2 = conditionDescriptor.operators.get(operator); + if (typeof createSchema2 === 'undefined') { continue; } - const createSchema = conditionDescriptor.operators.get(operator); - if (typeof createSchema === 'undefined') { continue; } - - const schema = createSchema(value); - allOf.push(schema); - } - switch (allOf.length) { - case 0: break; - case 1: anyOf.push(allOf[0]); break; - default: anyOf.push({allOf}); break; - } + const schema = createSchema2(value); + allOf.push(schema); } - let schema; - switch (anyOf.length) { - case 0: schema = {}; break; - case 1: schema = anyOf[0]; break; - default: schema = {anyOf}; break; + switch (allOf.length) { + case 0: break; + case 1: anyOf.push(allOf[0]); break; + default: anyOf.push({allOf}); break; } - return new JsonSchema(schema); } + let schema; + switch (anyOf.length) { + case 0: schema = {}; break; + case 1: schema = anyOf[0]; break; + default: schema = {anyOf}; break; + } + return new JsonSchema(schema); +} - /** - * Creates a normalized version of the context object to test, - * assigning dependent fields as needed. - * @param {import('settings').OptionsContext} context A context object which is used during schema validation. - * @returns {import('profile-conditions-util').NormalizedOptionsContext} A normalized context object. - */ - normalizeContext(context) { - const normalizedContext = /** @type {import('profile-conditions-util').NormalizedOptionsContext} */ (Object.assign({}, context)); - const {url} = normalizedContext; - if (typeof url === 'string') { - try { - normalizedContext.domain = new URL(url).hostname; - } catch (e) { - // NOP - } - } - const {flags} = normalizedContext; - if (!Array.isArray(flags)) { - normalizedContext.flags = []; +/** + * Creates a normalized version of the context object to test, + * assigning dependent fields as needed. + * @param {import('settings').OptionsContext} context A context object which is used during schema validation. + * @returns {import('profile-conditions-util').NormalizedOptionsContext} A normalized context object. + */ +export function normalizeContext(context) { + const normalizedContext = /** @type {import('profile-conditions-util').NormalizedOptionsContext} */ (Object.assign({}, context)); + const {url} = normalizedContext; + if (typeof url === 'string') { + try { + normalizedContext.domain = new URL(url).hostname; + } catch (e) { + // NOP } - return normalizedContext; } - - // Private - - /** - * @param {string} value - * @returns {string[]} - */ - _split(value) { - return value.split(this._splitPattern); + const {flags} = normalizedContext; + if (!Array.isArray(flags)) { + normalizedContext.flags = []; } + return normalizedContext; +} - /** - * @param {string} value - * @returns {number} - */ - _stringToNumber(value) { - const number = Number.parseFloat(value); - return Number.isFinite(number) ? number : 0; - } +// Private - // popupLevel schema creation functions +/** + * @param {string} value + * @returns {string[]} + */ +function split(value) { + return value.split(splitPattern); +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaPopupLevelEqual(value) { - const number = this._stringToNumber(value); - return { - required: ['depth'], - properties: { - depth: {const: number} - } - }; - } +/** + * @param {string} value + * @returns {number} + */ +function stringToNumber(value) { + const number = Number.parseFloat(value); + return Number.isFinite(number) ? number : 0; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaPopupLevelNotEqual(value) { - return { - not: { - anyOf: [this._createSchemaPopupLevelEqual(value)] - } - }; - } +// popupLevel schema creation functions - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaPopupLevelLessThan(value) { - const number = this._stringToNumber(value); - return { - required: ['depth'], - properties: { - depth: {type: 'number', exclusiveMaximum: number} - } - }; - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaPopupLevelEqual(value) { + const number = stringToNumber(value); + return { + required: ['depth'], + properties: { + depth: {const: number} + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaPopupLevelGreaterThan(value) { - const number = this._stringToNumber(value); - return { - required: ['depth'], - properties: { - depth: {type: 'number', exclusiveMinimum: number} - } - }; - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaPopupLevelNotEqual(value) { + return { + not: { + anyOf: [createSchemaPopupLevelEqual(value)] + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaPopupLevelLessThanOrEqual(value) { - const number = this._stringToNumber(value); - return { - required: ['depth'], - properties: { - depth: {type: 'number', maximum: number} - } - }; - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaPopupLevelLessThan(value) { + const number = stringToNumber(value); + return { + required: ['depth'], + properties: { + depth: {type: 'number', exclusiveMaximum: number} + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaPopupLevelGreaterThanOrEqual(value) { - const number = this._stringToNumber(value); - return { - required: ['depth'], - properties: { - depth: {type: 'number', minimum: number} - } - }; - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaPopupLevelGreaterThan(value) { + const number = stringToNumber(value); + return { + required: ['depth'], + properties: { + depth: {type: 'number', exclusiveMinimum: number} + } + }; +} - // url schema creation functions +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaPopupLevelLessThanOrEqual(value) { + const number = stringToNumber(value); + return { + required: ['depth'], + properties: { + depth: {type: 'number', maximum: number} + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaUrlMatchDomain(value) { - const oneOf = []; - for (let domain of this._split(value)) { - if (domain.length === 0) { continue; } - domain = domain.toLowerCase(); - oneOf.push({const: domain}); +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaPopupLevelGreaterThanOrEqual(value) { + const number = stringToNumber(value); + return { + required: ['depth'], + properties: { + depth: {type: 'number', minimum: number} } - return { - required: ['domain'], - properties: { - domain: {oneOf} - } - }; - } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaUrlMatchRegExp(value) { - return { - required: ['url'], - properties: { - url: {type: 'string', pattern: value, patternFlags: 'i'} - } - }; +// url schema creation functions + +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaUrlMatchDomain(value) { + const oneOf = []; + for (let domain of split(value)) { + if (domain.length === 0) { continue; } + domain = domain.toLowerCase(); + oneOf.push({const: domain}); } + return { + required: ['domain'], + properties: { + domain: {oneOf} + } + }; +} - // modifierKeys schema creation functions +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaUrlMatchRegExp(value) { + return { + required: ['url'], + properties: { + url: {type: 'string', pattern: value, patternFlags: 'i'} + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaModifierKeysAre(value) { - return this._createSchemaArrayCheck('modifierKeys', value, true, false); - } +// modifierKeys schema creation functions - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaModifierKeysAreNot(value) { - return { - not: { - anyOf: [this._createSchemaArrayCheck('modifierKeys', value, true, false)] - } - }; - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaModifierKeysAre(value) { + return createSchemaArrayCheck('modifierKeys', value, true, false); +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaModifierKeysInclude(value) { - return this._createSchemaArrayCheck('modifierKeys', value, false, false); - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaModifierKeysAreNot(value) { + return { + not: { + anyOf: [createSchemaArrayCheck('modifierKeys', value, true, false)] + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaModifierKeysNotInclude(value) { - return this._createSchemaArrayCheck('modifierKeys', value, false, true); - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaModifierKeysInclude(value) { + return createSchemaArrayCheck('modifierKeys', value, false, false); +} - // modifierKeys schema creation functions +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaModifierKeysNotInclude(value) { + return createSchemaArrayCheck('modifierKeys', value, false, true); +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaFlagsAre(value) { - return this._createSchemaArrayCheck('flags', value, true, false); - } +// modifierKeys schema creation functions - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaFlagsAreNot(value) { - return { - not: { - anyOf: [this._createSchemaArrayCheck('flags', value, true, false)] - } - }; - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaFlagsAre(value) { + return createSchemaArrayCheck('flags', value, true, false); +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaFlagsInclude(value) { - return this._createSchemaArrayCheck('flags', value, false, false); - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaFlagsAreNot(value) { + return { + not: { + anyOf: [createSchemaArrayCheck('flags', value, true, false)] + } + }; +} - /** - * @param {string} value - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaFlagsNotInclude(value) { - return this._createSchemaArrayCheck('flags', value, false, true); - } +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaFlagsInclude(value) { + return createSchemaArrayCheck('flags', value, false, false); +} - // Generic +/** + * @param {string} value + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaFlagsNotInclude(value) { + return createSchemaArrayCheck('flags', value, false, true); +} - /** - * @param {string} key - * @param {string} value - * @param {boolean} exact - * @param {boolean} none - * @returns {import('ext/json-schema').Schema} - */ - _createSchemaArrayCheck(key, value, exact, none) { - /** @type {import('ext/json-schema').Schema[]} */ - const containsList = []; - for (const item of this._split(value)) { - if (item.length === 0) { continue; } - containsList.push({ - contains: { - const: item - } - }); - } - const containsListCount = containsList.length; - /** @type {import('ext/json-schema').Schema} */ - const schema = { - type: 'array' - }; - if (exact) { - schema.maxItems = containsListCount; - } - if (none) { - if (containsListCount > 0) { - schema.not = {anyOf: containsList}; - } - } else { - schema.minItems = containsListCount; - if (containsListCount > 0) { - schema.allOf = containsList; +// Generic + +/** + * @param {string} key + * @param {string} value + * @param {boolean} exact + * @param {boolean} none + * @returns {import('ext/json-schema').Schema} + */ +function createSchemaArrayCheck(key, value, exact, none) { + /** @type {import('ext/json-schema').Schema[]} */ + const containsList = []; + for (const item of split(value)) { + if (item.length === 0) { continue; } + containsList.push({ + contains: { + const: item } + }); + } + const containsListCount = containsList.length; + /** @type {import('ext/json-schema').Schema} */ + const schema = { + type: 'array' + }; + if (exact) { + schema.maxItems = containsListCount; + } + if (none) { + if (containsListCount > 0) { + schema.not = {anyOf: containsList}; + } + } else { + schema.minItems = containsListCount; + if (containsListCount > 0) { + schema.allOf = containsList; } - return { - required: [key], - properties: { - [key]: schema - } - }; } + return { + required: [key], + properties: { + [key]: schema + } + }; } |