diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index d857a9e0f..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true, - "node": true - }, - "extends": [ - "prettier" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": "./tsconfig.json", - "sourceType": "module" - }, - "plugins": [ - "eslint-plugin-import", - "eslint-plugin-jsdoc", - "eslint-plugin-node", - "eslint-plugin-unicorn", - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": [ - "error", - { - "default": "array" - } - ], - "@typescript-eslint/ban-types": [ - "error", - { - "types": { - "Object": { - "message": "Avoid using the `Object` type. Did you mean `object`?" - }, - "Function": { - "message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`." - }, - "Boolean": { - "message": "Avoid using the `Boolean` type. Did you mean `boolean`?" - }, - "Number": { - "message": "Avoid using the `Number` type. Did you mean `number`?" - }, - "String": { - "message": "Avoid using the `String` type. Did you mean `string`?" - }, - "Symbol": { - "message": "Avoid using the `Symbol` type. Did you mean `symbol`?" - }, - "Buffer": { - "message": "Do not use Node.js specific Buffer type, use Uint8Array" - } - } - } - ], - - "@typescript-eslint/consistent-type-assertions": "error", - "@typescript-eslint/dot-notation": "error", - "@typescript-eslint/indent": [ - "error", - 2, - { - "ObjectExpression": "first", - "FunctionDeclaration": { - "parameters": "first" - }, - "FunctionExpression": { - "parameters": "first" - }, - "SwitchCase": 1 - } - ], - "@typescript-eslint/naming-convention": "off", - "@typescript-eslint/no-empty-function": [ - "error", - { - "allow": [ - "constructors" - ] - } - ], - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-parameter-properties": "off", - "@typescript-eslint/no-shadow": [ - "error", - { - "hoist": "all" - } - ], - "@typescript-eslint/no-this-alias": "error", - "@typescript-eslint/no-unused-expressions": "error", - "@typescript-eslint/no-use-before-define": "off", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/prefer-function-type": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/quotes": "off", - "@typescript-eslint/semi": [ - "error", - "always" - ], - "@typescript-eslint/triple-slash-reference": [ - "error", - { - "path": "always", - "types": "prefer-import", - "lib": "always" - } - ], - "@typescript-eslint/unified-signatures": "error", - "arrow-parens": [ - "error", - "as-needed" - ], - "comma-dangle": "error", - "complexity": "off", - "constructor-super": "error", - "curly": "off", - "default-case": "off", - "dot-notation": "error", - "eqeqeq": [ - "error", - "smart" - ], - "guard-for-in": "off", - "id-denylist": [ - "error", - "any", - "Number", - "number", - "String", - "string", - "Boolean", - "boolean", - "Undefined", - "undefined" - ], - "id-match": "error", - "import/no-extraneous-dependencies": [ - "error", - { - "devDependencies": false - } - ], - "import/no-internal-modules": "off", - "import/order": "off", - "import/no-unresolved": ["error", {"caseSensitiveStrict": true }], - "indent": "off", - "jsdoc/check-alignment": "error", - "jsdoc/check-indentation": "error", - "jsdoc/newline-after-description": "off", - "max-classes-per-file": "off", - "max-len": [ - "error", - { - "code": 200 - } - ], - "new-parens": "error", - "no-bitwise": "off", - "no-buffer-constructor": "error", - "no-caller": "error", - "no-cond-assign": "error", - "no-console": "error", - "no-debugger": "error", - "no-duplicate-case": "error", - "no-duplicate-imports": "error", - "no-empty": "error", - "no-empty-function": "off", - "no-eval": "error", - "no-extra-bind": "error", - "no-fallthrough": "off", - "no-invalid-this": "off", - "no-new-func": "error", - "no-new-wrappers": "error", - "no-redeclare": "error", - "no-return-await": "error", - "no-restricted-globals": ["error", "Buffer"], - "no-restricted-imports": [ - "error", - { - "paths": ["node:buffer"] - } - ], - "no-sequences": "error", - "no-shadow": "off", - "no-sparse-arrays": "error", - "no-template-curly-in-string": "error", - "no-throw-literal": "error", - "no-trailing-spaces": "error", - "no-undef-init": "error", - "no-underscore-dangle": "error", - "no-unsafe-finally": "error", - "no-unused-expressions": "error", - "no-unused-labels": "error", - "no-use-before-define": "off", - "no-var": "error", - "node/file-extension-in-import": ["error", "always"], - "node/no-extraneous-import": "error", - "object-shorthand": "error", - "one-var": [ - "error", - "never" - ], - "prefer-const": "error", - "prefer-object-spread": "error", - "quote-props": [ - "error", - "as-needed" - ], - "quotes": "off", - "radix": "error", - "semi": "error", - "space-in-parens": [ - "error", - "never" - ], - "spaced-comment": [ - "error", - "always", - { - "markers": [ - "/" - ] - } - ], - "unicorn/prefer-ternary": "error", - "use-isnan": "error", - "valid-typeof": "off" - }, - "settings": { - "import/parsers": { - "@typescript-eslint/parser": [ - ".ts", - ".tsx" - ] - }, - "import/resolver": { - "typescript": { - "alwaysTryTypes": true, - "project": [ - "lib/tsconfig.json", - "test/tsconfig.json", - "doc-gen/tsconfig.json" - ] - } - } - } -} - diff --git a/.github/workflows/nodejs-ci.yml b/.github/workflows/nodejs-ci.yml index 24012a406..d6758819b 100644 --- a/.github/workflows/nodejs-ci.yml +++ b/.github/workflows/nodejs-ci.yml @@ -24,8 +24,11 @@ jobs: - name: Yarn install run: yarn install - - name: Static code analysis - run: yarn run lint + - name: Lint TypeScript + run: yarn run lint-ts + + - name: Lint Markdown + run: yarn run lint-md - name: Build run: yarn run build diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 000000000..5ca2d201b --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,53 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "organizeImports": { + "enabled": false + }, + "formatter": { + "enabled": false + }, + "linter": { + "enabled": true, + "rules": { + "correctness": { + "noConstantCondition": "warn" + }, + "style": { + "noParameterAssign": "off" + }, + "recommended": true, + "complexity": { + "noForEach": "off" + }, + "suspicious": { + "noEmptyBlockStatements": "error", + "noControlCharactersInRegex": "off" + }, + "nursery": { + "noRestrictedImports": { + "level": "error", + "options": { + "paths": { + "node:buffer": "Use Uint8Array instead of Buffer" + } + } + }, + "useConsistentBuiltinInstantiation": "error", + "useThrowNewError": "error", + "useThrowOnlyError": "error", + "useErrorMessage": "error" + } + } + }, + "files": { + "ignoreUnknown": true, + "ignore": [ + "./coverage", + "./yarn", + "./lib/**/*.d.ts", + "./lib/**/*.js", + "./test/**/*.d.ts", + "./test/**/*.js" + ] + } +} diff --git a/doc-gen/MarkDown.ts b/doc-gen/MarkDown.ts index f3dda5e59..5a78879ad 100644 --- a/doc-gen/MarkDown.ts +++ b/doc-gen/MarkDown.ts @@ -1,4 +1,4 @@ -import * as fs from 'fs'; +import type * as fs from 'node:fs'; export class Row { constructor(public values: string[]) { @@ -7,7 +7,7 @@ export class Row { export class Table { - private static padEnd(value: string, size: number, pad: string = ' ') { + private static padEnd(value: string, size: number, pad = ' ') { while (value.length < size) { value += pad; } @@ -20,13 +20,13 @@ export class Table { const cellTxt = values.length > ci ? values[ci] : ''; colValues.push(Table.padEnd(cellTxt, colSizes[ci])); } - out.write('| ' + colValues.join(' | ') + ' |\n'); + out.write(`| ${colValues.join(' | ')} |\n`); } private static lineToString(colSizes: number[]): string { const colValues = colSizes.map(size => Table.padEnd('-', size, '-')); - return '|-' + colValues.join('-|-') + '-|\n'; + return `|-${colValues.join('-|-')}-|\n`; } public rows: Row[] = []; diff --git a/doc-gen/gen.ts b/doc-gen/gen.ts index ea81a350d..e42756cbf 100644 --- a/doc-gen/gen.ts +++ b/doc-gen/gen.ts @@ -30,8 +30,8 @@ function getNativeSourceTags(nativeType: string, commonTag: string): string[] { function write(out: fs.WriteStream) { - const json = fs.readFileSync(path.join(dirname, 'common.json')); - const commonDescriptionDict: ITagInfoDict = JSON.parse(json as any); + const json = fs.readFileSync(path.join(dirname, 'common.json'), {encoding: 'utf-8'}); + const commonDescriptionDict: ITagInfoDict = JSON.parse(json); const table = new markDown.Table(); diff --git a/example/javascript/orderTags.js b/example/javascript/orderTags.js index 10f0f3205..8fac64e33 100644 --- a/example/javascript/orderTags.js +++ b/example/javascript/orderTags.js @@ -1,5 +1,5 @@ import { parseFile, orderTags } from '../../lib/index.js'; // music-metadata -import { inspect } from 'util'; +import { inspect } from 'node:util'; (async () => { try { diff --git a/example/javascript/parseFile.js b/example/javascript/parseFile.js index 7105536e0..853d25388 100644 --- a/example/javascript/parseFile.js +++ b/example/javascript/parseFile.js @@ -1,5 +1,5 @@ import { parseFile } from '../../lib/index.js'; // music-metadata -import { inspect } from 'util'; +import { inspect } from 'node:util'; (async () => { try { diff --git a/example/javascript/stream.js b/example/javascript/stream.js index 5dedae2d3..5e526c30a 100644 --- a/example/javascript/stream.js +++ b/example/javascript/stream.js @@ -1,5 +1,5 @@ -import https from 'https'; -import { inspect } from 'util'; +import https from 'node:https'; +import { inspect } from 'node:util'; import { parseStream } from '../../lib/index.js'; // music-metadata const audioUrl = 'https://github.com/Borewit/music-metadata/raw/master/test/samples/MusicBrainz%20-%20Beth%20Hart%20-%20Sinner\'s%20Prayer%20%5Bid3v2.3%5D.V2.mp3'; @@ -15,7 +15,7 @@ function httpGet (url) { resolve(httpGet(res.headers.location)); break; default: - reject(new Error('Unexpected status-code:' + res.statusCode)); + reject(new Error(`Unexpected status-code:${res.statusCode}`)); } }); }); diff --git a/example/typescript/typescript.ts b/example/typescript/typescript.ts index d073b8f8c..48e69e4f8 100644 --- a/example/typescript/typescript.ts +++ b/example/typescript/typescript.ts @@ -1,5 +1,5 @@ import { parseFile } from '../../lib/index.js'; -import { inspect } from 'util'; +import { inspect } from 'node:util'; (async () => { try { diff --git a/lib/ParserFactory.ts b/lib/ParserFactory.ts index a4e2aea3f..4af993ec8 100644 --- a/lib/ParserFactory.ts +++ b/lib/ParserFactory.ts @@ -1,9 +1,9 @@ import { fileTypeFromBuffer } from 'file-type'; import ContentType from 'content-type'; -import MimeType from 'media-typer'; +import {parse as mimeTypeParse, type MediaType} from 'media-typer'; import initDebug from 'debug'; -import { INativeMetadataCollector, MetadataCollector } from './common/MetadataCollector.js'; +import { type INativeMetadataCollector, MetadataCollector } from './common/MetadataCollector.js'; import { AIFFParser } from './aiff/AiffParser.js'; import { APEv2Parser } from './apev2/APEv2Parser.js'; import { AsfParser } from './asf/AsfParser.js'; @@ -18,7 +18,7 @@ import { DsfParser } from './dsf/DsfParser.js'; import { DsdiffParser } from './dsdiff/DsdiffParser.js'; import { MatroskaParser } from './matroska/MatroskaParser.js'; -import { IOptions, IAudioMetadata, ParserType } from './type.js'; +import type { IOptions, IAudioMetadata, ParserType } from './type.js'; import type { ITokenizer } from 'strtok3'; const debug = initDebug('music-metadata:parser:factory'); @@ -41,285 +41,281 @@ export interface ITokenParser { parse(): Promise; } -export function parseHttpContentType(contentType: string): { type: string, subtype: string, suffix?: string, parameters: { [id: string]: string; } } { +interface IContentType extends MediaType { + parameters: { [id: string]: string; }; +} + +export function parseHttpContentType(contentType: string): IContentType { const type = ContentType.parse(contentType); - const mime = MimeType.parse(type.type); + const mime = mimeTypeParse(type.type); return { type: mime.type, subtype: mime.subtype, suffix: mime.suffix, parameters: type.parameters - }; -} - -async function parse(tokenizer: ITokenizer, parserId: ParserType, opts: IOptions = {}): Promise { - // Parser found, execute parser - const parser = await ParserFactory.loadParser(parserId); - const metadata = new MetadataCollector(opts); - await parser.init(metadata, tokenizer, opts).parse(); - return metadata.toCommonMetadata(); + } as IContentType; } -export class ParserFactory { +/** + * Parse metadata from tokenizer + * @param tokenizer - Tokenizer + * @param opts - Options + * @returns Native metadata + */ +export async function parseOnContentType(tokenizer: ITokenizer, opts: IOptions): Promise { - /** - * Parse metadata from tokenizer - * @param tokenizer - Tokenizer - * @param opts - Options - * @returns Native metadata - */ - public static async parseOnContentType(tokenizer: ITokenizer, opts: IOptions): Promise { + const { mimeType, path, url } = tokenizer.fileInfo; - const { mimeType, path, url } = await tokenizer.fileInfo; + // Resolve parser based on MIME-type or file extension + const parserId = getParserIdForMimeType(mimeType) || getParserIdForExtension(path) || getParserIdForExtension(url); - // Resolve parser based on MIME-type or file extension - const parserId = ParserFactory.getParserIdForMimeType(mimeType) || ParserFactory.getParserIdForExtension(path) || ParserFactory.getParserIdForExtension(url); - - if (!parserId) { - debug('No parser found for MIME-type / extension: ' + mimeType); - } - - return this.parse(tokenizer, parserId, opts); + if (!parserId) { + debug(`No parser found for MIME-type / extension: ${mimeType}`); } - public static async parse(tokenizer: ITokenizer, parserId: ParserType, opts: IOptions): Promise { + return parse(tokenizer, parserId, opts); +} + +export async function parse(tokenizer: ITokenizer, parserId: ParserType, opts: IOptions): Promise { - if (!parserId) { - // Parser could not be determined on MIME-type or extension - debug('Guess parser on content...'); + let id = parserId; + if (!id) { + // Parser could not be determined on MIME-type or extension + debug('Guess parser on content...'); - const buf = new Uint8Array(4100); - await tokenizer.peekBuffer(buf, {mayBeLess: true}); - if (tokenizer.fileInfo.path) { - parserId = this.getParserIdForExtension(tokenizer.fileInfo.path); + const buf = new Uint8Array(4100); + await tokenizer.peekBuffer(buf, {mayBeLess: true}); + if (tokenizer.fileInfo.path) { + id = getParserIdForExtension(tokenizer.fileInfo.path); + } + if (!id) { + const guessedType = await fileTypeFromBuffer(buf); + if (!guessedType) { + throw new Error('Failed to determine audio format'); } - if (!parserId) { - const guessedType = await fileTypeFromBuffer(buf); - if (!guessedType) { - throw new Error('Failed to determine audio format'); - } - debug(`Guessed file type is mime=${guessedType.mime}, extension=${guessedType.ext}`); - parserId = ParserFactory.getParserIdForMimeType(guessedType.mime); - if (!parserId) { - throw new Error('Guessed MIME-type not supported: ' + guessedType.mime); - } + debug(`Guessed file type is mime=${guessedType.mime}, extension=${guessedType.ext}`); + id = getParserIdForMimeType(guessedType.mime); + if (!id) { + throw new Error(`Guessed MIME-type not supported: ${guessedType.mime}`); } } - // Parser found, execute parser - return parse(tokenizer, parserId, opts); } + // Parser found, execute parser + const parser = await loadParser(id); + const metadata = new MetadataCollector(opts); + await parser.init(metadata, tokenizer, opts).parse(); + return metadata.toCommonMetadata(); +} - /** - * @param filePath - Path, filename or extension to audio file - * @return Parser sub-module name - */ - public static getParserIdForExtension(filePath: string): ParserType { - if (!filePath) - return; - - const extension = this.getExtension(filePath).toLocaleLowerCase() || filePath; - - switch (extension) { - - case '.mp2': - case '.mp3': - case '.m2a': - case '.aac': // Assume it is ADTS-container - return 'mpeg'; - - case '.ape': - return 'apev2'; - - case '.mp4': - case '.m4a': - case '.m4b': - case '.m4pa': - case '.m4v': - case '.m4r': - case '.3gp': - return 'mp4'; - - case '.wma': - case '.wmv': - case '.asf': - return 'asf'; - - case '.flac': - return 'flac'; - - case '.ogg': - case '.ogv': - case '.oga': - case '.ogm': - case '.ogx': - case '.opus': // recommended filename extension for Ogg Opus - case '.spx': // recommended filename extension for Ogg Speex - return 'ogg'; - - case '.aif': - case '.aiff': - case '.aifc': - return 'aiff'; - - case '.wav': - case '.bwf': // Broadcast Wave Format - return 'riff'; - - case '.wv': - case '.wvp': - return 'wavpack'; - - case '.mpc': - return 'musepack'; - - case '.dsf': - return 'dsf'; - - case '.dff': - return 'dsdiff'; - - case '.mka': - case '.mkv': - case '.mk3d': - case '.mks': - case '.webm': - return 'matroska'; - } +/** + * @param filePath - Path, filename or extension to audio file + * @return Parser submodule name + */ +export function getParserIdForExtension(filePath: string): ParserType { + if (!filePath) + return; + + const extension = getExtension(filePath).toLocaleLowerCase() || filePath; + + switch (extension) { + + case '.mp2': + case '.mp3': + case '.m2a': + case '.aac': // Assume it is ADTS-container + return 'mpeg'; + + case '.ape': + return 'apev2'; + + case '.mp4': + case '.m4a': + case '.m4b': + case '.m4pa': + case '.m4v': + case '.m4r': + case '.3gp': + return 'mp4'; + + case '.wma': + case '.wmv': + case '.asf': + return 'asf'; + + case '.flac': + return 'flac'; + + case '.ogg': + case '.ogv': + case '.oga': + case '.ogm': + case '.ogx': + case '.opus': // recommended filename extension for Ogg Opus + case '.spx': // recommended filename extension for Ogg Speex + return 'ogg'; + + case '.aif': + case '.aiff': + case '.aifc': + return 'aiff'; + + case '.wav': + case '.bwf': // Broadcast Wave Format + return 'riff'; + + case '.wv': + case '.wvp': + return 'wavpack'; + + case '.mpc': + return 'musepack'; + + case '.dsf': + return 'dsf'; + + case '.dff': + return 'dsdiff'; + + case '.mka': + case '.mkv': + case '.mk3d': + case '.mks': + case '.webm': + return 'matroska'; } +} - public static async loadParser(moduleName: ParserType): Promise { - switch (moduleName) { - case 'aiff': return new AIFFParser(); - case 'adts': - case 'mpeg': - return new MpegParser(); - case 'apev2': return new APEv2Parser(); - case 'asf': return new AsfParser(); - case 'dsf': return new DsfParser(); - case 'dsdiff': return new DsdiffParser(); - case 'flac': return new FlacParser(); - case 'mp4': return new MP4Parser(); - case 'musepack': return new MusepackParser(); - case 'ogg': return new OggParser(); - case 'riff': return new WaveParser(); - case 'wavpack': return new WavPackParser(); - case 'matroska': return new MatroskaParser(); - default: - throw new Error(`Unknown parser type: ${moduleName}`); - } +export async function loadParser(moduleName: ParserType): Promise { + switch (moduleName) { + case 'aiff': return new AIFFParser(); + case 'adts': + case 'mpeg': + return new MpegParser(); + case 'apev2': return new APEv2Parser(); + case 'asf': return new AsfParser(); + case 'dsf': return new DsfParser(); + case 'dsdiff': return new DsdiffParser(); + case 'flac': return new FlacParser(); + case 'mp4': return new MP4Parser(); + case 'musepack': return new MusepackParser(); + case 'ogg': return new OggParser(); + case 'riff': return new WaveParser(); + case 'wavpack': return new WavPackParser(); + case 'matroska': return new MatroskaParser(); + default: + throw new Error(`Unknown parser type: ${moduleName}`); } +} - private static getExtension(fname: string): string { - const i = fname.lastIndexOf('.'); - return i === -1 ? '' : fname.slice(i); - } +function getExtension(fname: string): string { + const i = fname.lastIndexOf('.'); + return i === -1 ? '' : fname.slice(i); +} - /** - * @param httpContentType - HTTP Content-Type, extension, path or filename - * @returns Parser sub-module name - */ - private static getParserIdForMimeType(httpContentType: string): ParserType { - - let mime; - try { - mime = parseHttpContentType(httpContentType); - } catch (err) { - debug(`Invalid HTTP Content-Type header value: ${httpContentType}`); - return; - } +/** + * @param httpContentType - HTTP Content-Type, extension, path or filename + * @returns Parser submodule name + */ +function getParserIdForMimeType(httpContentType: string): ParserType { + + let mime: IContentType; + try { + mime = parseHttpContentType(httpContentType); + } catch (err) { + debug(`Invalid HTTP Content-Type header value: ${httpContentType}`); + return; + } - const subType = mime.subtype.indexOf('x-') === 0 ? mime.subtype.substring(2) : mime.subtype; + const subType = mime.subtype.indexOf('x-') === 0 ? mime.subtype.substring(2) : mime.subtype; - switch (mime.type) { + switch (mime.type) { - case 'audio': - switch (subType) { + case 'audio': + switch (subType) { - case 'mp3': // Incorrect MIME-type, Chrome, in Web API File object - case 'mpeg': - return 'mpeg'; + case 'mp3': // Incorrect MIME-type, Chrome, in Web API File object + case 'mpeg': + return 'mpeg'; - case 'aac': - case 'aacp': - return 'adts'; + case 'aac': + case 'aacp': + return 'adts'; - case 'flac': - return 'flac'; + case 'flac': + return 'flac'; - case 'ape': - case 'monkeys-audio': - return 'apev2'; + case 'ape': + case 'monkeys-audio': + return 'apev2'; - case 'mp4': - case 'm4a': - return 'mp4'; + case 'mp4': + case 'm4a': + return 'mp4'; - case 'ogg': // RFC 7845 - case 'opus': // RFC 6716 - case 'speex': // RFC 5574 - return 'ogg'; + case 'ogg': // RFC 7845 + case 'opus': // RFC 6716 + case 'speex': // RFC 5574 + return 'ogg'; - case 'ms-wma': - case 'ms-wmv': - case 'ms-asf': - return 'asf'; + case 'ms-wma': + case 'ms-wmv': + case 'ms-asf': + return 'asf'; - case 'aiff': - case 'aif': - case 'aifc': - return 'aiff'; + case 'aiff': + case 'aif': + case 'aifc': + return 'aiff'; - case 'vnd.wave': - case 'wav': - case 'wave': - return 'riff'; + case 'vnd.wave': + case 'wav': + case 'wave': + return 'riff'; - case 'wavpack': - return 'wavpack'; + case 'wavpack': + return 'wavpack'; - case 'musepack': - return 'musepack'; + case 'musepack': + return 'musepack'; - case 'matroska': - case 'webm': - return 'matroska'; + case 'matroska': + case 'webm': + return 'matroska'; - case 'dsf': - return 'dsf'; - } - break; + case 'dsf': + return 'dsf'; + } + break; - case 'video': - switch (subType) { + case 'video': + switch (subType) { - case 'ms-asf': - case 'ms-wmv': - return 'asf'; + case 'ms-asf': + case 'ms-wmv': + return 'asf'; - case 'm4v': - case 'mp4': - return 'mp4'; + case 'm4v': + case 'mp4': + return 'mp4'; - case 'ogg': - return 'ogg'; + case 'ogg': + return 'ogg'; - case 'matroska': - case 'webm': - return 'matroska'; - } - break; + case 'matroska': + case 'webm': + return 'matroska'; + } + break; - case 'application': - switch (subType) { + case 'application': + switch (subType) { - case 'vnd.ms-asf': - return 'asf'; + case 'vnd.ms-asf': + return 'asf'; - case 'ogg': - return 'ogg'; - } - break; - } + case 'ogg': + return 'ogg'; + } + break; } - } diff --git a/lib/aiff/AiffParser.ts b/lib/aiff/AiffParser.ts index 4f1d58444..763cd9bad 100644 --- a/lib/aiff/AiffParser.ts +++ b/lib/aiff/AiffParser.ts @@ -54,13 +54,13 @@ export class AIFFParser extends BasicParser { break; default: - throw Error('Unsupported AIFF type: ' + type); + throw new Error(`Unsupported AIFF type: ${type}`); } this.metadata.setFormat('lossless', !this.isCompressed); try { while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= iff.Header.len) { - debug('Reading AIFF chunk at offset=' + this.tokenizer.position); + debug(`Reading AIFF chunk at offset=${this.tokenizer.position}`); const chunkHeader = await this.tokenizer.readToken(iff.Header); const nextChunk = 2 * Math.round(chunkHeader.chunkSize / 2); @@ -69,7 +69,7 @@ export class AIFFParser extends BasicParser { } } catch (err) { if (err instanceof strtok3.EndOfStreamError) { - debug(`End-of-stream`); + debug("End-of-stream"); } else { throw err; } @@ -79,7 +79,7 @@ export class AIFFParser extends BasicParser { public async readData(header: iff.IChunkHeader): Promise { switch (header.chunkID) { - case 'COMM': // The Common Chunk + case 'COMM': { // The Common Chunk const common = await this.tokenizer.readToken(new AiffToken.Common(header, this.isCompressed)); this.metadata.setFormat('bitsPerSample', common.sampleSize); this.metadata.setFormat('sampleRate', common.sampleRate); @@ -88,12 +88,14 @@ export class AIFFParser extends BasicParser { this.metadata.setFormat('duration', common.numSampleFrames / common.sampleRate); this.metadata.setFormat('codec', common.compressionName ?? compressionTypes[common.compressionType]); return header.chunkSize; + } - case 'ID3 ': // ID3-meta-data + case 'ID3 ': { // ID3-meta-data const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize)); const rst = strtok3.fromBuffer(id3_data); await new ID3v2Parser().parse(this.metadata, rst, this.options); return header.chunkSize; + } case 'SSND': // Sound Data Chunk if (this.metadata.format.duration) { @@ -115,7 +117,7 @@ export class AIFFParser extends BasicParser { public async readTextChunk(header: iff.IChunkHeader): Promise { const value = await this.tokenizer.readToken(new Token.StringType(header.chunkSize, 'ascii')); - const values = value.split('\0').map(v => v.trim()).filter(v => v && v.length); + const values = value.split('\0').map(v => v.trim()).filter(v => v?.length); await Promise.all(values.map(v => this.metadata.addTag('AIFF', header.chunkID, v))); return header.chunkSize; } diff --git a/lib/aiff/AiffTagMap.ts b/lib/aiff/AiffTagMap.ts index 5f99f9a29..6d2517a1c 100644 --- a/lib/aiff/AiffTagMap.ts +++ b/lib/aiff/AiffTagMap.ts @@ -1,4 +1,4 @@ -import { INativeTagMap } from '../common/GenericTagTypes.js'; +import type { INativeTagMap } from '../common/GenericTagTypes.js'; import { CommonTagMapper } from '../common/GenericTagMapper.js'; /** diff --git a/lib/aiff/AiffToken.ts b/lib/aiff/AiffToken.ts index 13ea1baff..a9668ccd7 100644 --- a/lib/aiff/AiffToken.ts +++ b/lib/aiff/AiffToken.ts @@ -1,7 +1,7 @@ import * as Token from 'token-types'; import { FourCcToken } from '../common/FourCC.js'; -import * as iff from '../iff/index.js'; +import type * as iff from '../iff/index.js'; import type { IGetToken } from 'strtok3'; diff --git a/lib/apev2/APEv2Parser.ts b/lib/apev2/APEv2Parser.ts index ea938521c..599b5310b 100644 --- a/lib/apev2/APEv2Parser.ts +++ b/lib/apev2/APEv2Parser.ts @@ -4,16 +4,16 @@ import { StringType } from 'token-types'; import { uint8ArrayToString } from 'uint8array-extras'; import * as util from '../common/Util.js'; -import { IOptions, IRandomReader, IApeHeader } from '../type.js'; -import { INativeMetadataCollector } from '../common/MetadataCollector.js'; +import type { IOptions, IRandomReader, IApeHeader } from '../type.js'; +import type { INativeMetadataCollector } from '../common/MetadataCollector.js'; import { BasicParser } from '../common/BasicParser.js'; import { DataType, DescriptorParser, Header, - IDescriptor, - IFooter, - IHeader, ITagItemHeader, + type IDescriptor, + type IFooter, + type IHeader, type ITagItemHeader, TagFooter, TagItemHeader } from './APEv2Token.js'; @@ -87,7 +87,7 @@ export class APEv2Parser extends BasicParser { public async tryParseApeHeader(): Promise { if (this.tokenizer.fileInfo.size && this.tokenizer.fileInfo.size - this.tokenizer.position < TagFooter.len) { - debug(`No APEv2 header found, end-of-file reached`); + debug("No APEv2 header found, end-of-file reached"); return; } @@ -95,7 +95,7 @@ export class APEv2Parser extends BasicParser { if (footer.ID === preamble) { await this.tokenizer.ignore(TagFooter.len); return this.parseTags(footer); - } else { + } debug(`APEv2 header not found at offset=${this.tokenizer.position}`); if (this.tokenizer.fileInfo.size) { // Try to read the APEv2 header using just the footer-header @@ -104,7 +104,6 @@ export class APEv2Parser extends BasicParser { await this.tokenizer.readBuffer(buffer); return APEv2Parser.parseTagFooter(this.metadata, buffer, this.options); } - } } public async parse(): Promise { diff --git a/lib/apev2/APEv2TagMapper.ts b/lib/apev2/APEv2TagMapper.ts index a80749e5d..578ca2e2d 100644 --- a/lib/apev2/APEv2TagMapper.ts +++ b/lib/apev2/APEv2TagMapper.ts @@ -1,4 +1,4 @@ -import {INativeTagMap} from '../common/GenericTagTypes.js'; +import type {INativeTagMap} from '../common/GenericTagTypes.js'; import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js'; /** diff --git a/lib/asf/AsfObject.ts b/lib/asf/AsfObject.ts index fb80a1ea4..f9d81061c 100644 --- a/lib/asf/AsfObject.ts +++ b/lib/asf/AsfObject.ts @@ -4,11 +4,10 @@ import * as Token from 'token-types'; import type { IGetToken, ITokenizer } from 'strtok3'; import * as util from '../common/Util.js'; -import { IPicture, ITag } from '../type.js'; +import type { AnyTagValue, IPicture, ITag } from '../type.js'; import GUID from './GUID.js'; -import { AsfUtil } from './AsfUtil.js'; +import { getParserForAttr, parseUnicodeAttr } from './AsfUtil.js'; import { AttachedPictureType } from '../id3v2/ID3v2Token.js'; -import { base64ToUint8Array } from 'uint8array-extras'; /** * Data Type: Specifies the type of information being stored. The following values are recognized. @@ -17,27 +16,27 @@ export enum DataType { /** * Unicode string. The data consists of a sequence of Unicode characters. */ - UnicodeString, + UnicodeString = 0, /** * BYTE array. The type of data is implementation-specific. */ - ByteArray, + ByteArray = 1, /** * BOOL. The data is 2 bytes long and should be interpreted as a 16-bit unsigned integer. Only 0x0000 or 0x0001 are permitted values. */ - Bool, + Bool = 2, /** * DWORD. The data is 4 bytes long and should be interpreted as a 32-bit unsigned integer. */ - DWord, + DWord = 3, /** * QWORD. The data is 8 bytes long and should be interpreted as a 64-bit unsigned integer. */ - QWord, + QWord = 4, /** * WORD. The data is 2 bytes long and should be interpreted as a 16-bit unsigned integer. */ - Word + Word = 5 } /** @@ -108,25 +107,21 @@ export abstract class State implements IGetToken { public abstract get(buf: Uint8Array, off: number): T; - protected postProcessTag(tags: ITag[], name: string, valueType: number, data: any) { + protected postProcessTag(tags: ITag[], name: string, valueType: number, data: AnyTagValue) { if (name === 'WM/Picture') { - tags.push({id: name, value: WmPictureToken.fromBuffer(data)}); + tags.push({id: name, value: WmPictureToken.fromBuffer(data as Uint8Array)}); } else { - const parseAttr = AsfUtil.getParserForAttr(valueType); + const parseAttr = getParserForAttr(valueType); if (!parseAttr) { - throw new Error('unexpected value headerType: ' + valueType); + throw new Error(`unexpected value headerType: ${valueType}`); } - tags.push({id: name, value: parseAttr(data)}); + tags.push({id: name, value: parseAttr(data as Uint8Array)}); } } } // ToDo: use ignore type -export class IgnoreObjectState extends State { - - constructor(header: IAsfObjectHeader) { - super(header); - } +export class IgnoreObjectState extends State { public get(buf: Uint8Array, off: number): null { return null; @@ -241,10 +236,6 @@ export class FilePropertiesObject extends State { public static guid = GUID.FilePropertiesObject; - constructor(header: IAsfObjectHeader) { - super(header); - } - public get(buf: Uint8Array, off: number): IFilePropertiesObject { return { @@ -292,10 +283,6 @@ export class StreamPropertiesObject extends State { public static guid = GUID.StreamPropertiesObject; - public constructor(header: IAsfObjectHeader) { - super(header); - } - public get(buf: Uint8Array, off: number): IStreamPropertiesObject { return { @@ -419,10 +406,6 @@ export class ContentDescriptionObjectState extends State { private static contentDescTags = ['Title', 'Author', 'Copyright', 'Description', 'Rating']; - constructor(header: IAsfObjectHeader) { - super(header); - } - public get(buf: Uint8Array, off: number): ITag[] { const tags: ITag[] = []; @@ -433,7 +416,7 @@ export class ContentDescriptionObjectState extends State { if (length > 0) { const tagName = ContentDescriptionObjectState.contentDescTags[i]; const end = pos + length; - tags.push({id: tagName, value: AsfUtil.parseUnicodeAttr(buf.slice(off + pos, off + end))}); + tags.push({id: tagName, value: parseUnicodeAttr(buf.slice(off + pos, off + end))}); pos = end; } } @@ -449,10 +432,6 @@ export class ExtendedContentDescriptionObjectState extends State { public static guid = GUID.ExtendedContentDescriptionObject; - constructor(header: IAsfObjectHeader) { - super(header); - } - public get(buf: Uint8Array, off: number): ITag[] { const tags: ITag[] = []; const view = new DataView(buf.buffer, off); @@ -461,7 +440,7 @@ export class ExtendedContentDescriptionObjectState extends State { for (let i = 0; i < attrCount; i += 1) { const nameLen = view.getUint16(pos, true); pos += 2; - const name = AsfUtil.parseUnicodeAttr(buf.slice(off + pos, off + pos + nameLen)); + const name = parseUnicodeAttr(buf.slice(off + pos, off + pos + nameLen)); pos += nameLen; const valueType = view.getUint16(pos, true); pos += 2; @@ -517,10 +496,6 @@ export class ExtendedStreamPropertiesObjectState extends State { public static guid = GUID.MetadataObject; - constructor(header: IAsfObjectHeader) { - super(header); - } - public get(uint8Array: Uint8Array, off: number): ITag[] { const tags: ITag[] = []; @@ -576,7 +547,7 @@ export class MetadataObjectState extends State { pos += 2; const dataLen = view.getUint32(pos, true); pos += 4; - const name = AsfUtil.parseUnicodeAttr(uint8Array.slice(off + pos, off + pos + nameLen)); + const name = parseUnicodeAttr(uint8Array.slice(off + pos, off + pos + nameLen)); pos += nameLen; const data = uint8Array.slice(off + pos, off + pos + dataLen); pos += dataLen; @@ -587,13 +558,11 @@ export class MetadataObjectState extends State { } // 4.8 Metadata Library Object (optional, 0 or 1) + +// biome-ignore lint/complexity/noStaticOnlyClass: Extends a non-static class export class MetadataLibraryObjectState extends MetadataObjectState { public static guid = GUID.MetadataLibraryObject; - - constructor(header: IAsfObjectHeader) { - super(header); - } } export interface IWmPicture extends IPicture { @@ -609,10 +578,6 @@ export interface IWmPicture extends IPicture { */ export class WmPictureToken implements IGetToken { - public static fromBase64(base64str: string): IPicture { - return this.fromBuffer(base64ToUint8Array(base64str)); - } - public static fromBuffer(buffer: Uint8Array): IWmPicture { const pic = new WmPictureToken(buffer.length); return pic.get(buffer, 0); diff --git a/lib/asf/AsfParser.ts b/lib/asf/AsfParser.ts index 8aaee8290..cc7524312 100644 --- a/lib/asf/AsfParser.ts +++ b/lib/asf/AsfParser.ts @@ -1,6 +1,6 @@ import initDebug from 'debug'; -import { ITag, TrackType } from '../type.js'; +import { type ITag, TrackType } from '../type.js'; import GUID from './GUID.js'; import * as AsfObject from './AsfObject.js'; import { BasicParser } from '../common/BasicParser.js'; @@ -23,7 +23,7 @@ export class AsfParser extends BasicParser { public async parse() { const header = await this.tokenizer.readToken(AsfObject.TopLevelHeaderObjectToken); if (!header.objectId.equals(GUID.HeaderObject)) { - throw new Error('expected asf header; but was not found; got: ' + header.objectId.str); + throw new Error(`expected asf header; but was not found; got: ${header.objectId.str}`); } try { await this.parseObjectHeader(header.numberOfHeaderObjects); @@ -33,7 +33,6 @@ export class AsfParser extends BasicParser { } private async parseObjectHeader(numberOfObjectHeaders: number): Promise { - let tags: ITag[]; do { // Parse common header of the ASF Object (3.1) @@ -42,21 +41,24 @@ export class AsfParser extends BasicParser { debug('header GUID=%s', header.objectId.str); switch (header.objectId.str) { - case AsfObject.FilePropertiesObject.guid.str: // 3.2 + case AsfObject.FilePropertiesObject.guid.str: { // 3.2 const fpo = await this.tokenizer.readToken(new AsfObject.FilePropertiesObject(header)); this.metadata.setFormat('duration', Number(fpo.playDuration / BigInt(1000)) / 10000 - Number(fpo.preroll) / 1000); this.metadata.setFormat('bitrate', fpo.maximumBitrate); break; + } - case AsfObject.StreamPropertiesObject.guid.str: // 3.3 + case AsfObject.StreamPropertiesObject.guid.str: { // 3.3 const spo = await this.tokenizer.readToken(new AsfObject.StreamPropertiesObject(header)); - this.metadata.setFormat('container', 'ASF/' + spo.streamType); + this.metadata.setFormat('container', `ASF/${spo.streamType}`); break; + } - case AsfObject.HeaderExtensionObject.guid.str: // 3.4 + case AsfObject.HeaderExtensionObject.guid.str: { // 3.4 const extHeader = await this.tokenizer.readToken(new AsfObject.HeaderExtensionObject()); await this.parseExtensionObject(extHeader.extensionDataSize); break; + } case AsfObject.ContentDescriptionObjectState.guid.str: // 3.10 tags = await this.tokenizer.readToken(new AsfObject.ContentDescriptionObjectState(header)); @@ -68,7 +70,7 @@ export class AsfParser extends BasicParser { await this.addTags(tags); break; - case GUID.CodecListObject.str: + case GUID.CodecListObject.str: { const codecs = await AsfObject.readCodecEntries(this.tokenizer); codecs.forEach(codec => { this.metadata.addStreamInfo({ @@ -79,6 +81,7 @@ export class AsfParser extends BasicParser { const audioCodecs = codecs.filter(codec => codec.type.audioCodec).map(codec => codec.codecName).join('/'); this.metadata.setFormat('codec', audioCodecs); break; + } case GUID.StreamBitratePropertiesObject.str: // ToDo? @@ -92,7 +95,7 @@ export class AsfParser extends BasicParser { break; default: - this.metadata.addWarning('Ignore ASF-Object-GUID: ' + header.objectId.str); + this.metadata.addWarning(`Ignore ASF-Object-GUID: ${header.objectId.str}`); debug('Ignore ASF-Object-GUID: %s', header.objectId.str); await this.tokenizer.readToken(new AsfObject.IgnoreObjectState(header)); } @@ -105,7 +108,6 @@ export class AsfParser extends BasicParser { } private async parseExtensionObject(extensionSize: number): Promise { - do { // Parse common header of the ASF Object (3.1) const header = await this.tokenizer.readToken(AsfObject.HeaderObjectToken); @@ -118,15 +120,17 @@ export class AsfParser extends BasicParser { await this.tokenizer.readToken(new AsfObject.ExtendedStreamPropertiesObjectState(header)); break; - case AsfObject.MetadataObjectState.guid.str: // 4.7 + case AsfObject.MetadataObjectState.guid.str: { // 4.7 const moTags = await this.tokenizer.readToken(new AsfObject.MetadataObjectState(header)); await this.addTags(moTags); break; + } - case AsfObject.MetadataLibraryObjectState.guid.str: // 4.8 + case AsfObject.MetadataLibraryObjectState.guid.str: { // 4.8 const mlTags = await this.tokenizer.readToken(new AsfObject.MetadataLibraryObjectState(header)); await this.addTags(mlTags); break; + } case GUID.PaddingObject.str: // ToDo: register bytes pad @@ -142,7 +146,7 @@ export class AsfParser extends BasicParser { break; default: - this.metadata.addWarning('Ignore ASF-Object-GUID: ' + header.objectId.str); + this.metadata.addWarning(`Ignore ASF-Object-GUID: ${header.objectId.str}`); // console.log("Ignore ASF-Object-GUID: %s", header.objectId.str); await this.tokenizer.readToken(new AsfObject.IgnoreObjectState(header)); break; diff --git a/lib/asf/AsfTagMapper.ts b/lib/asf/AsfTagMapper.ts index a44f7ea4e..ccdac6887 100644 --- a/lib/asf/AsfTagMapper.ts +++ b/lib/asf/AsfTagMapper.ts @@ -1,6 +1,6 @@ -import {INativeTagMap} from '../common/GenericTagTypes.js'; +import type {INativeTagMap} from '../common/GenericTagTypes.js'; import {CommonTagMapper} from '../common/GenericTagMapper.js'; -import {IRating, ITag} from '../type.js'; +import type {IRating, ITag} from '../type.js'; /** * ASF Metadata tag mappings. @@ -81,7 +81,7 @@ export class AsfTagMapper extends CommonTagMapper { public static toRating(rating: string): IRating { return { - rating: parseFloat(rating + 1) / 5 + rating: Number.parseFloat(rating + 1) / 5 }; } @@ -92,11 +92,12 @@ export class AsfTagMapper extends CommonTagMapper { protected postMap(tag: ITag): void { switch (tag.id) { - case 'WM/SharedUserRating': + case 'WM/SharedUserRating': { const keys = tag.id.split(':'); - tag.value = AsfTagMapper.toRating(tag.value); + tag.value = AsfTagMapper.toRating(tag.value as string); tag.id = keys[0]; break; + } } } diff --git a/lib/asf/AsfUtil.ts b/lib/asf/AsfUtil.ts index 42e41964e..65201e99e 100644 --- a/lib/asf/AsfUtil.ts +++ b/lib/asf/AsfUtil.ts @@ -1,47 +1,45 @@ import * as Token from 'token-types'; import * as util from '../common/Util.js'; -import { DataType } from './AsfObject.js'; +import type { DataType } from './AsfObject.js'; export type AttributeParser = (buf: Uint8Array) => boolean | string | number | bigint | Uint8Array; -export class AsfUtil { - - public static getParserForAttr(i: DataType): AttributeParser { - return AsfUtil.attributeParsers[i]; - } +export function getParserForAttr(i: DataType): AttributeParser { + return attributeParsers[i]; +} - public static parseUnicodeAttr(uint8Array: Uint8Array): string { - return util.stripNulls(util.decodeString(uint8Array, 'utf-16le')); - } +export function parseUnicodeAttr(uint8Array: Uint8Array): string { + return util.stripNulls(util.decodeString(uint8Array, 'utf-16le')); +} - private static attributeParsers: AttributeParser[] = [ - AsfUtil.parseUnicodeAttr, - AsfUtil.parseByteArrayAttr, - AsfUtil.parseBoolAttr, - AsfUtil.parseDWordAttr, - AsfUtil.parseQWordAttr, - AsfUtil.parseWordAttr, - AsfUtil.parseByteArrayAttr - ]; - - private static parseByteArrayAttr(buf: Uint8Array): Uint8Array { +const attributeParsers: AttributeParser[] = [ + parseUnicodeAttr, + parseByteArrayAttr, + parseBoolAttr, + parseDWordAttr, + parseQWordAttr, + parseWordAttr, + parseByteArrayAttr +]; + +function parseByteArrayAttr(buf: Uint8Array): Uint8Array { return new Uint8Array(buf); } - private static parseBoolAttr(buf: Uint8Array, offset: number = 0): boolean { - return AsfUtil.parseWordAttr(buf, offset) === 1; - } +function parseBoolAttr(buf: Uint8Array, offset = 0): boolean { + return parseWordAttr(buf, offset) === 1; +} - private static parseDWordAttr(buf: Uint8Array, offset: number = 0): number { - return Token.UINT32_LE.get(buf, offset); - } +function parseDWordAttr(buf: Uint8Array, offset = 0): number { + return Token.UINT32_LE.get(buf, offset); +} - private static parseQWordAttr(buf: Uint8Array, offset: number = 0): bigint { - return Token.UINT64_LE.get(buf, offset); - } +function parseQWordAttr(buf: Uint8Array, offset = 0): bigint { + return Token.UINT64_LE.get(buf, offset); +} - private static parseWordAttr(buf: Uint8Array, offset: number = 0): number { - return Token.UINT16_LE.get(buf, offset); - } +function parseWordAttr(buf: Uint8Array, offset = 0): number { + return Token.UINT16_LE.get(buf, offset); } + diff --git a/lib/asf/GUID.ts b/lib/asf/GUID.ts index 2522a6028..9401a4e8e 100644 --- a/lib/asf/GUID.ts +++ b/lib/asf/GUID.ts @@ -68,8 +68,8 @@ export default class GUID { public static ASF_Index_Placeholder_Object = new GUID("D9AADE20-7C17-4F9C-BC28-8555DD98E2A2"); - public static fromBin(bin: Uint8Array, offset: number = 0) { - return new GUID(this.decode(bin, offset)); + public static fromBin(bin: Uint8Array, offset = 0) { + return new GUID(GUID.decode(bin, offset)); } /** @@ -78,13 +78,9 @@ export default class GUID { * @param offset Read offset in bytes, default 0 * @returns GUID as dashed hexadecimal representation */ - public static decode(objectId: Uint8Array, offset: number = 0): string { + public static decode(objectId: Uint8Array, offset = 0): string { const view = new DataView(objectId.buffer, offset); - const guid = view.getUint32(0, true).toString(16) + "-" + - view.getUint16(4, true).toString(16) + "-" + - view.getUint16(6, true).toString(16) + "-" + - view.getUint16(8).toString(16) + "-" + - uint8ArrayToHex(objectId.slice(offset + 10, offset + 16)); + const guid = `${view.getUint32(0, true).toString(16)}-${view.getUint16(4, true).toString(16)}-${view.getUint16(6, true).toString(16)}-${view.getUint16(8).toString(16)}-${uint8ArrayToHex(objectId.slice(offset + 10, offset + 16))}`; return guid.toUpperCase(); } @@ -113,9 +109,9 @@ export default class GUID { public static encode(str: string): Uint8Array { const bin = new Uint8Array(16); const view = new DataView(bin.buffer); - view.setUint32(0, parseInt(str.slice(0, 8), 16), true); - view.setUint16(4, parseInt(str.slice(9, 13), 16), true); - view.setUint16(6, parseInt(str.slice(14, 18), 16), true); + view.setUint32(0, Number.parseInt(str.slice(0, 8), 16), true); + view.setUint16(4, Number.parseInt(str.slice(9, 13), 16), true); + view.setUint16(6, Number.parseInt(str.slice(14, 18), 16), true); bin.set(hexToUint8Array(str.slice(19, 23)), 8); bin.set(hexToUint8Array(str.slice(24)), 10); diff --git a/lib/common/BasicParser.ts b/lib/common/BasicParser.ts index 74376a1ce..fd61b5e4c 100644 --- a/lib/common/BasicParser.ts +++ b/lib/common/BasicParser.ts @@ -1,8 +1,8 @@ import type { ITokenizer } from 'strtok3'; -import { ITokenParser } from '../ParserFactory.js'; -import { IOptions, IPrivateOptions } from '../type.js'; -import { INativeMetadataCollector } from './MetadataCollector.js'; +import type { ITokenParser } from '../ParserFactory.js'; +import type { IOptions, IPrivateOptions } from '../type.js'; +import type { INativeMetadataCollector } from './MetadataCollector.js'; export abstract class BasicParser implements ITokenParser { diff --git a/lib/common/CaseInsensitiveTagMap.ts b/lib/common/CaseInsensitiveTagMap.ts index 8db01723c..fd689373c 100644 --- a/lib/common/CaseInsensitiveTagMap.ts +++ b/lib/common/CaseInsensitiveTagMap.ts @@ -1,4 +1,4 @@ -import { INativeTagMap, TagType } from './GenericTagTypes.js'; +import type { INativeTagMap, TagType } from './GenericTagTypes.js'; import { CommonTagMapper } from './GenericTagMapper.js'; export class CaseInsensitiveTagMap extends CommonTagMapper { diff --git a/lib/common/CombinedTagMapper.ts b/lib/common/CombinedTagMapper.ts index 0a1d73b42..9e2c6b624 100644 --- a/lib/common/CombinedTagMapper.ts +++ b/lib/common/CombinedTagMapper.ts @@ -1,15 +1,15 @@ import { ID3v1TagMapper } from '../id3v1/ID3v1TagMap.js'; import { ID3v24TagMapper } from '../id3v2/ID3v24TagMapper.js'; import { AsfTagMapper } from '../asf/AsfTagMapper.js'; -import { IGenericTag, TagType } from './GenericTagTypes.js'; +import type { IGenericTag, TagType } from './GenericTagTypes.js'; import { ID3v22TagMapper } from '../id3v2/ID3v22TagMapper.js'; import { APEv2TagMapper } from '../apev2/APEv2TagMapper.js'; -import { IGenericTagMapper } from './GenericTagMapper.js'; +import type { IGenericTagMapper } from './GenericTagMapper.js'; import { MP4TagMapper } from '../mp4/MP4TagMapper.js'; import { VorbisTagMapper } from '../ogg/vorbis/VorbisTagMapper.js'; import { RiffInfoTagMapper } from '../riff/RiffInfoTagMap.js'; -import { ITag } from '../type.js'; -import { INativeMetadataCollector } from './MetadataCollector.js'; +import type { ITag } from '../type.js'; +import type { INativeMetadataCollector } from './MetadataCollector.js'; import { MatroskaTagMapper } from '../matroska/MatroskaTagMapper.js'; import { AiffTagMapper } from '../aiff/AiffTagMap.js'; @@ -47,7 +47,7 @@ export class CombinedTagMapper { if (tagMapper) { return this.tagMappers[tagType].mapGenericTag(tag, warnings); } - throw new Error('No generic tag mapper defined for tag-format: ' + tagType); + throw new Error(`No generic tag mapper defined for tag-format: ${tagType}`); } private registerTagMapper(genericTagMapper: IGenericTagMapper) { diff --git a/lib/common/FourCC.ts b/lib/common/FourCC.ts index e4d427596..546c93ac3 100644 --- a/lib/common/FourCC.ts +++ b/lib/common/FourCC.ts @@ -1,4 +1,4 @@ -import { IToken } from 'strtok3'; +import type { IToken } from 'strtok3'; import { stringToUint8Array, uint8ArrayToString } from 'uint8array-extras'; import * as util from './Util.js'; diff --git a/lib/common/GenericTagMapper.ts b/lib/common/GenericTagMapper.ts index 15ca7b601..dd127fdbf 100644 --- a/lib/common/GenericTagMapper.ts +++ b/lib/common/GenericTagMapper.ts @@ -1,6 +1,6 @@ -import * as generic from './GenericTagTypes.js'; -import {ITag} from '../type.js'; -import { INativeMetadataCollector, IWarningCollector } from './MetadataCollector.js'; +import type * as generic from './GenericTagTypes.js'; +import type {ITag} from '../type.js'; +import type { INativeMetadataCollector, IWarningCollector } from './MetadataCollector.js'; export interface IGenericTagMapper { @@ -28,8 +28,8 @@ export class CommonTagMapper implements IGenericTagMapper { public static maxRatingScore = 1; public static toIntOrNull(str: string): number { - const cleaned = parseInt(str, 10); - return isNaN(cleaned) ? null : cleaned; + const cleaned = Number.parseInt(str, 10); + return Number.isNaN(cleaned) ? null : cleaned; } // TODO: a string of 1of1 would fail to be converted @@ -38,8 +38,8 @@ export class CommonTagMapper implements IGenericTagMapper { public static normalizeTrack(origVal: number | string) { const split = origVal.toString().split('/'); return { - no: parseInt(split[0], 10) || null, - of: parseInt(split[1], 10) || null + no: Number.parseInt(split[0], 10) || null, + of: Number.parseInt(split[1], 10) || null }; } diff --git a/lib/common/GenericTagTypes.ts b/lib/common/GenericTagTypes.ts index 7ca2c41b9..20ffe9c8d 100644 --- a/lib/common/GenericTagTypes.ts +++ b/lib/common/GenericTagTypes.ts @@ -1,8 +1,10 @@ +import type { AnyTagValue } from '../type.js'; + export type TagType = 'vorbis' | 'ID3v1' | 'ID3v2.2' | 'ID3v2.3' | 'ID3v2.4' | 'APEv2' | 'asf' | 'iTunes' | 'exif' | 'matroska' | 'AIFF'; export interface IGenericTag { - id: GenericTagId, - value: any + id: GenericTagId; + value: AnyTagValue; } export type GenericTagId = @@ -262,7 +264,7 @@ export const commonTags: ITagInfoMap = { * @returns {boolean|*} true if given alias is mapped as a singleton', otherwise false */ export function isSingleton(alias: GenericTagId): boolean { - return commonTags.hasOwnProperty(alias) && !commonTags[alias].multiple; + return commonTags[alias] && !commonTags[alias].multiple; } /** diff --git a/lib/common/MetadataCollector.ts b/lib/common/MetadataCollector.ts index 94f27ce6a..01204705e 100644 --- a/lib/common/MetadataCollector.ts +++ b/lib/common/MetadataCollector.ts @@ -1,12 +1,12 @@ import { - FormatId, - IAudioMetadata, ICommonTagsResult, - IFormat, - INativeTags, IOptions, IQualityInformation, IPicture, ITrackInfo, TrackType + type FormatId, + type IAudioMetadata, type ICommonTagsResult, + type IFormat, + type INativeTags, type IOptions, type IQualityInformation, type IPicture, type ITrackInfo, TrackType, type IComment, type AnyTagValue } from '../type.js'; import initDebug from 'debug'; -import { IGenericTag, TagType, isSingleton, isUnique } from './GenericTagTypes.js'; +import { type IGenericTag, type TagType, isSingleton, isUnique } from './GenericTagTypes.js'; import { CombinedTagMapper } from './CombinedTagMapper.js'; import { CommonTagMapper } from './GenericTagMapper.js'; import { toRatio } from './Util.js'; @@ -45,9 +45,9 @@ export interface INativeMetadataCollector extends IWarningCollector { */ hasAny(): boolean; - setFormat(key: FormatId, value: any): void; + setFormat(key: FormatId, value: AnyTagValue): void; - addTag(tagType: TagType, tagId: string, value: any): Promise; + addTag(tagType: TagType, tagId: string, value: AnyTagValue): Promise; addStreamInfo(streamInfo: ITrackInfo): void; } @@ -92,7 +92,7 @@ export class MetadataCollector implements INativeMetadataCollector { private tagMapper = new CombinedTagMapper(); public constructor(private opts: IOptions) { - let priority: number = 1; + let priority = 1; for (const tagType of TagPriority) { this.originPriority[tagType] = priority++; } @@ -112,16 +112,16 @@ export class MetadataCollector implements INativeMetadataCollector { this.format.trackInfo.push(streamInfo); } - public setFormat(key: FormatId, value: any) { + public setFormat(key: FormatId, value: AnyTagValue) { debug(`format: ${key} = ${value}`); - (this.format as any)[key] = value; // as any to override readonly + (this.format as unknown as { [id: string]: unknown; })[key] = value; // as any to override readonly if (this.opts.observer) { this.opts.observer({metadata: this, tag: {type: 'format', id: key, value}}); } } - public async addTag(tagType: TagType, tagId: string, value: any): Promise { + public async addTag(tagType: TagType, tagId: string, value: AnyTagValue): Promise { debug(`tag ${tagType}.${tagId} = ${value}`); if (!this.native[tagType]) { this.format.tagTypes.push(tagType); @@ -160,9 +160,9 @@ export class MetadataCollector implements INativeMetadataCollector { case 'artists': if (!this.common.artist || this.commonOrigin.artist === this.originPriority.artificial) { - if (!this.common.artists || this.common.artists.indexOf(tag.value) === -1) { + if (!this.common.artists || this.common.artists.indexOf(tag.value as string) === -1) { // Fill artist using artists source - const artists = (this.common.artists || []).concat([tag.value]); + const artists = (this.common.artists || []).concat([tag.value as string]); const value = joinArtists(artists); const artistTag: IGenericTag = {id: 'artist', value}; this.setGenericTag('artificial', artistTag); @@ -179,65 +179,68 @@ export class MetadataCollector implements INativeMetadataCollector { }); case 'totaltracks': - this.common.track.of = CommonTagMapper.toIntOrNull(tag.value); + this.common.track.of = CommonTagMapper.toIntOrNull(tag.value as string); return; case 'totaldiscs': - this.common.disk.of = CommonTagMapper.toIntOrNull(tag.value); + this.common.disk.of = CommonTagMapper.toIntOrNull(tag.value as string); return; case 'movementTotal': - this.common.movementIndex.of = CommonTagMapper.toIntOrNull(tag.value); + this.common.movementIndex.of = CommonTagMapper.toIntOrNull(tag.value as string); return; case 'track': case 'disk': - case 'movementIndex': + case 'movementIndex': { const of = this.common[tag.id].of; // store of value, maybe maybe overwritten - this.common[tag.id] = CommonTagMapper.normalizeTrack(tag.value); + this.common[tag.id] = CommonTagMapper.normalizeTrack(tag.value as string); this.common[tag.id].of = of != null ? of : this.common[tag.id].of; return; + } case 'bpm': case 'year': case 'originalyear': - tag.value = parseInt(tag.value, 10); + tag.value = Number.parseInt(tag.value as string, 10); break; - case 'date': + case 'date': { // ToDo: be more strict on 'YYYY...' - const year = parseInt(tag.value.substr(0, 4), 10); - if (!isNaN(year)) { + const year = Number.parseInt((tag.value as string).substr(0, 4), 10); + if (!Number.isNaN(year)) { this.common.year = year; } break; + } case 'discogs_label_id': case 'discogs_release_id': case 'discogs_master_release_id': case 'discogs_artist_id': case 'discogs_votes': - tag.value = typeof tag.value === 'string' ? parseInt(tag.value, 10) : tag.value; + tag.value = typeof tag.value === 'string' ? Number.parseInt(tag.value, 10) : tag.value; break; case 'replaygain_track_gain': case 'replaygain_track_peak': case 'replaygain_album_gain': case 'replaygain_album_peak': - tag.value = toRatio(tag.value); + tag.value = toRatio(tag.value as string); break; case 'replaygain_track_minmax': - tag.value = tag.value.split(',').map(v => parseInt(v, 10)); + tag.value = (tag.value as string).split(',').map(v => Number.parseInt(v, 10)); break; - case 'replaygain_undo': - const minMix = tag.value.split(',').map(v => parseInt(v, 10)); + case 'replaygain_undo': { + const minMix = (tag.value as string).split(',').map(v => Number.parseInt(v, 10)); tag.value = { leftChannel: minMix[0], rightChannel: minMix[1] }; break; + } case 'gapless': // iTunes gap-less flag case 'compilation': @@ -247,7 +250,7 @@ export class MetadataCollector implements INativeMetadataCollector { break; case 'isrc': // Only keep unique values - if (this.common[tag.id] && this.common[tag.id].indexOf(tag.value) !== -1) + if (this.common[tag.id] && this.common[tag.id].indexOf(tag.value as string) !== -1) return; break; @@ -255,8 +258,8 @@ export class MetadataCollector implements INativeMetadataCollector { if (typeof tag.value === 'string') { tag.value = {text: tag.value}; } - if (tag.value.descriptor === 'iTunPGAP') { - this.setGenericTag(tagType, {id: 'gapless', value: tag.value.text === '1'}); + if ((tag.value as IComment).descriptor === 'iTunPGAP') { + this.setGenericTag(tagType, {id: 'gapless', value: (tag.value as IComment).text === '1'}); } break; @@ -303,14 +306,14 @@ export class MetadataCollector implements INativeMetadataCollector { } return picture; } - this.addWarning(`Empty picture tag found`); + this.addWarning("Empty picture tag found"); return null; } /** * Convert native tag to common tags */ - private async toCommon(tagType: TagType, tagId: string, value: any): Promise { + private async toCommon(tagType: TagType, tagId: string, value: AnyTagValue): Promise { const tag = {id: tagId, value}; @@ -361,7 +364,7 @@ export class MetadataCollector implements INativeMetadataCollector { export function joinArtists(artists: string[]): string { if (artists.length > 2) { - return artists.slice(0, artists.length - 1).join(', ') + ' & ' + artists[artists.length - 1]; + return `${artists.slice(0, artists.length - 1).join(', ')} & ${artists[artists.length - 1]}`; } return artists.join(' & '); } diff --git a/lib/common/RandomFileReader.ts b/lib/common/RandomFileReader.ts index 0849313d9..17c2b0162 100644 --- a/lib/common/RandomFileReader.ts +++ b/lib/common/RandomFileReader.ts @@ -1,6 +1,6 @@ -import * as fs from 'fs'; +import * as fs from 'node:fs'; -import { IRandomReader } from '../type.js'; +import type { IRandomReader } from '../type.js'; /** * Provides abstract file access via the IRandomRead interface diff --git a/lib/common/RandomUint8ArrayReader.ts b/lib/common/RandomUint8ArrayReader.ts index 8706a7d60..3341fe2a1 100644 --- a/lib/common/RandomUint8ArrayReader.ts +++ b/lib/common/RandomUint8ArrayReader.ts @@ -1,4 +1,4 @@ -import { IRandomReader } from '../type.js'; +import type { IRandomReader } from '../type.js'; /** * Provides abstract Uint8Array access via the IRandomRead interface diff --git a/lib/common/Util.ts b/lib/common/Util.ts index 79e2a7e99..331384095 100644 --- a/lib/common/Util.ts +++ b/lib/common/Util.ts @@ -1,5 +1,5 @@ import { StringType } from 'token-types'; -import { IRatio } from '../type.js'; +import type { IRatio } from '../type.js'; export type StringEncoding = 'ascii' // Use 'utf-8' or latin1 instead @@ -35,13 +35,12 @@ export function findZero(uint8Array: Uint8Array, start: number, end: number, enc i += 2; } return i; - } else { + } while (uint8Array[i] !== 0) { if (i >= end) return end; i++; } return i; - } } export function trimRightNull(x: string): string { @@ -69,7 +68,7 @@ export function decodeString(uint8Array: Uint8Array, encoding: StringEncoding): // https://github.com/leetreveil/musicmetadata/issues/84 if (uint8Array[0] === 0xFF && uint8Array[1] === 0xFE) { // little endian return decodeString(uint8Array.subarray(2), encoding); - } else if (encoding === 'utf-16le' && uint8Array[0] === 0xFE && uint8Array[1] === 0xFF) { + }if (encoding === 'utf-16le' && uint8Array[0] === 0xFE && uint8Array[1] === 0xFF) { // BOM, indicating big endian decoding if ((uint8Array.length & 1) !== 0) throw new Error('Expected even number of octets for 16-bit unicode string'); @@ -125,7 +124,7 @@ export function a2hex(str: string) { const arr = []; for (let i = 0, l = str.length; i < l; i++) { const hex = Number(str.charCodeAt(i)).toString(16); - arr.push(hex.length === 1 ? '0' + hex : hex); + arr.push(hex.length === 1 ? `0${hex}` : hex); } return arr.join(' '); } @@ -143,7 +142,7 @@ export function ratioToDb(ratio: number): number { * db Decibels */ export function dbToRatio(dB: number): number { - return Math.pow(10, dB / 10); + return 10 ** (dB / 10); } /** @@ -154,7 +153,7 @@ export function toRatio(value: string): IRatio { const ps = value.split(' ').map(p => p.trim().toLowerCase()); // @ts-ignore if (ps.length >= 1) { - const v = parseFloat(ps[0]); + const v = Number.parseFloat(ps[0]); return ps.length === 2 && ps[1] === 'db' ? { dB: v, ratio: dbToRatio(v) diff --git a/lib/core.ts b/lib/core.ts index 4ae803d5c..85c61cc1a 100644 --- a/lib/core.ts +++ b/lib/core.ts @@ -2,23 +2,20 @@ * Primary entry point, Node.js specific entry point is index.ts */ -import * as strtok3 from 'strtok3'; +import {type AnyWebByteStream, type IFileInfo, type ITokenizer, fromWebStream, fromBuffer} from 'strtok3'; -import { ParserFactory } from './ParserFactory.js'; +import { parseOnContentType } from './ParserFactory.js'; import { RandomUint8ArrayReader } from './common/RandomUint8ArrayReader.js'; import { APEv2Parser } from './apev2/APEv2Parser.js'; import { hasID3v1Header } from './id3v1/ID3v1Parser.js'; import { getLyricsHeaderLength } from './lyrics3/Lyrics3.js'; import type { IAudioMetadata, INativeTagDict, IOptions, IPicture, IPrivateOptions, IRandomReader, ITag } from './type.js'; -import type { ReadableStream as NodeReadableStream } from 'node:stream/web'; export { IFileInfo } from 'strtok3'; export { IAudioMetadata, IOptions, ITag, INativeTagDict, ICommonTagsResult, IFormat, IPicture, IRatio, IChapter, ILyricsTag, LyricsContentType, TimestampFormat } from './type.js'; -export type AnyWebStream = NodeReadableStream | ReadableStream; - /** * Parse Web API File * Requires Blob to be able to stream using a ReadableStreamBYOBReader, only available since Node.js ≥ 20 @@ -27,11 +24,11 @@ export type AnyWebStream = NodeReadableStream | ReadableStream; * @returns Metadata */ export async function parseBlob(blob: Blob, options: IOptions = {}): Promise { - const fileInfo: strtok3.IFileInfo = {mimeType: blob.type, size: blob.size}; + const fileInfo: IFileInfo = {mimeType: blob.type, size: blob.size}; if (blob instanceof File) { fileInfo.path = (blob as File).name; } - return parseWebStream(blob.stream(), fileInfo, options); + return parseWebStream(blob.stream() as AnyWebByteStream, fileInfo, options); } /** @@ -41,8 +38,8 @@ export async function parseBlob(blob: Blob, options: IOptions = {}): Promise, fileInfo?: strtok3.IFileInfo | string, options: IOptions = {}): Promise { - return parseFromTokenizer(strtok3.fromWebStream(webStream as any, {fileInfo: typeof fileInfo === 'string' ? {mimeType: fileInfo} : fileInfo}), options); +export function parseWebStream(webStream: AnyWebByteStream, fileInfo?: IFileInfo | string, options: IOptions = {}): Promise { + return parseFromTokenizer(fromWebStream(webStream, {fileInfo: typeof fileInfo === 'string' ? {mimeType: fileInfo} : fileInfo}), options); } /** @@ -53,12 +50,12 @@ export function parseWebStream(webStream: AnyWebStream, fileInfo?: s * @returns Metadata * Ref: https://github.com/Borewit/strtok3/blob/e6938c81ff685074d5eb3064a11c0b03ca934c1d/src/index.ts#L15 */ -export async function parseBuffer(uint8Array: Uint8Array, fileInfo?: strtok3.IFileInfo | string, options: IOptions = {}): Promise { +export async function parseBuffer(uint8Array: Uint8Array, fileInfo?: IFileInfo | string, options: IOptions = {}): Promise { const bufferReader = new RandomUint8ArrayReader(uint8Array); await scanAppendingHeaders(bufferReader, options); - const tokenizer = strtok3.fromBuffer(uint8Array, {fileInfo: typeof fileInfo === 'string' ? {mimeType: fileInfo} : fileInfo}); + const tokenizer = fromBuffer(uint8Array, {fileInfo: typeof fileInfo === 'string' ? {mimeType: fileInfo} : fileInfo}); return parseFromTokenizer(tokenizer, options); } @@ -68,8 +65,8 @@ export async function parseBuffer(uint8Array: Uint8Array, fileInfo?: strtok3.IFi * @param options - Parsing options * @returns Metadata */ -export function parseFromTokenizer(tokenizer: strtok3.ITokenizer, options?: IOptions): Promise { - return ParserFactory.parseOnContentType(tokenizer, options); +export function parseFromTokenizer(tokenizer: ITokenizer, options?: IOptions): Promise { + return parseOnContentType(tokenizer, options); } /** @@ -78,10 +75,15 @@ export function parseFromTokenizer(tokenizer: strtok3.ITokenizer, options?: IOpt * @returns tags indexed by id */ export function orderTags(nativeTags: ITag[]): INativeTagDict { - const tags = {}; - for (const tag of nativeTags) { - (tags[tag.id] = (tags[tag.id] || [])).push(tag.value); + const tags: INativeTagDict = {}; + + for (const { id, value } of nativeTags) { + if (!tags[id]) { + tags[id] = []; + } + tags[id].push(value); } + return tags; } diff --git a/lib/dsdiff/DsdiffParser.ts b/lib/dsdiff/DsdiffParser.ts index 523b8958c..0cbfd15cb 100644 --- a/lib/dsdiff/DsdiffParser.ts +++ b/lib/dsdiff/DsdiffParser.ts @@ -6,7 +6,7 @@ import { FourCcToken } from '../common/FourCC.js'; import { BasicParser } from '../common/BasicParser.js'; import { ID3v2Parser } from '../id3v2/ID3v2Parser.js'; -import { ChunkHeader64, IChunkHeader64 } from './DsdiffToken.js'; +import { ChunkHeader64, type IChunkHeader64 } from './DsdiffToken.js'; const debug = initDebug('music-metadata:parser:aiff'); @@ -32,7 +32,7 @@ export class DsdiffParser extends BasicParser { return this.readFmt8Chunks(header.chunkSize - BigInt(FourCcToken.len)); default: - throw Error(`Unsupported DSDIFF type: ${type}`); + throw new Error(`Unsupported DSDIFF type: ${type}`); } } @@ -53,32 +53,35 @@ export class DsdiffParser extends BasicParser { const p0 = this.tokenizer.position; switch (header.chunkID.trim()) { - case 'FVER': // 3.1 FORMAT VERSION CHUNK + case 'FVER': { // 3.1 FORMAT VERSION CHUNK const version = await this.tokenizer.readToken(Token.UINT32_LE); debug(`DSDIFF version=${version}`); break; + } - case 'PROP': // 3.2 PROPERTY CHUNK + case 'PROP': { // 3.2 PROPERTY CHUNK const propType = await this.tokenizer.readToken(FourCcToken); if (propType !== 'SND ') throw new Error('Unexpected PROP-chunk ID'); await this.handleSoundPropertyChunks(header.chunkSize - BigInt(FourCcToken.len)); break; + } - case 'ID3': // Unofficial ID3 tag support + case 'ID3': { // Unofficial ID3 tag support const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(Number(header.chunkSize))); const rst = strtok3.fromBuffer(id3_data); await new ID3v2Parser().parse(this.metadata, rst, this.options); break; - - default: - debug(`Ignore chunk[ID=${header.chunkID}, size=${header.chunkSize}]`); - break; + } case 'DSD': this.metadata.setFormat('numberOfSamples', Number(header.chunkSize * BigInt(8) / BigInt(this.metadata.format.numberOfChannels))); this.metadata.setFormat('duration', this.metadata.format.numberOfSamples / this.metadata.format.sampleRate); break; + default: + debug(`Ignore chunk[ID=${header.chunkID}, size=${header.chunkSize}]`); + break; + } const remaining = header.chunkSize - BigInt(this.tokenizer.position - p0); if (remaining > 0) { @@ -95,18 +98,20 @@ export class DsdiffParser extends BasicParser { const p0 = this.tokenizer.position; switch (sndPropHeader.chunkID.trim()) { - case 'FS': // 3.2.1 Sample Rate Chunk + case 'FS': { // 3.2.1 Sample Rate Chunk const sampleRate = await this.tokenizer.readToken(Token.UINT32_BE); this.metadata.setFormat('sampleRate', sampleRate); break; + } - case 'CHNL': // 3.2.2 Channels Chunk + case 'CHNL': { // 3.2.2 Channels Chunk const numChannels = await this.tokenizer.readToken(Token.UINT16_BE); this.metadata.setFormat('numberOfChannels', numChannels); await this.handleChannelChunks(sndPropHeader.chunkSize - BigInt(Token.UINT16_BE.len)); break; + } - case 'CMPR': // 3.2.3 Compression Type Chunk + case 'CMPR': { // 3.2.3 Compression Type Chunk const compressionIdCode = (await this.tokenizer.readToken(FourCcToken)).trim(); const count = await this.tokenizer.readToken(Token.UINT8); const compressionName = await this.tokenizer.readToken(new Token.StringType(count, 'ascii')); @@ -116,21 +121,22 @@ export class DsdiffParser extends BasicParser { } this.metadata.setFormat('codec', `${compressionIdCode} (${compressionName})`); break; + } - case 'ABSS': // 3.2.4 Absolute Start Time Chunk + case 'ABSS': { // 3.2.4 Absolute Start Time Chunk const hours = await this.tokenizer.readToken(Token.UINT16_BE); const minutes = await this.tokenizer.readToken(Token.UINT8); const seconds = await this.tokenizer.readToken(Token.UINT8); const samples = await this.tokenizer.readToken(Token.UINT32_BE); debug(`ABSS ${hours}:${minutes}:${seconds}.${samples}`); break; + } - case 'LSCO': // 3.2.5 Loudspeaker Configuration Chunk + case 'LSCO': { // 3.2.5 Loudspeaker Configuration Chunk const lsConfig = await this.tokenizer.readToken(Token.UINT16_BE); debug(`LSCO lsConfig=${lsConfig}`); break; - - case 'COMT': + } default: debug(`Unknown sound-property-chunk[ID=${sndPropHeader.chunkID}, size=${sndPropHeader.chunkSize}]`); await this.tokenizer.ignore(Number(sndPropHeader.chunkSize)); diff --git a/lib/dsdiff/DsdiffToken.ts b/lib/dsdiff/DsdiffToken.ts index 52b42cb4f..ed0af2b37 100644 --- a/lib/dsdiff/DsdiffToken.ts +++ b/lib/dsdiff/DsdiffToken.ts @@ -2,7 +2,7 @@ import * as Token from 'token-types'; import type { IGetToken } from 'strtok3'; import { FourCcToken } from '../common/FourCC.js'; -import { IChunkHeader64 } from '../iff/index.js'; +import type { IChunkHeader64 } from '../iff/index.js'; export { IChunkHeader64 } from '../iff/index.js'; /** diff --git a/lib/dsf/DsfParser.ts b/lib/dsf/DsfParser.ts index 24fb35b0b..97e1348fe 100644 --- a/lib/dsf/DsfParser.ts +++ b/lib/dsf/DsfParser.ts @@ -1,7 +1,7 @@ import initDebug from 'debug'; import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js'; -import { ChunkHeader, DsdChunk, FormatChunk, IChunkHeader, IDsdChunk, IFormatChunk } from './DsfChunk.js'; +import { ChunkHeader, DsdChunk, FormatChunk, type IChunkHeader, type IDsdChunk, type IFormatChunk } from './DsfChunk.js'; import { ID3v2Parser } from "../id3v2/ID3v2Parser.js"; const debug = initDebug('music-metadata:parser:DSF'); @@ -21,7 +21,7 @@ export class DsfParser extends AbstractID3Parser { this.metadata.setFormat('lossless', true); const dsdChunk = await this.tokenizer.readToken(DsdChunk); if (dsdChunk.metadataPointer === BigInt(0)) { - debug(`No ID3v2 tag present`); + debug("No ID3v2 tag present"); } else { debug(`expect ID3v2 at offset=${dsdChunk.metadataPointer}`); await this.parseChunks(dsdChunk.fileSize - chunkHeader.size); @@ -36,7 +36,7 @@ export class DsfParser extends AbstractID3Parser { const chunkHeader = await this.tokenizer.readToken(ChunkHeader); debug(`Parsing chunk name=${chunkHeader.id} size=${chunkHeader.size}`); switch (chunkHeader.id) { - case 'fmt ': + case 'fmt ': { const formatChunk = await this.tokenizer.readToken(FormatChunk); this.metadata.setFormat('numberOfChannels', formatChunk.channelNum); this.metadata.setFormat('sampleRate', formatChunk.samplingFrequency); @@ -46,6 +46,7 @@ export class DsfParser extends AbstractID3Parser { const bitrate = formatChunk.bitsPerSample * formatChunk.samplingFrequency * formatChunk.channelNum; this.metadata.setFormat('bitrate', bitrate); return; // We got what we want, stop further processing of chunks + } default: this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); break; diff --git a/lib/flac/FlacParser.ts b/lib/flac/FlacParser.ts index 63aa71207..8c7c61060 100644 --- a/lib/flac/FlacParser.ts +++ b/lib/flac/FlacParser.ts @@ -3,13 +3,13 @@ import initDebug from 'debug'; import type { ITokenizer, IGetToken } from 'strtok3'; import * as util from '../common/Util.js'; -import { IVorbisPicture, VorbisPictureToken } from '../ogg/vorbis/Vorbis.js'; +import { type IVorbisPicture, VorbisPictureToken } from '../ogg/vorbis/Vorbis.js'; import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js'; import { FourCcToken } from '../common/FourCC.js'; import { VorbisParser } from '../ogg/vorbis/VorbisParser.js'; -import { INativeMetadataCollector } from '../common/MetadataCollector.js'; -import { IOptions } from '../type.js'; -import { ITokenParser } from '../ParserFactory.js'; +import type { INativeMetadataCollector } from '../common/MetadataCollector.js'; +import type { IOptions } from '../type.js'; +import type { ITokenParser } from '../ParserFactory.js'; import { VorbisDecoder } from '../ogg/vorbis/VorbisDecoder.js'; const debug = initDebug('music-metadata:parser:FLAC'); @@ -32,7 +32,7 @@ export class FlacParser extends AbstractID3Parser { private vorbisParser: VorbisParser; - private padding: number = 0; + private padding = 0; /** * Initialize parser with output (metadata), input (tokenizer) & parsing options (options). @@ -56,7 +56,7 @@ export class FlacParser extends AbstractID3Parser { let blockHeader: IBlockHeader; do { // Read block header - blockHeader = await this.tokenizer.readToken(Metadata.BlockHeader); + blockHeader = await this.tokenizer.readToken(BlockHeader); // Parse block data await this.parseDataBlock(blockHeader); } @@ -88,7 +88,7 @@ export class FlacParser extends AbstractID3Parser { await this.parsePicture(blockHeader.length); return; default: - this.metadata.addWarning('Unknown block type: ' + blockHeader.type); + this.metadata.addWarning(`Unknown block type: ${blockHeader.type}`); } // Ignore data block return this.tokenizer.ignore(blockHeader.length).then(); @@ -99,10 +99,10 @@ export class FlacParser extends AbstractID3Parser { */ private async parseBlockStreamInfo(dataLen: number): Promise { - if (dataLen !== Metadata.BlockStreamInfo.len) + if (dataLen !== BlockStreamInfo.len) throw new Error('Unexpected block-stream-info length'); - const streamInfo = await this.tokenizer.readToken(Metadata.BlockStreamInfo); + const streamInfo = await this.tokenizer.readToken(BlockStreamInfo); this.metadata.setFormat('container', 'FLAC'); this.metadata.setFormat('codec', 'FLAC'); this.metadata.setFormat('lossless', true); @@ -133,10 +133,9 @@ export class FlacParser extends AbstractID3Parser { private async parsePicture(dataLen: number) { if (this.options.skipCovers) { return this.tokenizer.ignore(dataLen); - } else { + } const picture = await this.tokenizer.readToken(new VorbisPictureToken(dataLen)); this.vorbisParser.addTag('METADATA_BLOCK_PICTURE', picture); - } } } @@ -186,57 +185,54 @@ interface IBlockStreamInfo { fileMD5: Uint8Array; } -class Metadata { +const BlockHeader: IGetToken = { + len: 4, - public static BlockHeader: IGetToken = { - len: 4, - - get: (buf: Uint8Array, off: number): IBlockHeader => { - return { - lastBlock: util.getBit(buf, off, 7), - type: util.getBitAllignedNumber(buf, off, 1, 7), - length: UINT24_BE.get(buf, off + 1) - }; - } - }; + get: (buf: Uint8Array, off: number): IBlockHeader => { + return { + lastBlock: util.getBit(buf, off, 7), + type: util.getBitAllignedNumber(buf, off, 1, 7), + length: UINT24_BE.get(buf, off + 1) + }; + } +}; - /** - * METADATA_BLOCK_DATA - * Ref: https://xiph.org/flac/format.html#metadata_block_streaminfo - */ - public static BlockStreamInfo: IGetToken = { - len: 34, - - get: (buf: Uint8Array, off: number): IBlockStreamInfo => { - return { - // The minimum block size (in samples) used in the stream. - minimumBlockSize: UINT16_BE.get(buf, off), - // The maximum block size (in samples) used in the stream. - // (Minimum blocksize == maximum blocksize) implies a fixed-blocksize stream. - maximumBlockSize: UINT16_BE.get(buf, off + 2) / 1000, - // The minimum frame size (in bytes) used in the stream. - // May be 0 to imply the value is not known. - minimumFrameSize: UINT24_BE.get(buf, off + 4), - // The maximum frame size (in bytes) used in the stream. - // May be 0 to imply the value is not known. - maximumFrameSize: UINT24_BE.get(buf, off + 7), - // Sample rate in Hz. Though 20 bits are available, - // the maximum sample rate is limited by the structure of frame headers to 655350Hz. - // Also, a value of 0 is invalid. - sampleRate: UINT24_BE.get(buf, off + 10) >> 4, - // probably slower: sampleRate: common.getBitAllignedNumber(buf, off + 10, 0, 20), - // (number of channels)-1. FLAC supports from 1 to 8 channels - channels: util.getBitAllignedNumber(buf, off + 12, 4, 3) + 1, - // bits per sample)-1. - // FLAC supports from 4 to 32 bits per sample. Currently the reference encoder and decoders only support up to 24 bits per sample. - bitsPerSample: util.getBitAllignedNumber(buf, off + 12, 7, 5) + 1, - // Total samples in stream. - // 'Samples' means inter-channel sample, i.e. one second of 44.1Khz audio will have 44100 samples regardless of the number of channels. - // A value of zero here means the number of total samples is unknown. - totalSamples: util.getBitAllignedNumber(buf, off + 13, 4, 36), - // the MD5 hash of the file (see notes for usage... it's a littly tricky) - fileMD5: new Uint8ArrayType(16).get(buf, off + 18) - }; - } - }; -} +/** + * METADATA_BLOCK_DATA + * Ref: https://xiph.org/flac/format.html#metadata_block_streaminfo + */ +const BlockStreamInfo: IGetToken = { + len: 34, + + get: (buf: Uint8Array, off: number): IBlockStreamInfo => { + return { + // The minimum block size (in samples) used in the stream. + minimumBlockSize: UINT16_BE.get(buf, off), + // The maximum block size (in samples) used in the stream. + // (Minimum blocksize == maximum blocksize) implies a fixed-blocksize stream. + maximumBlockSize: UINT16_BE.get(buf, off + 2) / 1000, + // The minimum frame size (in bytes) used in the stream. + // May be 0 to imply the value is not known. + minimumFrameSize: UINT24_BE.get(buf, off + 4), + // The maximum frame size (in bytes) used in the stream. + // May be 0 to imply the value is not known. + maximumFrameSize: UINT24_BE.get(buf, off + 7), + // Sample rate in Hz. Though 20 bits are available, + // the maximum sample rate is limited by the structure of frame headers to 655350Hz. + // Also, a value of 0 is invalid. + sampleRate: UINT24_BE.get(buf, off + 10) >> 4, + // probably slower: sampleRate: common.getBitAllignedNumber(buf, off + 10, 0, 20), + // (number of channels)-1. FLAC supports from 1 to 8 channels + channels: util.getBitAllignedNumber(buf, off + 12, 4, 3) + 1, + // bits per sample)-1. + // FLAC supports from 4 to 32 bits per sample. Currently the reference encoder and decoders only support up to 24 bits per sample. + bitsPerSample: util.getBitAllignedNumber(buf, off + 12, 7, 5) + 1, + // Total samples in stream. + // 'Samples' means inter-channel sample, i.e. one second of 44.1Khz audio will have 44100 samples regardless of the number of channels. + // A value of zero here means the number of total samples is unknown. + totalSamples: util.getBitAllignedNumber(buf, off + 13, 4, 36), + // the MD5 hash of the file (see notes for usage... it's a littly tricky) + fileMD5: new Uint8ArrayType(16).get(buf, off + 18) + }; + } +}; diff --git a/lib/id3v1/ID3v1Parser.ts b/lib/id3v1/ID3v1Parser.ts index 26c8c3340..c96a9afca 100644 --- a/lib/id3v1/ID3v1Parser.ts +++ b/lib/id3v1/ID3v1Parser.ts @@ -6,7 +6,7 @@ import * as util from '../common/Util.js'; import type { IGetToken } from 'strtok3'; import { BasicParser } from '../common/BasicParser.js'; import { APEv2Parser } from '../apev2/APEv2Parser.js'; -import { IRandomReader } from '../type.js'; +import type { AnyTagValue, IRandomReader } from '../type.js'; const debug = initDebug('music-metadata:parser:ID3v1'); @@ -147,7 +147,7 @@ export class ID3v1Parser extends BasicParser { } } - private async addTag(id: string, value: any): Promise { + private async addTag(id: string, value: AnyTagValue): Promise { await this.metadata.addTag('ID3v1', id, value); } diff --git a/lib/id3v1/ID3v1TagMap.ts b/lib/id3v1/ID3v1TagMap.ts index 803ab0797..881324916 100644 --- a/lib/id3v1/ID3v1TagMap.ts +++ b/lib/id3v1/ID3v1TagMap.ts @@ -1,4 +1,4 @@ -import { INativeTagMap } from '../common/GenericTagTypes.js'; +import type { INativeTagMap } from '../common/GenericTagTypes.js'; import { CommonTagMapper } from '../common/GenericTagMapper.js'; /** diff --git a/lib/id3v2/AbstractID3Parser.ts b/lib/id3v2/AbstractID3Parser.ts index 24ddc1ce6..be4a1d687 100644 --- a/lib/id3v2/AbstractID3Parser.ts +++ b/lib/id3v2/AbstractID3Parser.ts @@ -1,4 +1,4 @@ -import { EndOfStreamError, ITokenizer } from 'strtok3'; +import { EndOfStreamError, type ITokenizer } from 'strtok3'; import initDebug from 'debug'; import { ID3v2Header } from './ID3v2Token.js'; @@ -24,7 +24,7 @@ export abstract class AbstractID3Parser extends BasicParser { await this.parseID3v2(); } catch (err) { if (err instanceof EndOfStreamError) { - debug(`End-of-stream`); + debug("End-of-stream"); } else { throw err; } diff --git a/lib/id3v2/FrameParser.ts b/lib/id3v2/FrameParser.ts index d2cca54ed..52f2948f5 100644 --- a/lib/id3v2/FrameParser.ts +++ b/lib/id3v2/FrameParser.ts @@ -2,20 +2,14 @@ import initDebug from 'debug'; import * as Token from 'token-types'; import * as util from '../common/Util.js'; -import { AttachedPictureType, ID3v2MajorVersion, TextEncodingToken, SyncTextHeader, TextHeader, ITextEncoding } from './ID3v2Token.js'; +import { AttachedPictureType, type ID3v2MajorVersion, type ITextEncoding, SyncTextHeader, TextEncodingToken, TextHeader } from './ID3v2Token.js'; import { Genres } from '../id3v1/ID3v1Parser.js'; -import { IWarningCollector } from '../common/MetadataCollector.js'; -import { IComment, ILyricsTag } from '../type.js'; +import type { IWarningCollector } from '../common/MetadataCollector.js'; +import type { IComment, ILyricsTag } from '../type.js'; const debug = initDebug('music-metadata:id3v2:frame-parser'); -interface IOut { - language?: string, - description?: string, - text?: string, -} - interface IPicture { type?: string, description?: string; @@ -23,13 +17,44 @@ interface IPicture { data?: Uint8Array; } +interface ICustomTag { + owner_identifier: string; +} + +export interface ICustomDataTag extends ICustomTag { + data: Uint8Array; +} + +export interface IIdentifierTag extends ICustomTag { + identifier: Uint8Array; +} + +export interface ITextTag { + description: string; + text: string[]; +} + +export interface IPopularimeter { + email: string; + rating: number; + counter: number; +} + + +export interface IGeneralEncapsulatedObject { + type: string; + filename: string; + description: string; + data: Uint8Array; +} + const defaultEnc = 'latin1'; // latin1 == iso-8859-1; export function parseGenre(origVal: string): string[] { // match everything inside parentheses const genres = []; let code: string; - let word: string = ''; + let word = ''; for (const c of origVal) { if (typeof code === 'string') { if (c === '(' && code === '') { @@ -89,7 +114,7 @@ export class FrameParser { const {encoding, bom} = TextEncodingToken.get(uint8Array, 0); const length = uint8Array.length; let offset = 0; - let output: any = []; // ToDo + let output: unknown = []; // ToDo const nullTerminatorLength = FrameParser.getNullTerminatorLength(encoding); let fzero: number; @@ -101,8 +126,8 @@ export class FrameParser { case 'MVIN': case 'MVNM': case 'PCS': - case 'PCST': - let text; + case 'PCST': { + let text: string; try { text = util.decodeString(uint8Array.slice(1), encoding).replace(/\x00+$/, ''); } catch (error) { @@ -112,8 +137,7 @@ export class FrameParser { case 'TMCL': // Musician credits list case 'TIPL': // Involved people list case 'IPLS': // Involved people list - output = this.splitValue(type, text); - output = FrameParser.functionList(output); + output = FrameParser.functionList(this.splitValue(type, text)); break; case 'TRK': case 'TRCK': @@ -143,14 +167,17 @@ export class FrameParser { output = this.major >= 4 ? this.splitValue(type, text) : [text]; } break; + } - case 'TXXX': - output = FrameParser.readIdentifierAndData(uint8Array, offset + 1, length, encoding); - output = { - description: output.id, - text: this.splitValue(type, util.decodeString(output.data, encoding).replace(/\x00+$/, '')) + case 'TXXX': { + const idAndData = FrameParser.readIdentifierAndData(uint8Array, offset + 1, length, encoding); + const textTag = { + description: idAndData.id, + text: this.splitValue(type, util.decodeString(idAndData.data, encoding).replace(/\x00+$/, '')) }; + output = textTag; break; + } case 'PIC': case 'APIC': @@ -172,7 +199,7 @@ export class FrameParser { break; default: - throw new Error('Warning: unexpected major versionIndex: ' + this.major); + throw new Error(`Warning: unexpected major versionIndex: ${this.major}`); } pic.format = FrameParser.fixPictureMimeType(pic.format); @@ -194,7 +221,7 @@ export class FrameParser { output = Token.UINT32_BE.get(uint8Array, 0); break; - case 'SYLT': + case 'SYLT': { const syltHeader = SyncTextHeader.get(uint8Array, 0); offset += SyncTextHeader.len; @@ -226,11 +253,12 @@ export class FrameParser { } output = result; break; + } case 'ULT': case 'USLT': case 'COM': - case 'COMM': + case 'COMM': { const textHeader = TextHeader.get(uint8Array, offset); offset += TextHeader.len; @@ -248,18 +276,21 @@ export class FrameParser { output = comment; break; + } - case 'UFID': - output = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc); - output = {owner_identifier: output.id, identifier: output.data}; + case 'UFID': { + const ufid = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc); + output = {owner_identifier: ufid.id, identifier: ufid.data} as IIdentifierTag; break; + } - case 'PRIV': // private frame - output = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc); - output = {owner_identifier: output.id, data: output.data}; + case 'PRIV': { // private frame + const priv = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc); + output = {owner_identifier: priv.id, data: priv.data} as ICustomDataTag; break; + } - case 'POPM': // Popularimeter + case 'POPM': { // Popularimeter fzero = util.findZero(uint8Array, offset, length, defaultEnc); const email = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc); offset = fzero + 1; @@ -270,6 +301,7 @@ export class FrameParser { counter: dataLen >= 5 ? Token.UINT32_BE.get(uint8Array, offset + 1) : undefined }; break; + } case 'GEOB': { // General encapsulated object fzero = util.findZero(uint8Array, offset + 1, length, encoding); @@ -280,12 +312,14 @@ export class FrameParser { offset = fzero + 1; fzero = util.findZero(uint8Array, offset, length - offset, encoding); const description = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc); - output = { + + const geob: IGeneralEncapsulatedObject = { type: mimeType, filename, description, data: uint8Array.slice(offset + 1, length) }; + output = geob; break; } @@ -323,17 +357,25 @@ export class FrameParser { } default: - debug('Warning: unsupported id3v2-tag-type: ' + type); + debug(`Warning: unsupported id3v2-tag-type: ${type}`); break; } return output; } - protected static readNullTerminatedString(uint8Array: Uint8Array, encoding: ITextEncoding): {text: string, len: number} { - let offset = encoding.bom ? 2 : 0; - const txt = uint8Array.slice(offset, offset = util.findZero(uint8Array, offset, uint8Array.length, encoding.encoding)); - offset += encoding.encoding === 'utf-16le' ? 2 : 1; + protected static readNullTerminatedString(uint8Array: Uint8Array, encoding: ITextEncoding): { text: string, len: number } { + let offset = encoding.bom ? 2: 0; + + const zeroIndex = util.findZero(uint8Array, offset, uint8Array.length, encoding.encoding); + const txt = uint8Array.slice(offset, zeroIndex); + + if (encoding.encoding === 'utf-16le') { + offset = zeroIndex + 2; + } else { + offset = zeroIndex + 1; + } + return { text: util.decodeString(txt, encoding.encoding), len: offset @@ -359,7 +401,7 @@ export class FrameParser { const res: { [index: string]: string[] } = {}; for (let i = 0; i + 1 < entries.length; i += 2) { const names: string[] = entries[i + 1].split(','); - res[entries[i]] = res.hasOwnProperty(entries[i]) ? res[entries[i]].concat(names) : names; + res[entries[i]] = res[entries[i]] ? res[entries[i]].concat(names) : names; } return res; } diff --git a/lib/id3v2/ID3v22TagMapper.ts b/lib/id3v2/ID3v22TagMapper.ts index bc9573cfa..ed5cb9e68 100644 --- a/lib/id3v2/ID3v22TagMapper.ts +++ b/lib/id3v2/ID3v22TagMapper.ts @@ -1,4 +1,4 @@ -import {INativeTagMap} from '../common/GenericTagTypes.js'; +import type {INativeTagMap} from '../common/GenericTagTypes.js'; import {CaseInsensitiveTagMap} from '../common/CaseInsensitiveTagMap.js'; /** diff --git a/lib/id3v2/ID3v24TagMapper.ts b/lib/id3v2/ID3v24TagMapper.ts index 631dd18f7..4fbc4d037 100644 --- a/lib/id3v2/ID3v24TagMapper.ts +++ b/lib/id3v2/ID3v24TagMapper.ts @@ -6,6 +6,7 @@ import { decodeString } from '../common/Util.js'; import type { INativeTagMap } from '../common/GenericTagTypes.js'; import type { INativeMetadataCollector } from '../common/MetadataCollector.js'; import type { IRating, ITag } from '../type.js'; +import type { ICustomDataTag, IIdentifierTag, IPopularimeter } from './FrameParser.js'; /** * ID3v2.3/ID3v2.4 tag mappings @@ -156,7 +157,7 @@ const id3v24TagMap: INativeTagMap = { export class ID3v24TagMapper extends CaseInsensitiveTagMap { - public static toRating(popm: any): IRating { + public static toRating(popm: IPopularimeter): IRating { return { source: popm.email, @@ -177,31 +178,36 @@ export class ID3v24TagMapper extends CaseInsensitiveTagMap { switch (tag.id) { - case 'UFID': // decode MusicBrainz Recording Id - if (tag.value.owner_identifier === 'http://musicbrainz.org') { - tag.id += ':' + tag.value.owner_identifier; - tag.value = decodeString(tag.value.identifier, 'latin1'); // latin1 == iso-8859-1 + case 'UFID': { + // decode MusicBrainz Recording Id + const idTag= tag.value as IIdentifierTag; + if (idTag.owner_identifier === 'http://musicbrainz.org') { + tag.id += `:${idTag.owner_identifier}`; + tag.value = decodeString(idTag.identifier, 'latin1'); // latin1 == iso-8859-1 } + } break; - case 'PRIV': - switch (tag.value.owner_identifier) { + case 'PRIV': { + const customTag = tag.value as ICustomDataTag; + switch(customTag.owner_identifier) { // decode Windows Media Player case 'AverageLevel': case 'PeakValue': - tag.id += ':' + tag.value.owner_identifier; - tag.value = tag.value.data.length === 4 ? UINT32_LE.get(tag.value.data, 0) : null; + tag.id += `:${customTag.owner_identifier}`; + tag.value = customTag.data.length === 4 ? UINT32_LE.get(customTag.data, 0) : null; if (tag.value === null) { - warnings.addWarning(`Failed to parse PRIV:PeakValue`); + warnings.addWarning('Failed to parse PRIV:PeakValue'); } break; default: - warnings.addWarning(`Unknown PRIV owner-identifier: ${tag.value.owner_identifier}`); + warnings.addWarning(`Unknown PRIV owner-identifier: ${customTag.data}`); } + } break; case 'POPM': - tag.value = ID3v24TagMapper.toRating(tag.value); + tag.value = ID3v24TagMapper.toRating(tag.value as IPopularimeter); break; default: diff --git a/lib/id3v2/ID3v2Parser.ts b/lib/id3v2/ID3v2Parser.ts index d1fc1b658..a0c064114 100644 --- a/lib/id3v2/ID3v2Parser.ts +++ b/lib/id3v2/ID3v2Parser.ts @@ -2,12 +2,12 @@ import type { ITokenizer } from 'strtok3'; import * as Token from 'token-types'; import * as util from '../common/Util.js'; -import { TagType } from '../common/GenericTagTypes.js'; -import { FrameParser } from './FrameParser.js'; -import { ExtendedHeader, ID3v2Header, ID3v2MajorVersion, IID3v2header, UINT32SYNCSAFE } from './ID3v2Token.js'; +import type { TagType } from '../common/GenericTagTypes.js'; +import { FrameParser, type ITextTag } from './FrameParser.js'; +import { ExtendedHeader, ID3v2Header, type ID3v2MajorVersion, type IID3v2header, UINT32SYNCSAFE } from './ID3v2Token.js'; -import { ITag, IOptions } from '../type.js'; -import { INativeMetadataCollector, IWarningCollector } from '../common/MetadataCollector.js'; +import type { ITag, IOptions, AnyTagValue } from '../type.js'; +import type { INativeMetadataCollector, IWarningCollector } from '../common/MetadataCollector.js'; interface IFrameFlags { status: { @@ -94,7 +94,7 @@ export class ID3v2Parser { } return frameParser.readData(uint8Array, frameHeader.id, includeCovers); default: - throw new Error('Unexpected majorVer: ' + majorVer); + throw new Error(`Unexpected majorVer: ${majorVer}`); } } @@ -105,7 +105,7 @@ export class ID3v2Parser { * @returns string e.g. COM:iTunPGAP */ private static makeDescriptionTagName(tag: string, description: string): string { - return tag + (description ? ':' + description : ''); + return tag + (description ? `:${description}` : ''); } private tokenizer: ITokenizer; @@ -129,7 +129,7 @@ export class ID3v2Parser { this.id3Header = id3Header; - this.headerType = ('ID3v2.' + id3Header.version.major) as TagType; + this.headerType = (`ID3v2.${id3Header.version.major}`) as TagType; return id3Header.flags.isExtendedHeader ? this.parseExtendedHeader() : this.parseId3Data(id3Header.size); } @@ -151,7 +151,7 @@ export class ID3v2Parser { switch (tag.id) { case 'TXXX': if (tag.value) { - await this.handleTag(tag, tag.value.text, () => tag.value.description); + await this.handleTag(tag, (tag.value as ITextTag).text, () => (tag.value as ITextTag).description); } break; default: @@ -160,19 +160,19 @@ export class ID3v2Parser { } } - private async handleTag(tag: ITag, values: any[], descriptor: (x: any) => string, resolveValue: (x: any) => string = value => value): Promise { + private async handleTag(tag: ITag, values: string[], descriptor: (x: AnyTagValue) => string, resolveValue: (x: string) => string = value => value): Promise { await Promise.all(values.map(value => this.addTag(ID3v2Parser.makeDescriptionTagName(tag.id, descriptor(value)), resolveValue(value)) )); } - private async addTag(id: string, value: any): Promise { + private async addTag(id: string, value: AnyTagValue): Promise { await this.metadata.addTag(this.headerType, id, value); } private parseMetadata(data: Uint8Array): ITag[] { let offset = 0; - const tags: { id: string, value: any }[] = []; + const tags: { id: string, value: AnyTagValue }[] = []; while (true) { if (offset === data.length) break; @@ -184,10 +184,12 @@ export class ID3v2Parser { break; } - const frameHeaderBytes = data.slice(offset, offset += frameHeaderLength); + const frameHeaderBytes = data.slice(offset, offset + frameHeaderLength); + offset += frameHeaderLength; const frameHeader = this.readFrameHeader(frameHeaderBytes, this.id3Header.version.major); - const frameDataBytes = data.slice(offset, offset += frameHeader.length); + const frameDataBytes = data.slice(offset, offset + frameHeader.length); + offset += frameHeader.length; const values = ID3v2Parser.readFrameData(frameDataBytes, frameHeader, this.id3Header.version.major, !this.options.skipCovers, this.metadata); if (values) { tags.push({id: frameHeader.id, value: values}); @@ -223,7 +225,7 @@ export class ID3v2Parser { break; default: - throw new Error('Unexpected majorVer: ' + majorVer); + throw new Error(`Unexpected majorVer: ${majorVer}`); } return header; } diff --git a/lib/id3v2/ID3v2Token.ts b/lib/id3v2/ID3v2Token.ts index f3f407b0e..315234ad8 100644 --- a/lib/id3v2/ID3v2Token.ts +++ b/lib/id3v2/ID3v2Token.ts @@ -8,27 +8,27 @@ import * as util from '../common/Util.js'; * Ref: http://id3.org/id3v2.3.0#Attached_picture */ export enum AttachedPictureType { - 'Other', - "32x32 pixels 'file icon' (PNG only)", - 'Other file icon', - 'Cover (front)', - 'Cover (back)', - 'Leaflet page', - 'Media (e.g. label side of CD)', - 'Lead artist/lead performer/soloist', - 'Artist/performer', - 'Conductor', - 'Band/Orchestra', - 'Composer', - 'Lyricist/text writer', - 'Recording Location', - 'During recording', - 'During performance', - 'Movie/video screen capture', - 'A bright coloured fish', - 'Illustration', - 'Band/artist logotype', - 'Publisher/Studio logotype' + 'Other' = 0, + "32x32 pixels 'file icon' (PNG only)" = 1, + 'Other file icon' = 2, + 'Cover (front)' = 3, + 'Cover (back)' = 4, + 'Leaflet page' = 5, + 'Media (e.g. label side of CD)' = 6, + 'Lead artist/lead performer/soloist' = 7, + 'Artist/performer' = 8, + 'Conductor' = 9, + 'Band/Orchestra' = 10, + 'Composer' = 11, + 'Lyricist/text writer' = 12, + 'Recording Location' = 13, + 'During recording' = 14, + 'During performance' = 15, + 'Movie/video screen capture' = 16, + 'A bright coloured fish' = 17, + 'Illustration' = 18, + 'Band/artist logotype' = 19, + 'Publisher/Studio logotype' = 20 } export type ID3v2MajorVersion = 2 | 3 | 4; @@ -57,7 +57,7 @@ export enum LyricsContentType { } export enum TimestampFormat { - notSynchronized0, + notSynchronized0 = 0, mpegFrameNumber = 1, milliseconds = 2 } diff --git a/lib/index.ts b/lib/index.ts index 49b56d43a..c8b211f0f 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -2,13 +2,13 @@ * Node.js specific entry point. */ -import * as Stream from 'stream'; -import * as strtok3 from 'strtok3'; +import type { Readable } from 'node:stream'; +import { fromFile, fromStream, type IFileInfo } from 'strtok3'; import initDebug from 'debug'; import { parseFromTokenizer, scanAppendingHeaders } from './core.js'; -import { ParserFactory } from './ParserFactory.js'; -import { IAudioMetadata, IOptions } from './type.js'; +import { getParserIdForExtension, parse } from './ParserFactory.js'; +import type { IAudioMetadata, IOptions } from './type.js'; import { RandomFileReader } from './common/RandomFileReader.js'; export { IAudioMetadata, IOptions, ITag, INativeTagDict, ICommonTagsResult, IFormat, IPicture, IRatio, IChapter, ILyricsTag, LyricsContentType, TimestampFormat } from './type.js'; @@ -23,8 +23,8 @@ const debug = initDebug('music-metadata:parser'); * @param options - Parsing options * @returns Metadata */ -export async function parseStream(stream: Stream.Readable, fileInfo?: strtok3.IFileInfo | string, options: IOptions = {}): Promise { - const tokenizer = await strtok3.fromStream(stream, {fileInfo: typeof fileInfo === 'string' ? {mimeType: fileInfo} : fileInfo}); +export async function parseStream(stream: Readable, fileInfo?: IFileInfo | string, options: IOptions = {}): Promise { + const tokenizer = await fromStream(stream, {fileInfo: typeof fileInfo === 'string' ? {mimeType: fileInfo} : fileInfo}); return parseFromTokenizer(tokenizer, options); } @@ -38,7 +38,7 @@ export async function parseFile(filePath: string, options: IOptions = {}): Promi debug(`parseFile: ${filePath}`); - const fileTokenizer = await strtok3.fromFile(filePath); + const fileTokenizer = await fromFile(filePath); const fileReader = await RandomFileReader.init(filePath, fileTokenizer.fileInfo.size); try { @@ -48,11 +48,11 @@ export async function parseFile(filePath: string, options: IOptions = {}): Promi } try { - const parserName = ParserFactory.getParserIdForExtension(filePath); + const parserName = getParserIdForExtension(filePath); if (!parserName) debug(' Parser could not be determined by file extension'); - return await ParserFactory.parse(fileTokenizer, parserName, options); + return await parse(fileTokenizer, parserName, options); } finally { await fileTokenizer.close(); } diff --git a/lib/lyrics3/Lyrics3.ts b/lib/lyrics3/Lyrics3.ts index 0641a55d6..f94d28fe5 100644 --- a/lib/lyrics3/Lyrics3.ts +++ b/lib/lyrics3/Lyrics3.ts @@ -1,4 +1,4 @@ -import { IRandomReader } from '../type.js'; +import type { IRandomReader } from '../type.js'; export const endTag2 = 'LYRICS200'; @@ -9,7 +9,7 @@ export async function getLyricsHeaderLength(reader: IRandomReader): Promise Promise>(); + private parserMap = new Map Promise>(); private ebmlMaxIDLength = 4; private ebmlMaxSizeLength = 8; @@ -52,7 +52,7 @@ export class MatroskaParser extends BasicParser { public async parse(): Promise { const containerSize = this.tokenizer.fileInfo.size ?? Number.MAX_SAFE_INTEGER; - const matroska = await this.parseContainer(matroskaDtd.elements, containerSize, []) as any as IMatroskaDoc; + const matroska = await this.parseContainer(matroskaDtd.elements, containerSize, []) as unknown as IMatroskaDoc; this.metadata.setFormat('container', `EBML/${matroska.ebml.docType}`); if (matroska.segment) { @@ -68,7 +68,7 @@ export class MatroskaParser extends BasicParser { } const audioTracks = matroska.segment.tracks; - if (audioTracks && audioTracks.entries) { + if (audioTracks?.entries) { audioTracks.entries.forEach(entry => { const stream: ITrackInfo = { @@ -241,7 +241,7 @@ export class MatroskaParser extends BasicParser { return buf; } - private async addTag(tagId: string, value: any): Promise { + private async addTag(tagId: string, value: AnyTagValue): Promise { await this.metadata.addTag('matroska', tagId, value); } diff --git a/lib/matroska/MatroskaTagMapper.ts b/lib/matroska/MatroskaTagMapper.ts index f73e86521..2cf80d89b 100644 --- a/lib/matroska/MatroskaTagMapper.ts +++ b/lib/matroska/MatroskaTagMapper.ts @@ -1,4 +1,4 @@ -import {INativeTagMap} from '../common/GenericTagTypes.js'; +import type {INativeTagMap} from '../common/GenericTagTypes.js'; import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js'; /** diff --git a/lib/matroska/types.ts b/lib/matroska/types.ts index 8d6decef4..343163d51 100644 --- a/lib/matroska/types.ts +++ b/lib/matroska/types.ts @@ -3,7 +3,7 @@ export interface IHeader { len: number; } -export enum DataType { 'string', uint, uid, bool, binary, float} +export enum DataType { 'string' = 0, uint = 1, uid = 2, bool = 3, binary = 4, float = 5} export interface IElementType { readonly name: string; @@ -16,6 +16,8 @@ export interface IContainerType { [id: number]: IElementType 'mvhd': movie header atom; child of Movie Atom - case 'tkhd': - case 'stsz': - case 'mdat': + } default: return dataHandler(this, remaining); } diff --git a/lib/mp4/AtomToken.ts b/lib/mp4/AtomToken.ts index 6750082e5..3ea059008 100644 --- a/lib/mp4/AtomToken.ts +++ b/lib/mp4/AtomToken.ts @@ -209,7 +209,7 @@ export abstract class FixedLengthAtom { protected constructor(public len: number, expLen: number, atomId: string) { if (len < expLen) { throw new Error(`Atom ${atomId} expected to be ${expLen}, but specifies ${len} bytes long.`); - } else if (len > expLen) { + }if (len > expLen) { debug(`Warning: atom ${atomId} expected to be ${expLen}, but was actually ${len} bytes long.`); } } diff --git a/lib/mp4/MP4Parser.ts b/lib/mp4/MP4Parser.ts index df1272e4e..1f69eea98 100644 --- a/lib/mp4/MP4Parser.ts +++ b/lib/mp4/MP4Parser.ts @@ -5,9 +5,9 @@ import { BasicParser } from '../common/BasicParser.js'; import { Genres } from '../id3v1/ID3v1Parser.js'; import { Atom } from './Atom.js'; import * as AtomToken from './AtomToken.js'; -import { IChapter, ITrackInfo, TrackType } from '../type.js'; +import { type AnyTagValue, type IChapter, type ITrackInfo, TrackType } from '../type.js'; -import { IGetToken } from '@tokenizer/token'; +import type { IGetToken } from '@tokenizer/token'; import { uint8ArrayToHex, uint8ArrayToString } from 'uint8array-extras'; const debug = initDebug('music-metadata:parser:MP4'); @@ -47,7 +47,7 @@ interface ITrackDescription extends AtomToken.ITrackHeaderAtom { timeToSampleTable?: AtomToken.ITimeToSampleToken[]; } -type IAtomParser = (payloadLength: number) => Promise; +type IAtomParser = (payloadLength: number) => Promise; const encoderDict: { [dataFormatId: string]: IEncoder; } = { raw: { @@ -109,7 +109,7 @@ const encoderDict: { [dataFormatId: string]: IEncoder; } = { } }; -function distinct(value: any, index: number, self: any[]) { +function distinct(value: AnyTagValue, index: number, self: AnyTagValue[]) { return self.indexOf(value) === index; } @@ -137,7 +137,7 @@ export class MP4Parser extends BasicParser { const integerType = (signed ? 'INT' : 'UINT') + array.length * 8 + (array.length > 1 ? '_BE' : ''); const token: IGetToken = Token[integerType]; if (!token) { - throw new Error('Token for integer type not found: "' + integerType + '"'); + throw new Error(`Token for integer type not found: "${integerType}"`); } return Number(token.get(array, 0)); } @@ -256,10 +256,9 @@ export class MP4Parser extends BasicParser { if (this.atomParsers[atom.header.name]) { return this.atomParsers[atom.header.name](remaining); - } else { + } debug(`No parser for atom path=${atom.atomPath}, payload-len=${remaining}, ignoring atom`); await this.tokenizer.ignore(remaining); - } } private getTrackDescription(): ITrackDescription { @@ -272,12 +271,12 @@ export class MP4Parser extends BasicParser { } } - private async addTag(id: string, value: any): Promise { + private async addTag(id: string, value: AnyTagValue): Promise { await this.metadata.addTag(tagFormat, id, value); } private addWarning(message: string) { - debug('Warning: ' + message); + debug(`Warning: ${message}`); this.metadata.addWarning(message); } @@ -298,14 +297,16 @@ export class MP4Parser extends BasicParser { case 'name': // name atom (optional) case 'mean': - case 'rate': + case 'rate': { const name = await this.tokenizer.readToken(new AtomToken.NameAtom(payLoadLength)); - tagKey += ':' + name.name; + tagKey += `:${name.name}`; break; + } - default: + default: { const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength)); - this.addWarning('Unsupported meta-item: ' + tagKey + '[' + child.header.name + '] => value=' + uint8ArrayToHex(uint8Array) + ' ascii=' + uint8ArrayToString(uint8Array, 'ascii')); + this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${uint8ArrayToString(uint8Array, 'ascii')}`); + } } }, metaAtom.getPayloadLength(0)); @@ -315,7 +316,7 @@ export class MP4Parser extends BasicParser { const dataAtom = await this.tokenizer.readToken(new AtomToken.DataAtom(Number(metaAtom.header.length) - AtomToken.Header.len)); if (dataAtom.type.set !== 0) { - throw new Error('Unsupported type-set != 0: ' + dataAtom.type.set); + throw new Error(`Unsupported type-set != 0: ${dataAtom.type.set}`); } // Use well-known-type table @@ -325,27 +326,30 @@ export class MP4Parser extends BasicParser { case 0: // reserved: Reserved for use where no type needs to be indicated switch (tagKey) { case 'trkn': - case 'disk': + case 'disk': { const num = Token.UINT8.get(dataAtom.value, 3); const of = Token.UINT8.get(dataAtom.value, 5); // console.log(" %s[data] = %s/%s", tagKey, num, of); - await this.addTag(tagKey, num + '/' + of); + await this.addTag(tagKey, `${num}/${of}`); break; + } - case 'gnre': + case 'gnre': { const genreInt = Token.UINT8.get(dataAtom.value, 1); const genreStr = Genres[genreInt - 1]; // console.log(" %s[data] = %s", tagKey, genreStr); await this.addTag(tagKey, genreStr); break; + } - case 'rate': + case 'rate': { const rate = new TextDecoder('ascii').decode(dataAtom.value); await this.addTag(tagKey, rate); break; + } default: - debug('unknown proprietary value type for: ' + metaAtom.atomPath); + debug(`unknown proprietary value type for: ${metaAtom.atomPath}`); } break; diff --git a/lib/mp4/MP4TagMapper.ts b/lib/mp4/MP4TagMapper.ts index 96b96ca53..7eb041ad0 100644 --- a/lib/mp4/MP4TagMapper.ts +++ b/lib/mp4/MP4TagMapper.ts @@ -1,7 +1,7 @@ import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap.js'; -import { INativeTagMap } from '../common/GenericTagTypes.js'; -import {ITag} from "../type.js"; -import {INativeMetadataCollector} from "../common/MetadataCollector.js"; +import type { INativeTagMap } from '../common/GenericTagTypes.js'; +import type {ITag} from "../type.js"; +import type {INativeMetadataCollector} from "../common/MetadataCollector.js"; /** * Ref: https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata @@ -126,7 +126,7 @@ export class MP4TagMapper extends CaseInsensitiveTagMap { case 'rate': tag.value = { source: undefined, - rating: parseFloat(tag.value) / 100 + rating: Number.parseFloat(tag.value as string) / 100 }; break; } diff --git a/lib/mpeg/ExtendedLameHeader.ts b/lib/mpeg/ExtendedLameHeader.ts index 310fbf0e2..a8096ebb0 100644 --- a/lib/mpeg/ExtendedLameHeader.ts +++ b/lib/mpeg/ExtendedLameHeader.ts @@ -6,7 +6,7 @@ import type { IGetToken } from 'strtok3'; import * as Token from 'token-types'; import * as common from '../common/Util.js'; -import { ReplayGain, IReplayGain } from './ReplayGainDataFormat.js'; +import { ReplayGain, type IReplayGain } from './ReplayGainDataFormat.js'; /** * LAME Tag, extends the Xing header format @@ -40,7 +40,7 @@ export const ExtendedLameHeader: IGetToken = { revision: common.getBitAllignedNumber(buf, off, 0, 4), vbr_method: common.getBitAllignedNumber(buf, off, 4, 4), lowpass_filter: 100 * Token.UINT8.get(buf, off + 1), - track_peak: track_peak === 0 ? undefined : track_peak / Math.pow(2, 23), + track_peak: track_peak === 0 ? undefined : track_peak / 2 ** 23, track_gain: ReplayGain.get(buf, 6), album_gain: ReplayGain.get(buf, 8), music_length: Token.UINT32_BE.get(buf, off + 20), diff --git a/lib/mpeg/MpegParser.ts b/lib/mpeg/MpegParser.ts index 3c6bcdad5..4315ac21d 100644 --- a/lib/mpeg/MpegParser.ts +++ b/lib/mpeg/MpegParser.ts @@ -4,7 +4,7 @@ import initDebug from 'debug'; import * as common from '../common/Util.js'; import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js'; -import { InfoTagHeaderTag, IXingInfoTag, LameEncoderVersion, readXingHeader } from './XingTag.js'; +import { InfoTagHeaderTag, type IXingInfoTag, LameEncoderVersion, readXingHeader } from './XingTag.js'; const debug = initDebug('music-metadata:parser:mpeg'); @@ -72,26 +72,26 @@ class MpegFrameHeader { public static ChannelMode = ['stereo', 'joint_stereo', 'dual_channel', 'mono']; private static bitrate_index = { - 0x01: {11: 32, 12: 32, 13: 32, 21: 32, 22: 8, 23: 8}, - 0x02: {11: 64, 12: 48, 13: 40, 21: 48, 22: 16, 23: 16}, - 0x03: {11: 96, 12: 56, 13: 48, 21: 56, 22: 24, 23: 24}, - 0x04: {11: 128, 12: 64, 13: 56, 21: 64, 22: 32, 23: 32}, - 0x05: {11: 160, 12: 80, 13: 64, 21: 80, 22: 40, 23: 40}, - 0x06: {11: 192, 12: 96, 13: 80, 21: 96, 22: 48, 23: 48}, - 0x07: {11: 224, 12: 112, 13: 96, 21: 112, 22: 56, 23: 56}, - 0x08: {11: 256, 12: 128, 13: 112, 21: 128, 22: 64, 23: 64}, - 0x09: {11: 288, 12: 160, 13: 128, 21: 144, 22: 80, 23: 80}, - 0x0A: {11: 320, 12: 192, 13: 160, 21: 160, 22: 96, 23: 96}, - 0x0B: {11: 352, 12: 224, 13: 192, 21: 176, 22: 112, 23: 112}, - 0x0C: {11: 384, 12: 256, 13: 224, 21: 192, 22: 128, 23: 128}, - 0x0D: {11: 416, 12: 320, 13: 256, 21: 224, 22: 144, 23: 144}, - 0x0E: {11: 448, 12: 384, 13: 320, 21: 256, 22: 160, 23: 160} + 1: {11: 32, 12: 32, 13: 32, 21: 32, 22: 8, 23: 8}, + 2: {11: 64, 12: 48, 13: 40, 21: 48, 22: 16, 23: 16}, + 3: {11: 96, 12: 56, 13: 48, 21: 56, 22: 24, 23: 24}, + 4: {11: 128, 12: 64, 13: 56, 21: 64, 22: 32, 23: 32}, + 5: {11: 160, 12: 80, 13: 64, 21: 80, 22: 40, 23: 40}, + 6: {11: 192, 12: 96, 13: 80, 21: 96, 22: 48, 23: 48}, + 7: {11: 224, 12: 112, 13: 96, 21: 112, 22: 56, 23: 56}, + 8: {11: 256, 12: 128, 13: 112, 21: 128, 22: 64, 23: 64}, + 9: {11: 288, 12: 160, 13: 128, 21: 144, 22: 80, 23: 80}, + 10: {11: 320, 12: 192, 13: 160, 21: 160, 22: 96, 23: 96}, + 11: {11: 352, 12: 224, 13: 192, 21: 176, 22: 112, 23: 112}, + 12: {11: 384, 12: 256, 13: 224, 21: 192, 22: 128, 23: 128}, + 13: {11: 416, 12: 320, 13: 256, 21: 224, 22: 144, 23: 144}, + 14: {11: 448, 12: 384, 13: 320, 21: 256, 22: 160, 23: 160} }; private static sampling_rate_freq_index = { - 1: {0x00: 44100, 0x01: 48000, 0x02: 32000}, - 2: {0x00: 22050, 0x01: 24000, 0x02: 16000}, - 2.5: {0x00: 11025, 0x01: 12000, 0x02: 8000} + 1: {0: 44100, 1: 48000, 2: 32000}, + 2: {0: 22050, 1: 24000, 2: 16000}, + 2.5: {0: 11025, 1: 12000, 2: 8000} }; private static samplesInFrameTable = [ @@ -168,13 +168,13 @@ class MpegFrameHeader { // mono if (this.version === 1) { return 17; - } else if (this.version === 2 || this.version === 2.5) { + }if (this.version === 2 || this.version === 2.5) { return 9; } } else { if (this.version === 1) { return 32; - } else if (this.version === 2 || this.version === 2.5) { + }if (this.version === 2 || this.version === 2.5) { return 17; } } @@ -225,9 +225,9 @@ class MpegFrameHeader { } private parseAdtsHeader(buf: Uint8Array, off: number): void { - debug(`layer=0 => ADTS`); + debug("layer=0 => ADTS"); this.version = this.versionIndex === 2 ? 4 : 2; - this.container = 'ADTS/MPEG-' + this.version; + this.container = `ADTS/MPEG-${this.version}`; const profileIndex = common.getBitAllignedNumber(buf, off + 2, 0, 2); this.codec = 'AAC'; this.codecProfile = MPEG4.AudioObjectTypes[profileIndex]; @@ -272,14 +272,14 @@ const FrameHeader = { }; function getVbrCodecProfile(vbrScale: number): string { - return 'V' + Math.floor((100 - vbrScale) / 10); + return `V${Math.floor((100 - vbrScale) / 10)}`; } export class MpegParser extends AbstractID3Parser { - private frameCount: number = 0; - private syncFrameCount: number = -1; - private countSkipFrameData: number = 0; + private frameCount = 0; + private syncFrameCount = -1; + private countSkipFrameData = 0; private totalDataLength = 0; private audioFrameHeader; @@ -288,7 +288,7 @@ export class MpegParser extends AbstractID3Parser { private frame_size; private crc: number; - private calculateEofDuration: boolean = false; + private calculateEofDuration = false; private samplesPerFrame; private buf_frame_header = new Uint8Array(4); @@ -318,7 +318,7 @@ export class MpegParser extends AbstractID3Parser { } } catch (err) { if (err instanceof EndOfStreamError) { - debug(`End-of-stream`); + debug("End-of-stream"); if (this.calculateEofDuration) { const numberOfSamples = this.frameCount * this.samplesPerFrame; this.metadata.setFormat('numberOfSamples', numberOfSamples); @@ -338,7 +338,7 @@ export class MpegParser extends AbstractID3Parser { protected finalize() { const format = this.metadata.format; - const hasID3v1 = this.metadata.native.hasOwnProperty('ID3v1'); + const hasID3v1 = !!this.metadata.native.ID3v1; if (format.duration && this.tokenizer.fileInfo.size) { const mpegSize = this.tokenizer.fileInfo.size - this.mpegOffset - (hasID3v1 ? 128 : 0); if (format.codecProfile && format.codecProfile[0] === 'V') { @@ -377,7 +377,7 @@ export class MpegParser extends AbstractID3Parser { } this.syncFrameCount = this.frameCount; return; // sync - } else { + } gotFirstSync = false; bo = this.syncPeek.buf.indexOf(MpegFrameHeader.SyncByte1, bo); if (bo === -1) { @@ -386,11 +386,9 @@ export class MpegParser extends AbstractID3Parser { } await this.tokenizer.ignore(this.syncPeek.len); break; // continue with next buffer - } else { + } ++bo; gotFirstSync = true; - } - } } } } @@ -412,7 +410,7 @@ export class MpegParser extends AbstractID3Parser { header = FrameHeader.get(this.buf_frame_header, 0); } catch (err) { await this.tokenizer.ignore(1); - this.metadata.addWarning('Parse error: ' + err.message); + this.metadata.addWarning(`Parse error: ${err.message}`); return false; // sync } await this.tokenizer.ignore(3); @@ -487,10 +485,9 @@ export class MpegParser extends AbstractID3Parser { if (header.isProtectedByCRC) { await this.parseCrc(); return false; - } else { + } await this.skipSideInformation(); return false; - } } private async parseAdts(header: MpegFrameHeader): Promise { @@ -549,34 +546,35 @@ export class MpegParser extends AbstractID3Parser { this.metadata.setFormat('codecProfile', 'CBR'); return this.readXingInfoHeader(); - case 'Xing': + case 'Xing': { const infoTag = await this.readXingInfoHeader(); const codecProfile = getVbrCodecProfile(infoTag.vbrScale); this.metadata.setFormat('codecProfile', codecProfile); return null; + } case 'Xtra': // ToDo: ??? break; - case 'LAME': + case 'LAME': { const version = await this.tokenizer.readToken(LameEncoderVersion); if (this.frame_size >= this.offset + LameEncoderVersion.len) { this.offset += LameEncoderVersion.len; - this.metadata.setFormat('tool', 'LAME ' + version); + this.metadata.setFormat('tool', `LAME ${version}`); await this.skipFrameData(this.frame_size - this.offset); return null; - } else { + } this.metadata.addWarning('Corrupt LAME header'); break; - } + } // ToDo: ??? } // ToDo: promise duration??? const frameDataLeft = this.frame_size - this.offset; if (frameDataLeft < 0) { - this.metadata.addWarning('Frame ' + this.frameCount + 'corrupt: negative frameDataLeft'); + this.metadata.addWarning(`Frame ${this.frameCount}corrupt: negative frameDataLeft`); } else { await this.skipFrameData(frameDataLeft); } @@ -595,7 +593,7 @@ export class MpegParser extends AbstractID3Parser { this.offset += this.tokenizer.position - offset; if (infoTag.lame) { - this.metadata.setFormat('tool', 'LAME ' + common.stripNulls(infoTag.lame.version)); + this.metadata.setFormat('tool', `LAME ${common.stripNulls(infoTag.lame.version)}`); if (infoTag.lame.extended) { // this.metadata.setFormat('trackGain', infoTag.lame.extended.track_gain); this.metadata.setFormat('trackPeakLevel', infoTag.lame.extended.track_peak); diff --git a/lib/mpeg/XingTag.ts b/lib/mpeg/XingTag.ts index f655334c1..0065b6276 100644 --- a/lib/mpeg/XingTag.ts +++ b/lib/mpeg/XingTag.ts @@ -2,7 +2,7 @@ import * as Token from 'token-types'; import type { IGetToken, ITokenizer } from 'strtok3'; import * as util from '../common/Util.js'; -import { ExtendedLameHeader, IExtendedLameHeader } from './ExtendedLameHeader.js'; +import { ExtendedLameHeader, type IExtendedLameHeader } from './ExtendedLameHeader.js'; export interface IXingHeaderFlags { frames: boolean; @@ -94,7 +94,7 @@ export async function readXingHeader(tokenizer: ITokenizer): Promise parseInt(n, 10)); + const version = majorMinorVersion.split('.').map(n => Number.parseInt(n, 10)); if (version[0] >= 3 && version[1] >= 90) { xingInfoTag.lame.extended = await tokenizer.readToken(ExtendedLameHeader); } diff --git a/lib/musepack/index.ts b/lib/musepack/index.ts index 777cc2745..6915daac2 100644 --- a/lib/musepack/index.ts +++ b/lib/musepack/index.ts @@ -1,7 +1,7 @@ import initDebug from 'debug'; import * as Token from 'token-types'; -import { ITokenParser } from '../ParserFactory.js'; +import type { ITokenParser } from '../ParserFactory.js'; import { AbstractID3Parser } from '../id3v2/AbstractID3Parser.js'; import { MpcSv8Parser } from './sv8/MpcSv8Parser.js'; diff --git a/lib/musepack/sv7/BitReader.ts b/lib/musepack/sv7/BitReader.ts index c634753e4..ea5a07df9 100644 --- a/lib/musepack/sv7/BitReader.ts +++ b/lib/musepack/sv7/BitReader.ts @@ -3,7 +3,7 @@ import * as Token from 'token-types'; export class BitReader { - public pos: number = 0; + public pos = 0; private dword: number = undefined; public constructor(private tokenizer: ITokenizer) { @@ -25,20 +25,18 @@ export class BitReader { if (this.pos < 32) { out >>>= (32 - this.pos); return out & ((1 << bits) - 1); - } else { + } this.pos -= 32; if (this.pos === 0) { this.dword = undefined; return out & ((1 << bits) - 1); - } else { + } this.dword = await this.tokenizer.readToken(Token.UINT32_LE); if (this.pos) { out <<= this.pos; out |= this.dword >>> (32 - this.pos); } return out & ((1 << bits) - 1); - } - } } public async ignore(bits: number): Promise { diff --git a/lib/musepack/sv7/MpcSv7Parser.ts b/lib/musepack/sv7/MpcSv7Parser.ts index 8a80293fc..44d929b4e 100644 --- a/lib/musepack/sv7/MpcSv7Parser.ts +++ b/lib/musepack/sv7/MpcSv7Parser.ts @@ -10,7 +10,7 @@ const debug = initDebug('music-metadata:parser:musepack'); export class MpcSv7Parser extends BasicParser { private bitreader: BitReader; - private audioLength: number = 0; + private audioLength = 0; private duration: number; public async parse(): Promise { diff --git a/lib/musepack/sv8/MpcSv8Parser.ts b/lib/musepack/sv8/MpcSv8Parser.ts index 56732f0ef..3842b7154 100644 --- a/lib/musepack/sv8/MpcSv8Parser.ts +++ b/lib/musepack/sv8/MpcSv8Parser.ts @@ -9,7 +9,7 @@ const debug = initDebug('music-metadata:parser:musepack'); export class MpcSv8Parser extends BasicParser { - private audioLength: number = 0; + private audioLength = 0; public async parse(): Promise { @@ -28,13 +28,14 @@ export class MpcSv8Parser extends BasicParser { debug(`packet-header key=${header.key}, payloadLength=${header.payloadLength}`); switch (header.key) { - case 'SH': // Stream Header + case 'SH': { // Stream Header const sh = await sv8reader.readStreamHeader(header.payloadLength); this.metadata.setFormat('numberOfSamples', sh.sampleCount); this.metadata.setFormat('sampleRate', sh.sampleFrequency); this.metadata.setFormat('duration', sh.sampleCount / sh.sampleFrequency); this.metadata.setFormat('numberOfChannels', sh.channelCount); break; + } case 'AP': // Audio Packet this.audioLength += header.payloadLength; diff --git a/lib/musepack/sv8/StreamVersion8.ts b/lib/musepack/sv8/StreamVersion8.ts index 34f64d825..3c694a8db 100644 --- a/lib/musepack/sv8/StreamVersion8.ts +++ b/lib/musepack/sv8/StreamVersion8.ts @@ -1,5 +1,5 @@ import * as Token from 'token-types'; -import { ITokenizer, IGetToken } from 'strtok3'; +import type { ITokenizer, IGetToken } from 'strtok3'; import initDebug from 'debug'; import * as util from '../../common/Util.js'; @@ -100,7 +100,7 @@ export class StreamReader { public async readStreamHeader(size: number): Promise { - const streamHeader: IStreamHeader = {} as any; + const streamHeader: IStreamHeader = {} as unknown as IStreamHeader; debug(`Reading SH at offset=${this.tokenizer.position}`); const part1 = await this.tokenizer.readToken(SH_part1); @@ -124,7 +124,7 @@ export class StreamReader { return streamHeader; } - private async readVariableSizeField(len: number = 1, hb: number = 0): Promise { + private async readVariableSizeField(len = 1, hb = 0): Promise { let n = await this.tokenizer.readNumber(Token.UINT8); if ((n & 0x80) === 0) { return {len, value: hb + n}; diff --git a/lib/ogg/OggParser.ts b/lib/ogg/OggParser.ts index 775d70713..d5a6a786b 100644 --- a/lib/ogg/OggParser.ts +++ b/lib/ogg/OggParser.ts @@ -1,5 +1,5 @@ import * as Token from 'token-types'; -import { IGetToken, EndOfStreamError } from 'strtok3'; +import { type IGetToken, EndOfStreamError } from 'strtok3'; import initDebug from 'debug'; import * as util from '../common/Util.js'; @@ -11,14 +11,14 @@ import { OpusParser } from './opus/OpusParser.js'; import { SpeexParser } from './speex/SpeexParser.js'; import { TheoraParser } from './theora/TheoraParser.js'; -import * as Ogg from './Ogg.js'; +import type * as Ogg from './Ogg.js'; const debug = initDebug('music-metadata:parser:ogg'); export class SegmentTable implements IGetToken { private static sum(buf: number[], off: number, len: number): number { - let s: number = 0; + let s = 0; for (let i = off; i < off + len; ++i) { s += buf[i]; } @@ -114,7 +114,7 @@ export class OggParser extends BasicParser { this.pageConsumer = new TheoraParser(this.metadata, this.options, this.tokenizer); break; default: - throw new Error('gg audio-codec not recognized (id=' + id + ')'); + throw new Error(`gg audio-codec not recognized (id=${id})`); } } await this.pageConsumer.parsePage(header, pageData); @@ -122,7 +122,7 @@ export class OggParser extends BasicParser { } catch (err) { if (err instanceof EndOfStreamError) { this.metadata.addWarning('Last OGG-page is not marked with last-page flag'); - debug(`End-of-stream`); + debug("End-of-stream"); this.metadata.addWarning('Last OGG-page is not marked with last-page flag'); if (this.header) { this.pageConsumer.calculateDuration(this.header); diff --git a/lib/ogg/opus/OpusParser.ts b/lib/ogg/opus/OpusParser.ts index 5113c4eb9..1e4a2c5c1 100644 --- a/lib/ogg/opus/OpusParser.ts +++ b/lib/ogg/opus/OpusParser.ts @@ -1,10 +1,10 @@ import * as Token from 'token-types'; -import {ITokenizer} from 'strtok3'; +import type {ITokenizer} from 'strtok3'; -import {IPageHeader} from '../Ogg.js'; +import type {IPageHeader} from '../Ogg.js'; import {VorbisParser} from '../vorbis/VorbisParser.js'; -import {IOptions} from '../../type.js'; -import {INativeMetadataCollector} from '../../common/MetadataCollector.js'; +import type {IOptions} from '../../type.js'; +import type {INativeMetadataCollector} from '../../common/MetadataCollector.js'; import * as Opus from './Opus.js'; @@ -16,7 +16,7 @@ import * as Opus from './Opus.js'; export class OpusParser extends VorbisParser { private idHeader: Opus.IIdHeader; - private lastPos: number = -1; + private lastPos = -1; constructor(metadata: INativeMetadataCollector, options: IOptions, private tokenizer: ITokenizer) { super(metadata, options); diff --git a/lib/ogg/speex/SpeexParser.ts b/lib/ogg/speex/SpeexParser.ts index 2f4083fa2..f213d0b33 100644 --- a/lib/ogg/speex/SpeexParser.ts +++ b/lib/ogg/speex/SpeexParser.ts @@ -1,12 +1,12 @@ -import { ITokenizer } from 'strtok3'; +import type { ITokenizer } from 'strtok3'; import initDebug from 'debug'; -import { IPageHeader } from '../Ogg.js'; +import type { IPageHeader } from '../Ogg.js'; import { VorbisParser } from '../vorbis/VorbisParser.js'; import * as Speex from './Speex.js'; -import { IOptions } from '../../type.js'; -import { INativeMetadataCollector } from '../../common/MetadataCollector.js'; +import type { IOptions } from '../../type.js'; +import type { INativeMetadataCollector } from '../../common/MetadataCollector.js'; const debug = initDebug('music-metadata:parser:ogg:speex'); diff --git a/lib/ogg/theora/TheoraParser.ts b/lib/ogg/theora/TheoraParser.ts index db491b54c..37e182608 100644 --- a/lib/ogg/theora/TheoraParser.ts +++ b/lib/ogg/theora/TheoraParser.ts @@ -1,9 +1,9 @@ -import { ITokenizer } from 'strtok3'; +import type { ITokenizer } from 'strtok3'; import initDebug from 'debug'; -import * as Ogg from '../Ogg.js'; -import { IOptions } from '../../type.js'; -import { INativeMetadataCollector } from '../../common/MetadataCollector.js'; +import type * as Ogg from '../Ogg.js'; +import type { IOptions } from '../../type.js'; +import type { INativeMetadataCollector } from '../../common/MetadataCollector.js'; import { IdentificationHeader } from './Theora.js'; const debug = initDebug('music-metadata:parser:ogg:theora'); diff --git a/lib/ogg/vorbis/Vorbis.ts b/lib/ogg/vorbis/Vorbis.ts index dcee4900f..b51ab46e9 100644 --- a/lib/ogg/vorbis/Vorbis.ts +++ b/lib/ogg/vorbis/Vorbis.ts @@ -2,7 +2,7 @@ import * as Token from 'token-types'; import { AttachedPictureType } from '../../id3v2/ID3v2Token.js'; -import { IPicture } from '../../type.js'; +import type { IPicture } from '../../type.js'; import type { IGetToken } from 'strtok3'; /** @@ -34,7 +34,7 @@ export interface IVorbisPicture extends IPicture { export class VorbisPictureToken implements IGetToken { public static fromBase64(base64str: string): IVorbisPicture { - return this.fromBuffer(Uint8Array.from(atob(base64str), c => c.charCodeAt(0))); + return VorbisPictureToken.fromBuffer(Uint8Array.from(atob(base64str), c => c.charCodeAt(0))); } public static fromBuffer(buffer: Uint8Array): IVorbisPicture { @@ -49,19 +49,26 @@ export class VorbisPictureToken implements IGetToken { const type = AttachedPictureType[Token.UINT32_BE.get(buffer, offset)]; - const mimeLen = Token.UINT32_BE.get(buffer, offset += 4); - const format = new Token.StringType(mimeLen, 'utf-8').get(buffer, offset += 4); - - const descLen = Token.UINT32_BE.get(buffer, offset += mimeLen); - const description = new Token.StringType(descLen, 'utf-8').get(buffer, offset += 4); - - const width = Token.UINT32_BE.get(buffer, offset += descLen); - const height = Token.UINT32_BE.get(buffer, offset += 4); - const colour_depth = Token.UINT32_BE.get(buffer, offset += 4); - const indexed_color = Token.UINT32_BE.get(buffer, offset += 4); - - const picDataLen = Token.UINT32_BE.get(buffer, offset += 4); - const data = Uint8Array.from(buffer.slice(offset += 4, offset + picDataLen)); + offset += 4; + const mimeLen = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const format = new Token.StringType(mimeLen, 'utf-8').get(buffer, offset); + offset += mimeLen; + const descLen = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const description = new Token.StringType(descLen, 'utf-8').get(buffer, offset); + offset += descLen + const width = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const height = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const colour_depth = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const indexed_color = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const picDataLen = Token.UINT32_BE.get(buffer, offset); + offset += 4; + const data = Uint8Array.from(buffer.slice(offset, offset + picDataLen)); return { type, diff --git a/lib/ogg/vorbis/VorbisParser.ts b/lib/ogg/vorbis/VorbisParser.ts index 2b08785dd..af7b022f8 100644 --- a/lib/ogg/vorbis/VorbisParser.ts +++ b/lib/ogg/vorbis/VorbisParser.ts @@ -2,11 +2,11 @@ import * as Token from 'token-types'; import debugInit from 'debug'; import { VorbisDecoder } from './VorbisDecoder.js'; -import { CommonHeader, IdentificationHeader, IVorbisPicture, VorbisPictureToken } from './Vorbis.js'; +import { CommonHeader, IdentificationHeader, type IVorbisPicture, VorbisPictureToken } from './Vorbis.js'; -import { IPageConsumer, IPageHeader } from '../Ogg.js'; -import { IOptions } from '../../type.js'; -import { INativeMetadataCollector } from '../../common/MetadataCollector.js'; +import type { IPageConsumer, IPageHeader } from '../Ogg.js'; +import type { IOptions } from '../../type.js'; +import type { INativeMetadataCollector } from '../../common/MetadataCollector.js'; const debug = debugInit('music-metadata:parser:ogg:vorbis1'); @@ -79,7 +79,7 @@ export class VorbisParser implements IPageConsumer { public async addTag(id: string, value: string | IVorbisPicture): Promise { if (id === 'METADATA_BLOCK_PICTURE' && (typeof value === 'string')) { if (this.options.skipCovers) { - debug(`Ignore picture`); + debug("Ignore picture"); return; } value = VorbisPictureToken.fromBase64(value); diff --git a/lib/ogg/vorbis/VorbisTagMapper.ts b/lib/ogg/vorbis/VorbisTagMapper.ts index 671a29664..31d75dcac 100644 --- a/lib/ogg/vorbis/VorbisTagMapper.ts +++ b/lib/ogg/vorbis/VorbisTagMapper.ts @@ -1,7 +1,7 @@ -import { INativeTagMap } from '../../common/GenericTagTypes.js'; +import type { INativeTagMap } from '../../common/GenericTagTypes.js'; import { CommonTagMapper } from '../../common/GenericTagMapper.js'; -import { IRating, ITag } from '../../type.js'; +import type { IRating, ITag } from '../../type.js'; /** * Vorbis tag mappings @@ -123,7 +123,7 @@ export class VorbisTagMapper extends CommonTagMapper { return { source: email ? email.toLowerCase() : email, - rating: (parseFloat(rating) / maxScore) * CommonTagMapper.maxRatingScore + rating: (Number.parseFloat(rating) / maxScore) * CommonTagMapper.maxRatingScore }; } @@ -134,10 +134,10 @@ export class VorbisTagMapper extends CommonTagMapper { protected postMap(tag: ITag): void { if (tag.id === 'RATING') { // The way Winamp 5.666 assigns rating - tag.value = VorbisTagMapper.toRating(undefined, tag.value, 100); + tag.value = VorbisTagMapper.toRating(undefined, tag.value as string, 100); } else if (tag.id.indexOf('RATING:') === 0) { const keys = tag.id.split(':'); - tag.value = VorbisTagMapper.toRating(keys[1], tag.value, 1); + tag.value = VorbisTagMapper.toRating(keys[1], tag.value as string, 1); tag.id = keys[0]; } diff --git a/lib/riff/RiffChunk.ts b/lib/riff/RiffChunk.ts index 05d64a5e8..1fc5937ab 100644 --- a/lib/riff/RiffChunk.ts +++ b/lib/riff/RiffChunk.ts @@ -1,6 +1,6 @@ import * as Token from 'token-types'; import type { IGetToken } from 'strtok3'; -import { IChunkHeader } from '../iff/index.js'; +import type { IChunkHeader } from '../iff/index.js'; export { IChunkHeader } from '../iff/index.js'; diff --git a/lib/riff/RiffInfoTagMap.ts b/lib/riff/RiffInfoTagMap.ts index 0c2bd2f78..b91125097 100644 --- a/lib/riff/RiffInfoTagMap.ts +++ b/lib/riff/RiffInfoTagMap.ts @@ -1,4 +1,4 @@ -import {INativeTagMap} from '../common/GenericTagTypes.js'; +import type {INativeTagMap} from '../common/GenericTagTypes.js'; import {CommonTagMapper} from '../common/GenericTagMapper.js'; /** diff --git a/lib/type.ts b/lib/type.ts index 3cfc217db..5ea75c00b 100644 --- a/lib/type.ts +++ b/lib/type.ts @@ -1,11 +1,13 @@ -import { GenericTagId, TagType } from './common/GenericTagTypes.js'; -import { IFooter } from './apev2/APEv2Token.js'; -import { TrackType } from './matroska/types.js'; -import { LyricsContentType, TimestampFormat } from './id3v2/ID3v2Token.js'; +import type { GenericTagId, TagType } from './common/GenericTagTypes.js'; +import type { IFooter } from './apev2/APEv2Token.js'; +import type { TrackType } from './matroska/types.js'; +import type { LyricsContentType, TimestampFormat } from './id3v2/ID3v2Token.js'; export { TrackType } from './matroska/types.js'; export { LyricsContentType, TimestampFormat } from './id3v2/ID3v2Token.js'; +export type AnyTagValue = unknown; + /** * Attached picture, typically used for cover art */ @@ -513,8 +515,8 @@ export interface IFormat { } export interface ITag { - id: string, - value: any + id: string; + value: AnyTagValue; } export interface IChapter { @@ -540,7 +542,7 @@ export interface INativeTags { * Tags ordered by tag-ID */ export interface INativeTagDict { - [tagId: string]: any[]; + [tagId: string]: AnyTagValue[]; } export interface INativeAudioMetadata { @@ -658,7 +660,7 @@ export interface IMetadataEvent { /** * Tag value */ - value: any + value: AnyTagValue }; /** diff --git a/lib/wav/WaveChunk.ts b/lib/wav/WaveChunk.ts index 647a1989f..7068d4b5c 100644 --- a/lib/wav/WaveChunk.ts +++ b/lib/wav/WaveChunk.ts @@ -1,5 +1,5 @@ import type { IGetToken } from 'strtok3'; -import { IChunkHeader } from '../iff/index.js'; +import type { IChunkHeader } from '../iff/index.js'; import * as Token from 'token-types'; /** diff --git a/lib/wav/WaveParser.ts b/lib/wav/WaveParser.ts index 546c3a170..fd04aefed 100644 --- a/lib/wav/WaveParser.ts +++ b/lib/wav/WaveParser.ts @@ -8,7 +8,8 @@ import { ID3v2Parser } from '../id3v2/ID3v2Parser.js'; import * as util from '../common/Util.js'; import { FourCcToken } from '../common/FourCC.js'; import { BasicParser } from '../common/BasicParser.js'; -import { BroadcastAudioExtensionChunk } from '../wav/BwfChunk.js'; +import { BroadcastAudioExtensionChunk } from './BwfChunk.js'; +import type { AnyTagValue } from '../type.js'; const debug = initDebug('music-metadata:parser:RIFF'); @@ -76,13 +77,13 @@ export class WaveParser extends BasicParser { this.fact = await this.tokenizer.readToken(new WaveChunk.FactChunk(header)); break; - case 'fmt ': // The Util Chunk, non-PCM Formats + case 'fmt ': { // The Util Chunk, non-PCM Formats const fmt = await this.tokenizer.readToken(new WaveChunk.Format(header)); let subFormat = WaveChunk.WaveFormat[fmt.wFormatTag]; if (!subFormat) { - debug('WAVE/non-PCM format=' + fmt.wFormatTag); - subFormat = 'non-PCM (' + fmt.wFormatTag + ')'; + debug(`WAVE/non-PCM format=${fmt.wFormatTag}`); + subFormat = `non-PCM (${fmt.wFormatTag})`; } this.metadata.setFormat('codec', subFormat); this.metadata.setFormat('bitsPerSample', fmt.wBitsPerSample); @@ -91,15 +92,17 @@ export class WaveParser extends BasicParser { this.metadata.setFormat('bitrate', fmt.nBlockAlign * fmt.nSamplesPerSec * 8); this.blockAlign = fmt.nBlockAlign; break; + } case 'id3 ': // The way Picard, FooBar currently stores, ID3 meta-data - case 'ID3 ': // The way Mp3Tags stores ID3 meta-data + case 'ID3 ': { // The way Mp3Tags stores ID3 meta-data const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize)); const rst = strtok3.fromBuffer(id3_data); await new ID3v2Parser().parse(this.metadata, rst, this.options); break; + } - case 'data': // PCM-data + case 'data': { // PCM-data if (this.metadata.format.lossless !== false) { this.metadata.setFormat('lossless', true); } @@ -126,25 +129,27 @@ export class WaveParser extends BasicParser { } await this.tokenizer.ignore(header.chunkSize); break; + } - case 'bext': // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf + case 'bext': { // Broadcast Audio Extension chunk https://tech.ebu.ch/docs/tech/tech3285.pdf const bext = await this.tokenizer.readToken(BroadcastAudioExtensionChunk); Object.keys(bext).forEach(key => { - this.metadata.addTag('exif', 'bext.' + key, bext[key]); + this.metadata.addTag('exif', `bext.${key}`, bext[key]); }); const bextRemaining = header.chunkSize - BroadcastAudioExtensionChunk.len; await this.tokenizer.ignore(bextRemaining); break; + } case '\x00\x00\x00\x00': // padding ?? debug(`Ignore padding chunk: RIFF/${header.chunkID} of ${header.chunkSize} bytes`); - this.metadata.addWarning('Ignore chunk: RIFF/' + header.chunkID); + this.metadata.addWarning(`Ignore chunk: RIFF/${header.chunkID}`); await this.tokenizer.ignore(header.chunkSize); break; default: debug(`Ignore chunk: RIFF/${header.chunkID} of ${header.chunkSize} bytes`); - this.metadata.addWarning('Ignore chunk: RIFF/' + header.chunkID); + this.metadata.addWarning(`Ignore chunk: RIFF/${header.chunkID}`); await this.tokenizer.ignore(header.chunkSize); } @@ -161,11 +166,9 @@ export class WaveParser extends BasicParser { switch (listType) { case 'INFO': return this.parseRiffInfoTags(listHeader.chunkSize - 4); - - case 'adtl': default: - this.metadata.addWarning('Ignore chunk: RIFF/WAVE/LIST/' + listType); - debug('Ignoring chunkID=RIFF/WAVE/LIST/' + listType); + this.metadata.addWarning(`Ignore chunk: RIFF/WAVE/LIST/${listType}`); + debug(`Ignoring chunkID=RIFF/WAVE/LIST/${listType}`); return this.tokenizer.ignore(listHeader.chunkSize - 4).then(); } } @@ -180,11 +183,11 @@ export class WaveParser extends BasicParser { } if (chunkSize !== 0) { - throw Error('Illegal remaining size: ' + chunkSize); + throw new Error(`Illegal remaining size: ${chunkSize}`); } } - private addTag(id: string, value: any) { + private addTag(id: string, value: AnyTagValue) { this.metadata.addTag('exif', id, value); } diff --git a/lib/wavpack/WavPackParser.ts b/lib/wavpack/WavPackParser.ts index 36a337c98..775e675a5 100644 --- a/lib/wavpack/WavPackParser.ts +++ b/lib/wavpack/WavPackParser.ts @@ -3,7 +3,7 @@ import * as Token from 'token-types'; import { APEv2Parser } from '../apev2/APEv2Parser.js'; import { FourCcToken } from '../common/FourCC.js'; import { BasicParser } from '../common/BasicParser.js'; -import { IBlockHeader, IMetadataId, WavPack } from './WavPackToken.js'; +import { BlockHeaderToken, type IBlockHeader, type IMetadataId, MetadataIdToken } from './WavPackToken.js'; import initDebug from 'debug'; import { uint8ArrayToHex } from 'uint8array-extras'; @@ -35,10 +35,10 @@ export class WavPackParser extends BasicParser { if (blockId !== 'wvpk') break; - const header = await this.tokenizer.readToken(WavPack.BlockHeaderToken); + const header = await this.tokenizer.readToken(BlockHeaderToken); if (header.BlockID !== 'wvpk') throw new Error('Invalid WavPack Block-ID'); - debug(`WavPack header blockIndex=${header.blockIndex}, len=${WavPack.BlockHeaderToken.len}`); + debug(`WavPack header blockIndex=${header.blockIndex}, len=${BlockHeaderToken.len}`); if (header.blockIndex === 0 && !this.metadata.format.container) { this.metadata.setFormat('container', 'WavPack'); @@ -55,25 +55,26 @@ export class WavPackParser extends BasicParser { this.metadata.setFormat('codec', header.flags.isDSD ? 'DSD' : 'PCM'); } - const ignoreBytes = header.blockSize - (WavPack.BlockHeaderToken.len - 8); + const ignoreBytes = header.blockSize - (BlockHeaderToken.len - 8); await (header.blockIndex === 0 ? this.parseMetadataSubBlock(header, ignoreBytes) : this.tokenizer.ignore(ignoreBytes)); if (header.blockSamples > 0) { this.audioDataSize += header.blockSize; // Count audio data for bit-rate calculation } } - while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= WavPack.BlockHeaderToken.len); + while (!this.tokenizer.fileInfo.size || this.tokenizer.fileInfo.size - this.tokenizer.position >= BlockHeaderToken.len); this.metadata.setFormat('bitrate', this.audioDataSize * 8 / this.metadata.format.duration); } /** * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf, 3.0 Metadata Sub-blocks * @param header Header - * @param remainingLength + * @param remainingLength Remaining length */ private async parseMetadataSubBlock(header: IBlockHeader, remainingLength: number): Promise { - while (remainingLength > WavPack.MetadataIdToken.len) { - const id = await this.tokenizer.readToken(WavPack.MetadataIdToken); + let remaining = remainingLength; + while (remaining > MetadataIdToken.len) { + const id = await this.tokenizer.readToken(MetadataIdToken); const dataSizeInWords = await this.tokenizer.readNumber(id.largeBlock ? Token.UINT24_LE : Token.UINT8); const data = new Uint8Array(dataSizeInWords * 2 - (id.isOddSize ? 1 : 0)); await this.tokenizer.readBuffer(data); @@ -82,7 +83,7 @@ export class WavPackParser extends BasicParser { case 0x0: // ID_DUMMY: could be used to pad WavPack blocks break; - case 0xe: // ID_DSD_BLOCK + case 0xe: { // ID_DSD_BLOCK debug('ID_DSD_BLOCK'); // https://github.com/dbry/WavPack/issues/71#issuecomment-483094813 const mp = 1 << Token.UINT8.get(data, 0); @@ -92,6 +93,7 @@ export class WavPackParser extends BasicParser { this.metadata.setFormat('sampleRate', samplingRate); this.metadata.setFormat('duration', header.totalSamples / samplingRate); break; + } case 0x24: // ID_ALT_TRAILER: maybe used to embed original ID3 tag header debug('ID_ALT_TRAILER: trailer for non-wav files'); @@ -110,12 +112,12 @@ export class WavPackParser extends BasicParser { break; } - remainingLength -= WavPack.MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2; - debug(`remainingLength=${remainingLength}`); + remaining -= MetadataIdToken.len + (id.largeBlock ? Token.UINT24_LE.len : Token.UINT8.len) + dataSizeInWords * 2; + debug(`remainingLength=${remaining}`); if (id.isOddSize) this.tokenizer.ignore(1); } - if (remainingLength !== 0) throw new Error('metadata-sub-block should fit it remaining length'); + if (remaining !== 0) throw new Error('metadata-sub-block should fit it remaining length'); } } diff --git a/lib/wavpack/WavPackToken.ts b/lib/wavpack/WavPackToken.ts index 842c3f12b..4278e0db7 100644 --- a/lib/wavpack/WavPackToken.ts +++ b/lib/wavpack/WavPackToken.ts @@ -69,82 +69,80 @@ export interface IMetadataId { const SampleRates = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000, -1]; -export class WavPack { - - /** - * WavPack Block Header - * - * 32-byte little-endian header at the front of every WavPack block - * - * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header") - */ - public static BlockHeaderToken: IGetToken = { - len: 32, - - get: (buf, off) => { - - const flags = Token.UINT32_LE.get(buf, off + 24); - - const res = { - // should equal 'wvpk' - BlockID: FourCcToken.get(buf, off), - // 0x402 to 0x410 are valid for decode - blockSize: Token.UINT32_LE.get(buf, off + 4), - // 0x402 (1026) to 0x410 are valid for decode - version: Token.UINT16_LE.get(buf, off + 8), - // 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length) - totalSamples: /* replace with bigint? (Token.UINT8.get(buf, off + 11) << 32) + */ Token.UINT32_LE.get(buf, off + 12), - // 40-bit block_index - blockIndex: /* replace with bigint? (Token.UINT8.get(buf, off + 10) << 32) + */ Token.UINT32_LE.get(buf, off + 16), - // 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length) - blockSamples: Token.UINT32_LE.get(buf, off + 20), - // various flags for id and decoding - flags: { - bitsPerSample: (1 + WavPack.getBitAllignedNumber(flags, 0, 2)) * 8, - isMono: WavPack.isBitSet(flags, 2), - isHybrid: WavPack.isBitSet(flags, 3), - isJointStereo: WavPack.isBitSet(flags, 4), - crossChannel: WavPack.isBitSet(flags, 5), - hybridNoiseShaping: WavPack.isBitSet(flags, 6), - floatingPoint: WavPack.isBitSet(flags, 7), - samplingRate: SampleRates[WavPack.getBitAllignedNumber(flags, 23, 4)], - isDSD: WavPack.isBitSet(flags, 31) - }, - // crc for actual decoded data - crc: new Token.Uint8ArrayType(4).get(buf, off + 28) - }; - - if (res.flags.isDSD) { - res.totalSamples *= 8; - } - - return res; +/** + * WavPack Block Header + * + * 32-byte little-endian header at the front of every WavPack block + * + * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 2/6: 2.0 "Block Header") + */ +export const BlockHeaderToken: IGetToken = { + len: 32, + + get: (buf, off) => { + + const flags = Token.UINT32_LE.get(buf, off + 24); + + const res = { + // should equal 'wvpk' + BlockID: FourCcToken.get(buf, off), + // 0x402 to 0x410 are valid for decode + blockSize: Token.UINT32_LE.get(buf, off + 4), + // 0x402 (1026) to 0x410 are valid for decode + version: Token.UINT16_LE.get(buf, off + 8), + // 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length) + totalSamples: /* replace with bigint? (Token.UINT8.get(buf, off + 11) << 32) + */ Token.UINT32_LE.get(buf, off + 12), + // 40-bit block_index + blockIndex: /* replace with bigint? (Token.UINT8.get(buf, off + 10) << 32) + */ Token.UINT32_LE.get(buf, off + 16), + // 40-bit total samples for entire file (if block_index == 0 and a value of -1 indicates an unknown length) + blockSamples: Token.UINT32_LE.get(buf, off + 20), + // various flags for id and decoding + flags: { + bitsPerSample: (1 + getBitAllignedNumber(flags, 0, 2)) * 8, + isMono: isBitSet(flags, 2), + isHybrid: isBitSet(flags, 3), + isJointStereo: isBitSet(flags, 4), + crossChannel: isBitSet(flags, 5), + hybridNoiseShaping: isBitSet(flags, 6), + floatingPoint: isBitSet(flags, 7), + samplingRate: SampleRates[getBitAllignedNumber(flags, 23, 4)], + isDSD: isBitSet(flags, 31) + }, + // crc for actual decoded data + crc: new Token.Uint8ArrayType(4).get(buf, off + 28) + }; + + if (res.flags.isDSD) { + res.totalSamples *= 8; } - }; - /** - * 3.0 Metadata Sub-Blocks - * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block") - */ - public static MetadataIdToken: IGetToken = { - len: 1, + return res; + } +}; - get: (buf, off) => { +/** + * 3.0 Metadata Sub-Blocks + * Ref: http://www.wavpack.com/WavPack5FileFormat.pdf (page 4/6: 3.0 "Metadata Sub-Block") + */ + export const MetadataIdToken: IGetToken = { + len: 1, - return { - functionId: WavPack.getBitAllignedNumber(buf[off], 0, 6), // functionId overlaps with isOptional flag - isOptional: WavPack.isBitSet(buf[off], 5), - isOddSize: WavPack.isBitSet(buf[off], 6), - largeBlock: WavPack.isBitSet(buf[off], 7) - }; - } - }; + get: (buf, off) => { - private static isBitSet(flags: number, bitOffset: number): boolean { - return WavPack.getBitAllignedNumber(flags, bitOffset, 1) === 1; + return { + functionId: getBitAllignedNumber(buf[off], 0, 6), // functionId overlaps with isOptional flag + isOptional: isBitSet(buf[off], 5), + isOddSize: isBitSet(buf[off], 6), + largeBlock: isBitSet(buf[off], 7) + }; } +}; - private static getBitAllignedNumber(flags: number, bitOffset: number, len: number): number { - return (flags >>> bitOffset) & (0xffffffff >>> (32 - len)); - } +function isBitSet(flags: number, bitOffset: number): boolean { + return getBitAllignedNumber(flags, bitOffset, 1) === 1; +} + +function getBitAllignedNumber(flags: number, bitOffset: number, len: number): number { + return (flags >>> bitOffset) & (0xffffffff >>> (32 - len)); } + diff --git a/package.json b/package.json index ee6ff7cd2..4dd26550d 100644 --- a/package.json +++ b/package.json @@ -84,12 +84,11 @@ "compile-test": "tsc -p test", "compile-doc": "tsc -p doc-gen", "compile": "yarn run compile-src && yarn compile-test && yarn compile-doc", - "eslint": "eslint lib test doc-gen", + "lint-ts": "biome check", "lint-md": "yarn run remark -u preset-lint-markdown-style-guide .", - "lint": "yarn run lint-md && yarn run eslint", + "lint": "yarn run lint-ts && yarn run lint-md", "test": "mocha", "build": "yarn run clean && yarn compile && yarn run doc-gen", - "start": "yarn run compile && yarn run lint && yarn run cover-test", "test-coverage": "c8 yarn run test", "send-codacy": "c8 report --reporter=text-lcov | codacy-coverage", "doc-gen": "yarn node doc-gen/gen.js" @@ -105,28 +104,17 @@ "uint8array-extras": "^1.4.0" }, "devDependencies": { - "@eslint/compat": "^1.1.1", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.7.0", + "@biomejs/biome": "1.8.3", "@types/chai": "^4.3.16", "@types/chai-as-promised": "^7.1.8", "@types/debug": "^4.1.12", + "@types/media-typer": "^1.1.3", "@types/mocha": "^10.0.7", "@types/node": "^22.1.0", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", "c8": "^10.1.2", "chai": "^5.1.1", "chai-as-promised": "^8.0.0", "del-cli": "^5.1.0", - "eslint": "^9.7.0", - "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsdoc": "^48.7.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-unicorn": "^55.0.0", - "globals": "^15.8.0", "mime": "^4.0.4", "mocha": "^10.6.0", "prettier": "^3.3.3", diff --git a/test/http-client.ts b/test/http-client.ts new file mode 100644 index 000000000..e69de29bb diff --git a/test/metadata-parsers.ts b/test/metadata-parsers.ts index c0cd1aef5..116ed42e3 100644 --- a/test/metadata-parsers.ts +++ b/test/metadata-parsers.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import * as mm from '../lib/index.js'; -import { IAudioMetadata, IOptions } from '../lib/index.js'; +import type { IAudioMetadata, IOptions } from '../lib/index.js'; type ParseFileMethod = (skipTest: () => void, filePath: string, mimeType?: string, options?: IOptions) => Promise; diff --git a/test/test-common.ts b/test/test-common.ts index 858a34dee..1d915e7ad 100644 --- a/test/test-common.ts +++ b/test/test-common.ts @@ -22,7 +22,7 @@ describe('GenericTagMap', () => { const tagMapper = combinedTagMapper.tagMappers[nativeType]; for (const nativeTag in tagMapper.tagMap) { const commonType = tagMapper.tagMap[nativeTag]; - assert.isDefined(commonTags[commonType], 'Unknown common tagTypes in mapping ' + nativeType + '.' + nativeTag + ' => ' + commonType); + assert.isDefined(commonTags[commonType], `Unknown common tagTypes in mapping ${nativeType}.${nativeTag} => ${commonType}`); } } }); diff --git a/test/test-concurrent-picture.ts b/test/test-concurrent-picture.ts index a7eac6c8d..91a7d8b6a 100644 --- a/test/test-concurrent-picture.ts +++ b/test/test-concurrent-picture.ts @@ -10,9 +10,9 @@ it("should handle concurrent parsing of pictures", () => { const files = [path.join(samplePath, 'flac.flac'), path.join(samplePath, 'flac-bug.flac')]; - return Promise.all(files.map(file => { + return Promise.all(files.map(file => { return mm.parseFile(file).then(result => { - const data = fs.readFileSync(file + '.jpg'); + const data = fs.readFileSync(`${file}.jpg`); t.deepEqual(result.common.picture[0].data, data, 'check picture'); }); })); diff --git a/test/test-discogs.ts b/test/test-discogs.ts index 4582877ba..f3d0f034b 100644 --- a/test/test-discogs.ts +++ b/test/test-discogs.ts @@ -32,8 +32,8 @@ describe('Discogs mappings', () => { // Each Discogs tag should be mapped for (const tag of discogs_tags) { - const tagName = 'TXXX:' + tag; - assert.isDefined(mapper.tagMap[tagName], 'Discogs/ID3v2.4 tag: ' + tagName); + const tagName = `TXXX:${tag}`; + assert.isDefined(mapper.tagMap[tagName], `Discogs/ID3v2.4 tag: ${tagName}`); } }); @@ -43,7 +43,7 @@ describe('Discogs mappings', () => { // Each Discogs tag should be mapped for (const tag of discogs_tags) { - assert.isDefined(mapper.tagMap[tag], 'Discog/Vorbis tag: ' + tag); + assert.isDefined(mapper.tagMap[tag], `Discog/Vorbis tag: ${tag}`); } }); }); @@ -63,39 +63,39 @@ describe('Discogs mappings', () => { // Check discogs, DISCOGS_RELEASE_ID tagName = getTagName('DISCOGS_RELEASE_ID'); - assert.deepEqual(native[tagName], ['4204665'], tagType + '/' + tagName); - assert.strictEqual(common.discogs_release_id, 4204665, +tagType + '/' + tagName + ' => common.discogs_release_id'); + assert.deepEqual(native[tagName], ['4204665'], `${tagType}/${tagName}`); + assert.strictEqual(common.discogs_release_id, 4204665, `${+tagType}/${tagName} => common.discogs_release_id`); // Check Discogs-tag: DISCOGS_ARTIST_ID tagName = getTagName('DISCOGS_ARTIST_ID'); - assert.deepEqual(native[tagName], ['389157', '900313'], tagType + '/' + tagName); - assert.deepEqual(common.discogs_artist_id, [389157, 900313], tagType + '/' + tagName + ' => common.discogs_artist_id'); + assert.deepEqual(native[tagName], ['389157', '900313'], `${tagType}/${tagName}`); + assert.deepEqual(common.discogs_artist_id, [389157, 900313], `${tagType}/${tagName} => common.discogs_artist_id`); // Check Discogs-tag: DISCOGS_ALBUM_ARTISTS tagName = getTagName('DISCOGS_ALBUM_ARTISTS'); - assert.deepEqual(native[tagName], ['Beth Hart', 'Joe Bonamassa'], tagType + '/' + tagName); - assert.deepEqual(common.artists, ['Beth Hart', 'Joe Bonamassa'], tagType + '/' + tagName + ' => common.artists'); + assert.deepEqual(native[tagName], ['Beth Hart', 'Joe Bonamassa'], `${tagType}/${tagName}`); + assert.deepEqual(common.artists, ['Beth Hart', 'Joe Bonamassa'], `${tagType}/${tagName} => common.artists`); // Check Discogs-tag: DISCOGS_VOTES tagName = getTagName('DISCOGS_VOTES'); - assert.deepEqual(native[tagName], ['9'], tagType + '/' + tagName); - assert.deepEqual(common.discogs_votes, 9, tagType + '/' + tagName + ' => common.discogs_votes'); + assert.deepEqual(native[tagName], ['9'], `${tagType}/${tagName}`); + assert.deepEqual(common.discogs_votes, 9, `${tagType}/${tagName} => common.discogs_votes`); // Check Discogs-tag: STYLE tagName = getTagName('STYLE'); - assert.deepEqual(native[tagName], ['Blues Rock'], tagType + '/' + tagName); + assert.deepEqual(native[tagName], ['Blues Rock'], `${tagType}/${tagName}`); switch (tagType) { case 'id3v23': - assert.deepEqual(common.genre, ['Rock;Blues', 'Blues Rock'], tagType + '/' + tagName + ' => common.genre'); - assert.deepEqual(native.TCON, ['Rock;Blues'], tagType + '/TCON'); // ToDo: why different in Vorbis + assert.deepEqual(common.genre, ['Rock;Blues', 'Blues Rock'], `${tagType}/${tagName} => common.genre`); + assert.deepEqual(native.TCON, ['Rock;Blues'], `${tagType}/TCON`); // ToDo: why different in Vorbis break; case 'vorbis': - assert.deepEqual(common.genre, ['Rock', 'Blues', 'Blues Rock'], tagType + '/' + tagName + ' => common.genre'); - assert.deepEqual(native.GENRE, ['Rock', 'Blues'], tagType + '/GENRE'); - assert.deepEqual(native.STYLE, ['Blues Rock'], tagType + '/STYLE'); + assert.deepEqual(common.genre, ['Rock', 'Blues', 'Blues Rock'], `${tagType}/${tagName} => common.genre`); + assert.deepEqual(native.GENRE, ['Rock', 'Blues'], `${tagType}/GENRE`); + assert.deepEqual(native.STYLE, ['Blues Rock'], `${tagType}/STYLE`); break; } } @@ -186,41 +186,41 @@ describe('Discogs mappings', () => { // Each Discogs tag should be mapped for (const tag of discogs_tags_found) { - assert.isTrue(discogs_tags.indexOf(tag) !== -1, 'Discog/Vorbis tag: ' + tag); + assert.isTrue(discogs_tags.indexOf(tag) !== -1, `Discog/Vorbis tag: ${tag}`); } - let tagName; + let tagName: string; // Check Discogs-tag: DISCOGS_RELEASE_ID tagName = getTagName('DISCOGS_RELEASE_ID'); - assert.deepEqual(native[tagName], ['3520814'], tagType + '/' + tagName); - assert.deepEqual(common.discogs_release_id, 3520814, tagType + '/' + tagName + ' => common.discogs_release_id'); + assert.deepEqual(native[tagName], ['3520814'], `${tagType}/${tagName}`); + assert.deepEqual(common.discogs_release_id, 3520814, `${tagType}/${tagName} => common.discogs_release_id`); // Check Discogs-tag: DISCOGS_MASTER_RELEASE_ID tagName = getTagName('DISCOGS_MASTER_RELEASE_ID'); - assert.deepEqual(native[tagName], ['461710'], tagType + '/' + tagName); - assert.deepEqual(common.discogs_master_release_id, 461710, tagType + '/' + tagName + ' => common.discogs_master_release_id'); + assert.deepEqual(native[tagName], ['461710'], `${tagType}/${tagName}`); + assert.deepEqual(common.discogs_master_release_id, 461710, `${tagType}/${tagName} => common.discogs_master_release_id`); // Check Discogs-tag: DISCOGS_ARTIST_ID tagName = getTagName('DISCOGS_ARTIST_ID'); - assert.deepEqual(native[tagName], ['467650'], tagType + '/' + tagName); - assert.deepEqual(common.discogs_artist_id, [467650], tagType + '/' + tagName + ' => common.discogs_artist_id'); + assert.deepEqual(native[tagName], ['467650'], `${tagType}/${tagName}`); + assert.deepEqual(common.discogs_artist_id, [467650], `${tagType}/${tagName} => common.discogs_artist_id`); // tagName = getTagName("DISCOGS_ALBUM_ARTISTS"); // t.deepEqual(native[tagName], ["Yasmin Levy"], tagType + "/" + tagName); // t.deepEqual(common.artists, ["Yasmin Levy", "Yasmin Levy"], tagType + "/" + tagName + " => common.artists"); // ToDo? remove duplicates // Check Discogs-tag: DISCOGS_ARTIST_NAME ToDo: test multiple artists tagName = getTagName('DISCOGS_ARTIST_NAME'); - assert.deepEqual(native[tagName], ['Yasmin Levy'], tagType + '/' + tagName); - assert.deepEqual(common.artists, ['Yasmin Levy'], tagType + '/' + tagName + ' => common.artists'); // ToDo? remove duplicates + assert.deepEqual(native[tagName], ['Yasmin Levy'], `${tagType}/${tagName}`); + assert.deepEqual(common.artists, ['Yasmin Levy'], `${tagType}/${tagName} => common.artists`); // ToDo? remove duplicates // Check Discogs-tag: DISCOGS_DATE tagName = getTagName('DISCOGS_DATE'); - assert.deepEqual(native[tagName], ['2009'], tagType + '/' + tagName); + assert.deepEqual(native[tagName], ['2009'], `${tagType}/${tagName}`); // ToDo? t.deepEqual(common.originaldate, "2009", "Vorbis/DISCOGS_DATE: => common.originaldate"); // Check Discogs: DISCOGS_CATALOG tagName = getTagName('DISCOGS_CATALOG'); - assert.deepEqual(native[tagName], ['450010'], tagType + '/' + tagName); - assert.deepEqual(common.catalognumber, ['450010'], tagType + '/' + tagName + ' => common.catalognumber'); + assert.deepEqual(native[tagName], ['450010'], `${tagType}/${tagName}`); + assert.deepEqual(common.catalognumber, ['450010'], `${tagType}/${tagName} => common.catalognumber`); } diff --git a/test/test-file-aac.ts b/test/test-file-aac.ts index 8f71cc064..708d612f1 100644 --- a/test/test-file-aac.ts +++ b/test/test-file-aac.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { Parsers } from './metadata-parsers.js'; -import { IFormat } from '../lib/index.js'; +import type { IFormat } from '../lib/index.js'; import { samplePath } from './util.js'; const aacSamplePath = path.join(samplePath, 'aac'); @@ -22,7 +22,7 @@ describe('Parse ADTS/AAC', () => { assert.approximately(format.duration, samples / sampleRate, 0.1, 'format.duration'); } - describe('parse: adts-mpeg4.aac AAC-LC, 16.0 kHz, 2 channels, 3 kBit', function(){ + describe('parse: adts-mpeg4.aac AAC-LC, 16.0 kHz, 2 channels, 3 kBit', ()=> { Parsers.forEach(parser => { it(parser.description, async function (){ diff --git a/test/test-file-ape.ts b/test/test-file-ape.ts index d767cffa6..e89f39068 100644 --- a/test/test-file-ape.ts +++ b/test/test-file-ape.ts @@ -4,6 +4,7 @@ import path from 'node:path'; import * as mm from '../lib/index.js'; import { Parsers } from './metadata-parsers.js'; import { samplePath } from './util.js'; +import type { IPicture } from '../lib/index.js'; describe('Parse APE (Monkey\'s Audio)', () => { @@ -34,8 +35,8 @@ describe('Parse APE (Monkey\'s Audio)', () => { function checkNative(ape: mm.INativeTagDict) { assert.deepEqual(ape.ENSEMBLE, ['Audioslave']); assert.deepEqual(ape.Artist, ['Audioslave', 'Chris Cornell']); - assert.strictEqual(ape['Cover Art (Front)'][0].data.length, 48658, 'raw cover art (front) length'); - assert.strictEqual(ape['Cover Art (Back)'][0].data.length, 48658, 'raw cover art (front) length'); + assert.strictEqual((ape['Cover Art (Front)'][0] as IPicture).data.length, 48658, 'raw cover art (front) length'); + assert.strictEqual((ape['Cover Art (Back)'][0] as IPicture).data.length, 48658, 'raw cover art (front) length'); } Parsers.forEach(parser => { diff --git a/test/test-file-asf.ts b/test/test-file-asf.ts index 52c927599..9b76d6453 100644 --- a/test/test-file-asf.ts +++ b/test/test-file-asf.ts @@ -2,11 +2,12 @@ import { assert } from 'chai'; import * as mm from '../lib/index.js'; import path from 'node:path'; import GUID from '../lib/asf/GUID.js'; -import { AsfUtil } from '../lib/asf/AsfUtil.js'; +import { getParserForAttr } from '../lib/asf/AsfUtil.js'; import { DataType } from '../lib/asf/AsfObject.js'; import { Parsers } from './metadata-parsers.js'; import { samplePath } from './util.js'; +import type { IPicture } from '../lib/index.js'; describe('Parse ASF', () => { @@ -69,7 +70,7 @@ describe('Parse ASF', () => { tests.forEach(test => { const buf = Uint8Array.from(test.raw); - assert.strictEqual(Number(AsfUtil.getParserForAttr(DataType.QWord)(buf)), test.expected, test.description); + assert.strictEqual(Number(getParserForAttr(DataType.QWord)(buf)), test.expected, test.description); }); }); @@ -128,7 +129,7 @@ describe('Parse ASF', () => { const asf = mm.orderTags(metadata.native.asf); assert.exists(asf['WM/Picture'][0], 'ASF WM/Picture should be set'); const nativePicture = asf['WM/Picture'][0]; - assert.exists(nativePicture.data); + assert.exists((nativePicture as IPicture).data); }); }); diff --git a/test/test-file-mpeg.ts b/test/test-file-mpeg.ts index b4f5a8537..b33bf900e 100644 --- a/test/test-file-mpeg.ts +++ b/test/test-file-mpeg.ts @@ -6,6 +6,7 @@ import { samplePath, SourceStream } from './util.js'; import { ID3v24TagMapper } from '../lib/id3v2/ID3v24TagMapper.js'; import { Parsers } from './metadata-parsers.js'; import * as mm from '../lib/index.js'; +import type { IPopularimeter } from '../lib/id3v2/FrameParser.js'; const t = assert; @@ -284,15 +285,15 @@ describe('Parse MPEG', () => { it('check mapping function', () => { - assert.deepEqual(ID3v24TagMapper.toRating({email: 'user1@bla.com', rating: 0}), { + assert.deepEqual(ID3v24TagMapper.toRating({email: 'user1@bla.com', rating: 0} as IPopularimeter), { source: 'user1@bla.com', rating: undefined }, 'unknown rating'); - assert.deepEqual(ID3v24TagMapper.toRating({email: 'user1@bla.com', rating: 1}), { + assert.deepEqual(ID3v24TagMapper.toRating({email: 'user1@bla.com', rating: 1} as IPopularimeter), { source: 'user1@bla.com', rating: 0 / 255 }, 'lowest rating'); - assert.deepEqual(ID3v24TagMapper.toRating({email: 'user1@bla.com', rating: 255}), { + assert.deepEqual(ID3v24TagMapper.toRating({email: 'user1@bla.com', rating: 255} as IPopularimeter), { source: 'user1@bla.com', rating: 1 }, 'highest rating'); diff --git a/test/test-file-wav.ts b/test/test-file-wav.ts index 4b9cc2721..9202dd6db 100644 --- a/test/test-file-wav.ts +++ b/test/test-file-wav.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import * as mm from '../lib/index.js'; import { samplePath } from './util.js'; -import { IFormat, INativeTagDict } from '../lib/index.js'; +import type { IFormat, INativeTagDict } from '../lib/index.js'; const wavSamples = path.join(samplePath, 'wav'); diff --git a/test/test-http.ts b/test/test-http.ts index 0e74def17..0d67db358 100644 --- a/test/test-http.ts +++ b/test/test-http.ts @@ -13,7 +13,7 @@ describe('HTTP streaming', function() { this.timeout(15 * 1000); this.retries(3); // Workaround for HTTP time-outs on Travis-CI - describe(`Stream HTTP using fetch()`, () => { + describe("Stream HTTP using fetch()", () => { [true, false].forEach(hasContentLength => { diff --git a/test/test-id3v2.3.ts b/test/test-id3v2.3.ts index b6f2d4266..b6584531c 100644 --- a/test/test-id3v2.3.ts +++ b/test/test-id3v2.3.ts @@ -7,6 +7,8 @@ import { MetadataCollector } from '../lib/common/MetadataCollector.js'; import * as mm from '../lib/index.js'; import { samplePath } from './util.js'; import { LyricsContentType, TimestampFormat, type ILyricsTag } from '../lib/core.js'; +import type { IPicture } from '../lib/index.js'; +import type { IGeneralEncapsulatedObject } from '../lib/id3v2/FrameParser.js'; describe('Extract metadata from ID3v2.3 header', () => { @@ -82,7 +84,7 @@ describe('Extract metadata from ID3v2.3 header', () => { assert.deepEqual(id3v23['TXXX:PERFORMER'], ['Explosions In The Sky'], 'native: TXXX:PERFORMER'); assert.deepEqual(id3v23['TXXX:PERFORMER'], ['Explosions In The Sky'], 'native: TXXX:PERFORMER'); - const apic = id3v23.APIC[0]; + const apic = id3v23.APIC[0] as IPicture; assert.strictEqual(apic.format, 'image/jpeg', 'raw APIC format'); assert.strictEqual(apic.type, 'Cover (front)', 'raw APIC tagTypes'); assert.strictEqual(apic.description, '', 'raw APIC description'); @@ -254,7 +256,7 @@ describe('Extract metadata from ID3v2.3 header', () => { it('4.5 MCDI: Music CD identifier', async () => { const metadata = await mm.parseFile(path.join(samplePath, '04-Strawberry.mp3')); const id3v23 = mm.orderTags(metadata.native['ID3v2.3']); - assert.equal(id3v23.MCDI[0].length, 804, 'TOC'); + assert.equal((id3v23.MCDI[0] as string).length, 804, 'TOC'); }); // https://id3.org/id3v2.3.0#Unsychronised_lyrics.2Ftext_transcription @@ -364,9 +366,10 @@ describe('Extract metadata from ID3v2.3 header', () => { assert.isDefined(native['ID3v2.3'], 'Presence of ID3v2.3 tag header'); const id3v2 = mm.orderTags(native['ID3v2.3']); - assert.deepEqual(id3v2.GEOB[0].type, 'application/octet-stream', 'ID3v2.GEOB[0].type'); - assert.deepEqual(id3v2.GEOB[0].filename, '', 'ID3v2.GEOB[0].filename'); - assert.deepEqual(id3v2.GEOB[0].description, 'Serato Overview', 'ID3v2.GEOB[0].description'); + const geob = id3v2.GEOB[0] as IGeneralEncapsulatedObject; + assert.deepEqual(geob.type, 'application/octet-stream', 'ID3v2.GEOB[0].type'); + assert.deepEqual(geob.filename, '', 'ID3v2.GEOB[0].filename'); + assert.deepEqual(geob.description, 'Serato Overview', 'ID3v2.GEOB[0].description'); }); it('4.18 POPM', async () => { @@ -385,11 +388,11 @@ describe('Extract metadata from ID3v2.3 header', () => { const filePath = path.join(samplePath, 'rating', testCaseFile.file); const {common} = await mm.parseFile(filePath); if (common.rating === undefined) { - assert.isUndefined(common.rating, 'Expect no rating property to be present in: ' + testCaseFile.file); + assert.isUndefined(common.rating, `Expect no rating property to be present in: ${testCaseFile.file}`); } else { - assert.isDefined(common.rating, 'Expect rating property to be present in: ' + testCaseFile.file); - assert.equal(Math.round(common.rating[0].rating * 4 + 1), testCaseFile.stars, 'ID3v2.3 rating conversion in: ' + testCaseFile.file); - assert.equal(mm.ratingToStars(common.rating[0].rating), testCaseFile.stars, 'ID3v2.3 rating conversion in: ' + testCaseFile.file); + assert.isDefined(common.rating, `Expect rating property to be present in: ${testCaseFile.file}`); + assert.equal(Math.round(common.rating[0].rating * 4 + 1), testCaseFile.stars, `ID3v2.3 rating conversion in: ${testCaseFile.file}`); + assert.equal(mm.ratingToStars(common.rating[0].rating), testCaseFile.stars, `ID3v2.3 rating conversion in: ${testCaseFile.file}`); } } }); diff --git a/test/test-id3v2.4-musicbrainz.ts b/test/test-id3v2.4-musicbrainz.ts index 1eaa93d0d..c143c243a 100644 --- a/test/test-id3v2.4-musicbrainz.ts +++ b/test/test-id3v2.4-musicbrainz.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import * as mm from '../lib/index.js'; import { samplePath } from './util.js'; +import type { IPicture } from '../lib/index.js'; it('should MusicBrainz tags with id3v2.4', async () => { @@ -58,10 +59,11 @@ it('should MusicBrainz tags with id3v2.4', async () => { { const picTag = native[i++]; assert.strictEqual(picTag.id, 'APIC', '[\'ID3v2.4\'].APIC #1'); - assert.deepEqual(picTag.value.format, 'image/jpeg', '[\'ID3v2.4\'].APIC #1 format'); - assert.deepEqual(picTag.value.type, 'Cover (front)', '[\'ID3v2.4\'].APIC #1 tagTypes'); - assert.deepEqual(picTag.value.description, '', '[\'ID3v2.4\'].APIC #1 description'); - assert.deepEqual(picTag.value.data.length, 75818, '[\'ID3v2.4\'].APIC #1 length'); + const pic = picTag.value as IPicture; + assert.deepEqual(pic.format, 'image/jpeg', '[\'ID3v2.4\'].APIC #1 format'); + assert.deepEqual(pic.type, 'Cover (front)', '[\'ID3v2.4\'].APIC #1 tagTypes'); + assert.deepEqual(pic.description, '', '[\'ID3v2.4\'].APIC #1 description'); + assert.deepEqual(pic.data.length, 75818, '[\'ID3v2.4\'].APIC #1 length'); } assert.deepEqual(native[i++], { diff --git a/test/test-mime.ts b/test/test-mime.ts index f3b60ea44..8c63e3003 100644 --- a/test/test-mime.ts +++ b/test/test-mime.ts @@ -23,7 +23,7 @@ describe('MIME & extension mapping', () => { break; default: - throw new Error('caught error parsing ' + extension + ': ' + err.message); + throw new Error(`caught error parsing ${extension}: ${err.message}`); } } @@ -43,7 +43,7 @@ describe('MIME & extension mapping', () => { const streamReader = new SourceStream(buf); // Convert extension to MIME-Type const mimeType = mime.getType(extension); - assert.isNotNull(mimeType, 'extension: ' + extension); + assert.isNotNull(mimeType, `extension: ${extension}`); return mm.parseStream(streamReader, mimeType) .catch(err => { diff --git a/test/test-picard-mappings.ts b/test/test-picard-mappings.ts index fbd7f0db7..f3ec7c381 100644 --- a/test/test-picard-mappings.ts +++ b/test/test-picard-mappings.ts @@ -93,8 +93,8 @@ describe('Picard mapping coverage', () => { const picNativeTag = PicardMappings[picComTag]; const mmCommonTag = convertName(picComTag); - assert.isDefined(asfTagMapper.tagMap[picNativeTag], 'Is \'' + picNativeTag + '\' defined?'); - assert.equal(asfTagMapper.tagMap[picNativeTag], mmCommonTag, 'Check Picard mapping for ' + picNativeTag); + assert.isDefined(asfTagMapper.tagMap[picNativeTag], `Is \'${picNativeTag}\' defined?`); + assert.equal(asfTagMapper.tagMap[picNativeTag], mmCommonTag, `Check Picard mapping for ${picNativeTag}`); } }); @@ -128,8 +128,8 @@ describe('Picard mapping coverage', () => { const picComTag = PicardMappings[picNativeTag]; const mmCommonTag = convertName(picComTag); - assert.isDefined(apeTagMapper.tagMap[picNativeTag.toUpperCase()], 'Is \'' + picNativeTag + '\' defined?'); - assert.equal(apeTagMapper.tagMap[picNativeTag.toUpperCase()], mmCommonTag, 'Check Picard mapping for ' + picNativeTag); + assert.isDefined(apeTagMapper.tagMap[picNativeTag.toUpperCase()], `Is \'${picNativeTag}\' defined?`); + assert.equal(apeTagMapper.tagMap[picNativeTag.toUpperCase()], mmCommonTag, `Check Picard mapping for ${picNativeTag}`); } }); @@ -187,8 +187,8 @@ describe('Picard mapping coverage', () => { const picComTag = PicardMappings[picNativeTag]; const mmCommonTag = convertName(picComTag); - assert.isDefined(id3v24TagMapper.tagMap[picNativeTag], 'Is \'' + picNativeTag + '\' defined?'); - assert.equal(id3v24TagMapper.tagMap[picNativeTag], mmCommonTag, 'Check Picard mapping for ' + picNativeTag); + assert.isDefined(id3v24TagMapper.tagMap[picNativeTag], `Is \'${picNativeTag}\' defined?`); + assert.equal(id3v24TagMapper.tagMap[picNativeTag], mmCommonTag, `Check Picard mapping for ${picNativeTag}`); } }); diff --git a/test/test-picard-parsing.ts b/test/test-picard-parsing.ts index a6476938b..09b7c3e2f 100644 --- a/test/test-picard-parsing.ts +++ b/test/test-picard-parsing.ts @@ -1,10 +1,10 @@ /* eslint-disable dot-notation, @typescript-eslint/dot-notation */ import { assert } from 'chai'; import path from 'node:path'; -import * as crypto from 'crypto'; +import * as crypto from 'node:crypto'; -import { TagType } from '../lib/common/GenericTagTypes.js'; -import { ICommonTagsResult, IFormat, INativeTagDict, parseFile, orderTags } from '../lib/index.js'; +import type { TagType } from '../lib/common/GenericTagTypes.js'; +import { type ICommonTagsResult, type IFormat, type INativeTagDict, parseFile, orderTags, type IPicture } from '../lib/index.js'; import { samplePath } from './util.js'; /** @@ -54,55 +54,55 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { */ function checkCommonMapping(inputTagType: TagType, common: ICommonTagsResult) { // Compare expectedCommonTags with result.common - assert.strictEqual(common.title, 'Sinner\'s Prayer', inputTagType + ' => common.title'); - assert.strictEqual(common.artist, 'Beth Hart & Joe Bonamassa', inputTagType + ' => common.artist'); + assert.strictEqual(common.title, 'Sinner\'s Prayer', `${inputTagType} => common.title`); + assert.strictEqual(common.artist, 'Beth Hart & Joe Bonamassa', `${inputTagType} => common.artist`); if (inputTagType === 'asf') { - assert.deepEqual(common.artists, ['Joe Bonamassa', 'Beth Hart'], inputTagType + ' => common.artists'); - assert.deepEqual(common.musicbrainz_artistid, ['984f8239-8fe1-4683-9c54-10ffb14439e9', '3fe817fc-966e-4ece-b00a-76be43e7e73c'], inputTagType + ' => common.musicbrainz_artistid'); + assert.deepEqual(common.artists, ['Joe Bonamassa', 'Beth Hart'], `${inputTagType} => common.artists`); + assert.deepEqual(common.musicbrainz_artistid, ['984f8239-8fe1-4683-9c54-10ffb14439e9', '3fe817fc-966e-4ece-b00a-76be43e7e73c'], `${inputTagType} => common.musicbrainz_artistid`); } else { - assert.deepEqual(common.artists, ['Beth Hart', 'Joe Bonamassa'], inputTagType + ' => common.artists'); - assert.deepEqual(common.musicbrainz_artistid, ['3fe817fc-966e-4ece-b00a-76be43e7e73c', '984f8239-8fe1-4683-9c54-10ffb14439e9'], inputTagType + ' => common.musicbrainz_artistid'); + assert.deepEqual(common.artists, ['Beth Hart', 'Joe Bonamassa'], `${inputTagType} => common.artists`); + assert.deepEqual(common.musicbrainz_artistid, ['3fe817fc-966e-4ece-b00a-76be43e7e73c', '984f8239-8fe1-4683-9c54-10ffb14439e9'], `${inputTagType} => common.musicbrainz_artistid`); } assert.strictEqual(common.albumartist, 'Beth Hart & Joe Bonamassa', 'common.albumartist'); // ToDo: this is not set - assert.deepEqual(common.albumartistsort, 'Hart, Beth & Bonamassa, Joe', inputTagType + ' => common.albumartistsort'); - assert.strictEqual(common.album, 'Don\'t Explain', inputTagType + ' => common.album = Don\'t Explain'); + assert.deepEqual(common.albumartistsort, 'Hart, Beth & Bonamassa, Joe', `${inputTagType} => common.albumartistsort`); + assert.strictEqual(common.album, 'Don\'t Explain', `${inputTagType} => common.album = Don\'t Explain`); if (inputTagType === 'asf') { - assert.deepEqual(common.track, {no: 1, of: null}, inputTagType + ' => common.track'); + assert.deepEqual(common.track, {no: 1, of: null}, `${inputTagType} => common.track`); } else { - assert.deepEqual(common.track, {no: 1, of: 10}, inputTagType + ' => common.track'); + assert.deepEqual(common.track, {no: 1, of: 10}, `${inputTagType} => common.track`); } - assert.deepEqual(common.disk, {no: 1, of: 1}, inputTagType + ' => common.disk'); + assert.deepEqual(common.disk, {no: 1, of: 1}, `${inputTagType} => common.disk`); if (hasOriginalData(inputTagType)) { - assert.strictEqual(common.originaldate, '2011-09-26', inputTagType + ' => common.originaldate = 2011-09-26'); + assert.strictEqual(common.originaldate, '2011-09-26', `${inputTagType} => common.originaldate = 2011-09-26`); } if (hasReleaseData(inputTagType)) { - assert.strictEqual(common.date, '2011-09-27', inputTagType + ' => common.date'); + assert.strictEqual(common.date, '2011-09-27', `${inputTagType} => common.date`); } - assert.strictEqual(common.year, 2011, inputTagType + ' => common.year'); - assert.strictEqual(common.originalyear, 2011, inputTagType + ' => common.year'); - assert.strictEqual(common.media, 'CD', inputTagType + ' => common.media = CD'); - assert.strictEqual(common.barcode, '804879313915', inputTagType + ' => common.barcode'); + assert.strictEqual(common.year, 2011, `${inputTagType} => common.year`); + assert.strictEqual(common.originalyear, 2011, `${inputTagType} => common.year`); + assert.strictEqual(common.media, 'CD', `${inputTagType} => common.media = CD`); + assert.strictEqual(common.barcode, '804879313915', `${inputTagType} => common.barcode`); // ToDo?? assert.deepEqual(common.producer, ['Roy Weisman'], 'common.producer = Roy Weisman') - assert.deepEqual(common.label, ['J&R Adventures'], inputTagType + ' => common.label = \'J&R Adventures\''); - assert.deepEqual(common.catalognumber, ['PRAR931391'], inputTagType + ' => common.catalognumber = PRAR931391'); - assert.strictEqual(common.originalyear, 2011, inputTagType + ' => common.originalyear = 2011'); - assert.strictEqual(common.releasestatus, 'official', inputTagType + ' => common.releasestatus = official'); - assert.deepEqual(common.releasetype, ['album'], inputTagType + ' => common.releasetype'); - assert.strictEqual(common.musicbrainz_albumid, 'e7050302-74e6-42e4-aba0-09efd5d431d8', inputTagType + ' => common.musicbrainz_albumid'); - assert.strictEqual(common.musicbrainz_recordingid, 'f151cb94-c909-46a8-ad99-fb77391abfb8', inputTagType + ' => common.musicbrainz_recordingid'); + assert.deepEqual(common.label, ['J&R Adventures'], `${inputTagType} => common.label = \'J&R Adventures\'`); + assert.deepEqual(common.catalognumber, ['PRAR931391'], `${inputTagType} => common.catalognumber = PRAR931391`); + assert.strictEqual(common.originalyear, 2011, `${inputTagType} => common.originalyear = 2011`); + assert.strictEqual(common.releasestatus, 'official', `${inputTagType} => common.releasestatus = official`); + assert.deepEqual(common.releasetype, ['album'], `${inputTagType} => common.releasetype`); + assert.strictEqual(common.musicbrainz_albumid, 'e7050302-74e6-42e4-aba0-09efd5d431d8', `${inputTagType} => common.musicbrainz_albumid`); + assert.strictEqual(common.musicbrainz_recordingid, 'f151cb94-c909-46a8-ad99-fb77391abfb8', `${inputTagType} => common.musicbrainz_recordingid`); if (inputTagType === 'asf') { - assert.deepEqual(common.musicbrainz_albumartistid, ['984f8239-8fe1-4683-9c54-10ffb14439e9', '3fe817fc-966e-4ece-b00a-76be43e7e73c'], inputTagType + ' => common.musicbrainz_albumartistid'); + assert.deepEqual(common.musicbrainz_albumartistid, ['984f8239-8fe1-4683-9c54-10ffb14439e9', '3fe817fc-966e-4ece-b00a-76be43e7e73c'], `${inputTagType} => common.musicbrainz_albumartistid`); } else { - assert.deepEqual(common.musicbrainz_albumartistid, ['3fe817fc-966e-4ece-b00a-76be43e7e73c', '984f8239-8fe1-4683-9c54-10ffb14439e9'], inputTagType + ' => common.musicbrainz_albumartistid'); + assert.deepEqual(common.musicbrainz_albumartistid, ['3fe817fc-966e-4ece-b00a-76be43e7e73c', '984f8239-8fe1-4683-9c54-10ffb14439e9'], `${inputTagType} => common.musicbrainz_albumartistid`); } - assert.strictEqual(common.musicbrainz_releasegroupid, 'e00305af-1c72-469b-9a7c-6dc665ca9adc', inputTagType + ' => common.musicbrainz_releasegroupid'); - assert.strictEqual(common.musicbrainz_trackid, 'd062f484-253c-374b-85f7-89aab45551c7', inputTagType + ' => common.musicbrainz_trackid'); - assert.strictEqual(common.asin, 'B005NPEUB2', inputTagType + ' => common.asin'); - assert.strictEqual(common.acoustid_id, '09c06fac-679a-45b1-8ea0-6ce532318363', inputTagType + ' => common.acoustid_id'); + assert.strictEqual(common.musicbrainz_releasegroupid, 'e00305af-1c72-469b-9a7c-6dc665ca9adc', `${inputTagType} => common.musicbrainz_releasegroupid`); + assert.strictEqual(common.musicbrainz_trackid, 'd062f484-253c-374b-85f7-89aab45551c7', `${inputTagType} => common.musicbrainz_trackid`); + assert.strictEqual(common.asin, 'B005NPEUB2', `${inputTagType} => common.asin`); + assert.strictEqual(common.acoustid_id, '09c06fac-679a-45b1-8ea0-6ce532318363', `${inputTagType} => common.acoustid_id`); // Check front cover assert.strictEqual(common.picture[0].format, 'image/jpeg', 'picture format'); @@ -170,12 +170,13 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { assert.deepEqual(vorbis.RELEASECOUNTRY, ['US'], 'vorbis.RELEASECOUNTRY'); assert.deepEqual(vorbis.RELEASESTATUS, ['official'], 'vorbis.RELEASESTATUS'); - assert.strictEqual(vorbis.METADATA_BLOCK_PICTURE[0].format, 'image/jpeg', 'vorbis.METADATA_BLOCK_PICTURE.format = \'image/jpeg\''); - assert.strictEqual(vorbis.METADATA_BLOCK_PICTURE[0].type, 'Cover (front)', 'vorbis.METADATA_BLOCK_PICTURE.type = \'Cover (front)\''); // ToDo: description?? + const picture = vorbis.METADATA_BLOCK_PICTURE[0] as IPicture; + assert.strictEqual(picture.format, 'image/jpeg', 'vorbis.METADATA_BLOCK_PICTURE.format = \'image/jpeg\''); + assert.strictEqual(picture.type, 'Cover (front)', 'vorbis.METADATA_BLOCK_PICTURE.type = \'Cover (front)\''); // ToDo: description?? - assert.strictEqual(vorbis.METADATA_BLOCK_PICTURE[0].description, '', 'vorbis.METADATA_BLOCK_PICTURE.description'); - assert.strictEqual(vorbis.METADATA_BLOCK_PICTURE[0].data.length, 98008, 'vorbis.METADATA_BLOCK_PICTURE.data.length = 98008 bytes'); - assert.strictEqual(calcHash(vorbis.METADATA_BLOCK_PICTURE[0].data), 'c57bec49b36ebf422018f82273d1995a', 'Picture content'); + assert.strictEqual(picture.description, '', 'vorbis.METADATA_BLOCK_PICTURE.description'); + assert.strictEqual(picture.data.length, 98008, 'vorbis.METADATA_BLOCK_PICTURE.data.length = 98008 bytes'); + assert.strictEqual(calcHash(picture.data), 'c57bec49b36ebf422018f82273d1995a', 'Picture content'); } it('should map FLAC/Vorbis', async () => { @@ -262,14 +263,15 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { assert.deepEqual(APEv2.Arranger, ['Jeff Bova'], 'APEv2.Arranger'); - // ToDo: - assert.deepEqual(APEv2['Cover Art (Front)'][0].format, 'image/jpeg', 'picture.format'); - assert.deepEqual(APEv2['Cover Art (Front)'][0].description, 'front', 'picture.description'); - assert.deepEqual(APEv2['Cover Art (Front)'][0].data.length, 98008, 'picture.data.length'); + const coverFront = APEv2['Cover Art (Front)'][0] as IPicture; + assert.deepEqual(coverFront.format, 'image/jpeg', 'picture.format'); + assert.deepEqual(coverFront.description, 'front', 'picture.description'); + assert.deepEqual(coverFront.data.length, 98008, 'picture.data.length'); - assert.deepEqual(APEv2['Cover Art (Back)'][0].format, 'image/png', 'picture.format'); - assert.deepEqual(APEv2['Cover Art (Back)'][0].description, 'back', 'picture.description'); - assert.deepEqual(APEv2['Cover Art (Back)'][0].data.length, 120291, 'picture.data.length'); + const coverBack = APEv2['Cover Art (Back)'][0] as IPicture; + assert.deepEqual(coverBack.format, 'image/png', 'picture.format'); + assert.deepEqual(coverBack.description, 'back', 'picture.description'); + assert.deepEqual(coverBack.data.length, 120291, 'picture.data.length'); } it('should map Monkey\'s Audio / APEv2', async () => { @@ -288,7 +290,7 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { const metadata = await parseFile(filePath); assert.isDefined(metadata, 'should return metadata'); assert.isDefined(metadata.native, 'should return metadata.native'); - assert.isDefined(metadata.native['APEv2'], 'should include native APEv2 tags'); + assert.isDefined(metadata.native.APEv2, 'should include native APEv2 tags'); checkFormat(metadata.format); checkApeTags(orderTags(metadata.native.APEv2)); checkCommonMapping('APEv2', metadata.common); @@ -310,7 +312,7 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { const metadata = await parseFile(filePath); assert.isDefined(metadata, 'should return metadata'); assert.isDefined(metadata.native, 'should return metadata.native'); - assert.isDefined(metadata.native['APEv2'], 'should include native APEv2 tags'); + assert.isDefined(metadata.native.APEv2, 'should include native APEv2 tags'); checkFormat(metadata.format); checkApeTags(orderTags(metadata.native.APEv2)); checkCommonMapping('APEv2', metadata.common); @@ -431,10 +433,11 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { function checkID3Tags(id3v24: INativeTagDict) { - assert.deepEqual(id3v24.APIC[0].data.length, 98008, 'id3v24.APIC.data.length'); - assert.deepEqual(id3v24.APIC[0].description, '', 'id3v24.APIC.data.description'); - assert.deepEqual(id3v24.APIC[0].format, 'image/jpeg', 'id3v24.APIC.format = image/jpeg'); - assert.deepEqual(id3v24.APIC[0].type, 'Cover (front)', 'd3v24.APIC.type = Cover (front)'); + const picture = id3v24.APIC[0] as IPicture; + assert.deepEqual(picture.data.length, 98008, 'id3v24.APIC.data.length'); + assert.deepEqual(picture.description, '', 'id3v24.APIC.data.description'); + assert.deepEqual(picture.format, 'image/jpeg', 'id3v24.APIC.format = image/jpeg'); + assert.deepEqual(picture.type, 'Cover (front)', 'd3v24.APIC.type = Cover (front)'); assert.deepEqual(id3v24.TALB, ['Don\'t Explain'], 'id3v24.TALB: Album/Movie/Show title'); assert.deepEqual(id3v24.TDOR, ['2011-09-26'], 'id3v24.TDOR'); diff --git a/test/test-regress-GH-56.ts b/test/test-regress-GH-56.ts index 6eaf0fc9b..f39588193 100644 --- a/test/test-regress-GH-56.ts +++ b/test/test-regress-GH-56.ts @@ -1,6 +1,6 @@ import { assert } from 'chai'; -import * as path from 'path'; +import * as path from 'node:path'; import { Parsers } from './metadata-parsers.js'; import { samplePath } from './util.js'; diff --git a/test/test-replay-gain.ts b/test/test-replay-gain.ts index 6f735eb2c..c2be02f6a 100644 --- a/test/test-replay-gain.ts +++ b/test/test-replay-gain.ts @@ -2,7 +2,7 @@ import { assert } from 'chai'; import path from 'node:path'; import * as mm from '../lib/index.js'; -import { TagType } from '../lib/common/GenericTagTypes.js'; +import type { TagType } from '../lib/common/GenericTagTypes.js'; import { samplePath } from './util.js'; interface IReplayGainSample { diff --git a/test/test-replaygain.ts b/test/test-replaygain.ts index 121aebdef..12d20f66e 100644 --- a/test/test-replaygain.ts +++ b/test/test-replaygain.ts @@ -25,7 +25,7 @@ describe('Decode replaygain tags', () => { dB: -7.03, ratio: 0.1981527025805098 }); - assert.deepEqual(toRatio('xxx'), {dB: NaN, ratio: NaN}); + assert.deepEqual(toRatio('xxx'), {dB: Number.NaN, ratio: Number.NaN}); }); it('should decode replaygain tags from FLAC/Vorbis', async () => { diff --git a/yarn.lock b/yarn.lock index 323ea6706..efa96e60b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,7 +15,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.24.5, @babel/helper-validator-identifier@npm:^7.24.7": +"@babel/helper-validator-identifier@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-validator-identifier@npm:7.24.7" checksum: 10c0/87ad608694c9477814093ed5b5c080c2e06d44cb1924ae8320474a74415241223cc2a725eea2640dd783ff1e3390e5f95eede978bc540e870053152e58f1d651 @@ -41,104 +41,103 @@ __metadata: languageName: node linkType: hard -"@cspotcode/source-map-support@npm:^0.8.0": - version: 0.8.1 - resolution: "@cspotcode/source-map-support@npm:0.8.1" +"@biomejs/biome@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/biome@npm:1.8.3" dependencies: - "@jridgewell/trace-mapping": "npm:0.3.9" - checksum: 10c0/05c5368c13b662ee4c122c7bfbe5dc0b613416672a829f3e78bc49a357a197e0218d6e74e7c66cfcd04e15a179acab080bd3c69658c9fbefd0e1ccd950a07fc6 + "@biomejs/cli-darwin-arm64": "npm:1.8.3" + "@biomejs/cli-darwin-x64": "npm:1.8.3" + "@biomejs/cli-linux-arm64": "npm:1.8.3" + "@biomejs/cli-linux-arm64-musl": "npm:1.8.3" + "@biomejs/cli-linux-x64": "npm:1.8.3" + "@biomejs/cli-linux-x64-musl": "npm:1.8.3" + "@biomejs/cli-win32-arm64": "npm:1.8.3" + "@biomejs/cli-win32-x64": "npm:1.8.3" + dependenciesMeta: + "@biomejs/cli-darwin-arm64": + optional: true + "@biomejs/cli-darwin-x64": + optional: true + "@biomejs/cli-linux-arm64": + optional: true + "@biomejs/cli-linux-arm64-musl": + optional: true + "@biomejs/cli-linux-x64": + optional: true + "@biomejs/cli-linux-x64-musl": + optional: true + "@biomejs/cli-win32-arm64": + optional: true + "@biomejs/cli-win32-x64": + optional: true + bin: + biome: bin/biome + checksum: 10c0/95fe99ce82cd8242f1be51cbf3ac26043b253f5a369d3dc24df09bdb32ec04dba679b1d4fa8b9d602b1bf2c30ecd80af14aa8f5c92d6e0cd6214a99a1099a65b languageName: node linkType: hard -"@es-joy/jsdoccomment@npm:~0.46.0": - version: 0.46.0 - resolution: "@es-joy/jsdoccomment@npm:0.46.0" - dependencies: - comment-parser: "npm:1.4.1" - esquery: "npm:^1.6.0" - jsdoc-type-pratt-parser: "npm:~4.0.0" - checksum: 10c0/a7a67936ebf6d9aaf74af018c3ac744769af3552b05ad9b88fca96b2ffdca16e724b0ff497f53634ec4cca81e98d8c471b6b6bde0fa5b725af4222ad9a0707f0 +"@biomejs/cli-darwin-arm64@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-darwin-arm64@npm:1.8.3" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.0 - resolution: "@eslint-community/eslint-utils@npm:4.4.0" - dependencies: - eslint-visitor-keys: "npm:^3.3.0" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/7e559c4ce59cd3a06b1b5a517b593912e680a7f981ae7affab0d01d709e99cd5647019be8fafa38c350305bc32f1f7d42c7073edde2ab536c745e365f37b607e +"@biomejs/cli-darwin-x64@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-darwin-x64@npm:1.8.3" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0": - version: 4.11.0 - resolution: "@eslint-community/regexpp@npm:4.11.0" - checksum: 10c0/0f6328869b2741e2794da4ad80beac55cba7de2d3b44f796a60955b0586212ec75e6b0253291fd4aad2100ad471d1480d8895f2b54f1605439ba4c875e05e523 +"@biomejs/cli-linux-arm64-musl@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-linux-arm64-musl@npm:1.8.3" + conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@eslint/compat@npm:^1.1.1": - version: 1.1.1 - resolution: "@eslint/compat@npm:1.1.1" - checksum: 10c0/ca8aa3811fa22d45913f5724978e6f3ae05fb7685b793de4797c9db3b0e22b530f0f492011b253754bffce879d7cece65762cc3391239b5d2249aef8230edc9a +"@biomejs/cli-linux-arm64@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-linux-arm64@npm:1.8.3" + conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@eslint/config-array@npm:^0.17.1": - version: 0.17.1 - resolution: "@eslint/config-array@npm:0.17.1" - dependencies: - "@eslint/object-schema": "npm:^2.1.4" - debug: "npm:^4.3.1" - minimatch: "npm:^3.1.2" - checksum: 10c0/b986a0a96f2b42467578968ce3d4ae3b9284e587f8490f2dcdc44ff1b8d30580c62b221da6e58d07b09e156c3050e2dc38267f9370521d9cafc099c4e30154ef +"@biomejs/cli-linux-x64-musl@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-linux-x64-musl@npm:1.8.3" + conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@eslint/eslintrc@npm:^3.1.0": - version: 3.1.0 - resolution: "@eslint/eslintrc@npm:3.1.0" - dependencies: - ajv: "npm:^6.12.4" - debug: "npm:^4.3.2" - espree: "npm:^10.0.1" - globals: "npm:^14.0.0" - ignore: "npm:^5.2.0" - import-fresh: "npm:^3.2.1" - js-yaml: "npm:^4.1.0" - minimatch: "npm:^3.1.2" - strip-json-comments: "npm:^3.1.1" - checksum: 10c0/5b7332ed781edcfc98caa8dedbbb843abfb9bda2e86538529c843473f580e40c69eb894410eddc6702f487e9ee8f8cfa8df83213d43a8fdb549f23ce06699167 +"@biomejs/cli-linux-x64@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-linux-x64@npm:1.8.3" + conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@eslint/js@npm:9.8.0, @eslint/js@npm:^9.7.0": - version: 9.8.0 - resolution: "@eslint/js@npm:9.8.0" - checksum: 10c0/42edaae6b020436410454579509dcb6a8cd5b260e9f18e037fd803ae28d35eb13663d4019f0ab8ba686a19d3c4a43b0e11394c148e23345377ab694da0e83262 +"@biomejs/cli-win32-arm64@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-win32-arm64@npm:1.8.3" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@eslint/object-schema@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/object-schema@npm:2.1.4" - checksum: 10c0/e9885532ea70e483fb007bf1275968b05bb15ebaa506d98560c41a41220d33d342e19023d5f2939fed6eb59676c1bda5c847c284b4b55fce521d282004da4dda +"@biomejs/cli-win32-x64@npm:1.8.3": + version: 1.8.3 + resolution: "@biomejs/cli-win32-x64@npm:1.8.3" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 - languageName: node - linkType: hard - -"@humanwhocodes/retry@npm:^0.3.0": - version: 0.3.0 - resolution: "@humanwhocodes/retry@npm:0.3.0" - checksum: 10c0/7111ec4e098b1a428459b4e3be5a5d2a13b02905f805a2468f4fa628d072f0de2da26a27d04f65ea2846f73ba51f4204661709f05bfccff645e3cedef8781bb6 +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": "npm:0.3.9" + checksum: 10c0/05c5368c13b662ee4c122c7bfbe5dc0b613416672a829f3e78bc49a357a197e0218d6e74e7c66cfcd04e15a179acab080bd3c69658c9fbefd0e1ccd950a07fc6 languageName: node linkType: hard @@ -214,7 +213,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -329,13 +328,6 @@ __metadata: languageName: node linkType: hard -"@pkgr/core@npm:^0.1.0": - version: 0.1.1 - resolution: "@pkgr/core@npm:0.1.1" - checksum: 10c0/3f7536bc7f57320ab2cf96f8973664bef624710c403357429fbf680a5c3b4843c1dbd389bb43daa6b1f6f1f007bb082f5abcb76bb2b5dc9f421647743b71d3d8 - languageName: node - linkType: hard - "@tokenizer/token@npm:^0.3.0": version: 0.3.0 resolution: "@tokenizer/token@npm:0.3.0" @@ -444,13 +436,6 @@ __metadata: languageName: node linkType: hard -"@types/json5@npm:^0.0.29": - version: 0.0.29 - resolution: "@types/json5@npm:0.0.29" - checksum: 10c0/6bf5337bc447b706bb5b4431d37686aa2ea6d07cfd6f79cc31de80170d6ff9b1c7384a9c0ccbc45b3f512bae9e9f75c2e12109806a15331dc94e8a8db6dbb4ac - languageName: node - linkType: hard - "@types/mdast@npm:^4.0.0": version: 4.0.4 resolution: "@types/mdast@npm:4.0.4" @@ -460,6 +445,13 @@ __metadata: languageName: node linkType: hard +"@types/media-typer@npm:^1.1.3": + version: 1.1.3 + resolution: "@types/media-typer@npm:1.1.3" + checksum: 10c0/bef7a51363996ce0fcbb9693bd668b1faca21e176b7d31945f558388a287560039db60dd15fe39a8c257825f8638c081ab5419089d7808ae81271dd28ee7ecf6 + languageName: node + linkType: hard + "@types/minimist@npm:^1.2.2": version: 1.2.5 resolution: "@types/minimist@npm:1.2.5" @@ -543,124 +535,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.16.1": - version: 7.18.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" - dependencies: - "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/type-utils": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" - natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^1.3.0" - peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/2b37948fa1b0dab77138909dabef242a4d49ab93e4019d4ef930626f0a7d96b03e696cd027fa0087881c20e73be7be77c942606b4a76fa599e6b37f6985304c3 - languageName: node - linkType: hard - -"@typescript-eslint/parser@npm:^7.16.1": - version: 7.18.0 - resolution: "@typescript-eslint/parser@npm:7.18.0" - dependencies: - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/370e73fca4278091bc1b657f85e7d74cd52b24257ea20c927a8e17546107ce04fbf313fec99aed0cc2a145ddbae1d3b12e9cc2c1320117636dc1281bcfd08059 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/scope-manager@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - checksum: 10c0/038cd58c2271de146b3a594afe2c99290034033326d57ff1f902976022c8b0138ffd3cb893ae439ae41003b5e4bcc00cabf6b244ce40e8668f9412cc96d97b8e - languageName: node - linkType: hard - -"@typescript-eslint/type-utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/type-utils@npm:7.18.0" - dependencies: - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.3.0" - peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/ad92a38007be620f3f7036f10e234abdc2fdc518787b5a7227e55fd12896dacf56e8b34578723fbf9bea8128df2510ba8eb6739439a3879eda9519476d5783fd - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/types@npm:7.18.0" - checksum: 10c0/eb7371ac55ca77db8e59ba0310b41a74523f17e06f485a0ef819491bc3dd8909bb930120ff7d30aaf54e888167e0005aa1337011f3663dc90fb19203ce478054 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/utils@npm:7.18.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - peerDependencies: - eslint: ^8.56.0 - checksum: 10c0/a25a6d50eb45c514469a01ff01f215115a4725fb18401055a847ddf20d1b681409c4027f349033a95c4ff7138d28c3b0a70253dfe8262eb732df4b87c547bd1e - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/538b645f8ff1d9debf264865c69a317074eaff0255e63d7407046176b0f6a6beba34a6c51d511f12444bae12a98c69891eb6f403c9f54c6c2e2849d1c1cb73c0 - languageName: node - linkType: hard - "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" @@ -668,15 +542,6 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.3.2": - version: 5.3.2 - resolution: "acorn-jsx@npm:5.3.2" - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 - languageName: node - linkType: hard - "acorn-walk@npm:^8.1.1": version: 8.3.3 resolution: "acorn-walk@npm:8.3.3" @@ -686,7 +551,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.12.0, acorn@npm:^8.4.1": +"acorn@npm:^8.11.0, acorn@npm:^8.4.1": version: 8.12.1 resolution: "acorn@npm:8.12.1" bin: @@ -724,18 +589,6 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4": - version: 6.12.6 - resolution: "ajv@npm:6.12.6" - dependencies: - fast-deep-equal: "npm:^3.1.1" - fast-json-stable-stringify: "npm:^2.0.0" - json-schema-traverse: "npm:^0.4.1" - uri-js: "npm:^4.2.2" - checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 - languageName: node - linkType: hard - "ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" @@ -792,13 +645,6 @@ __metadata: languageName: node linkType: hard -"are-docs-informative@npm:^0.0.2": - version: 0.0.2 - resolution: "are-docs-informative@npm:0.0.2" - checksum: 10c0/f0326981bd699c372d268b526b170a28f2e1aec2cf99d7de0686083528427ecdf6ae41fef5d9988e224a5616298af747ad8a76e7306b0a7c97cc085a99636d60 - languageName: node - linkType: hard - "arg@npm:^4.1.0": version: 4.1.3 resolution: "arg@npm:4.1.3" @@ -813,91 +659,6 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "array-buffer-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.5" - is-array-buffer: "npm:^3.0.4" - checksum: 10c0/f5cdf54527cd18a3d2852ddf73df79efec03829e7373a8322ef5df2b4ef546fb365c19c71d6b42d641cb6bfe0f1a2f19bc0ece5b533295f86d7c3d522f228917 - languageName: node - linkType: hard - -"array-includes@npm:^3.1.7": - version: 3.1.8 - resolution: "array-includes@npm:3.1.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - is-string: "npm:^1.0.7" - checksum: 10c0/5b1004d203e85873b96ddc493f090c9672fd6c80d7a60b798da8a14bff8a670ff95db5aafc9abc14a211943f05220dacf8ea17638ae0af1a6a47b8c0b48ce370 - languageName: node - linkType: hard - -"array-union@npm:^2.1.0": - version: 2.1.0 - resolution: "array-union@npm:2.1.0" - checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 - languageName: node - linkType: hard - -"array.prototype.findlastindex@npm:^1.2.3": - version: 1.2.5 - resolution: "array.prototype.findlastindex@npm:1.2.5" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10c0/962189487728b034f3134802b421b5f39e42ee2356d13b42d2ddb0e52057ffdcc170b9524867f4f0611a6f638f4c19b31e14606e8bcbda67799e26685b195aa3 - languageName: node - linkType: hard - -"array.prototype.flat@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flat@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10c0/a578ed836a786efbb6c2db0899ae80781b476200617f65a44846cb1ed8bd8b24c8821b83703375d8af639c689497b7b07277060024b9919db94ac3e10dc8a49b - languageName: node - linkType: hard - -"array.prototype.flatmap@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flatmap@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10c0/67b3f1d602bb73713265145853128b1ad77cc0f9b833c7e1e056b323fbeac41a4ff1c9c99c7b9445903caea924d9ca2450578d9011913191aa88cc3c3a4b54f4 - languageName: node - linkType: hard - -"arraybuffer.prototype.slice@npm:^1.0.3": - version: 1.0.3 - resolution: "arraybuffer.prototype.slice@npm:1.0.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.22.3" - es-errors: "npm:^1.2.1" - get-intrinsic: "npm:^1.2.3" - is-array-buffer: "npm:^3.0.4" - is-shared-array-buffer: "npm:^1.0.2" - checksum: 10c0/d32754045bcb2294ade881d45140a5e52bda2321b9e98fa514797b7f0d252c4c5ab0d1edb34112652c62fa6a9398def568da63a4d7544672229afea283358c36 - languageName: node - linkType: hard - "arrify@npm:^1.0.1": version: 1.0.1 resolution: "arrify@npm:1.0.1" @@ -912,15 +673,6 @@ __metadata: languageName: node linkType: hard -"available-typed-arrays@npm:^1.0.7": - version: 1.0.7 - resolution: "available-typed-arrays@npm:1.0.7" - dependencies: - possible-typed-array-names: "npm:^1.0.0" - checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2 - languageName: node - linkType: hard - "bail@npm:^2.0.0": version: 2.0.2 resolution: "bail@npm:2.0.2" @@ -977,20 +729,6 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.23.0": - version: 4.23.2 - resolution: "browserslist@npm:4.23.2" - dependencies: - caniuse-lite: "npm:^1.0.30001640" - electron-to-chromium: "npm:^1.4.820" - node-releases: "npm:^2.0.14" - update-browserslist-db: "npm:^1.1.0" - bin: - browserslist: cli.js - checksum: 10c0/0217d23c69ed61cdd2530c7019bf7c822cd74c51f8baab18dd62457fed3129f52499f8d3a6f809ae1fb7bb3050aa70caa9a529cc36c7478427966dbf429723a5 - languageName: node - linkType: hard - "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -998,13 +736,6 @@ __metadata: languageName: node linkType: hard -"builtin-modules@npm:^3.3.0": - version: 3.3.0 - resolution: "builtin-modules@npm:3.3.0" - checksum: 10c0/2cb3448b4f7306dc853632a4fcddc95e8d4e4b9868c139400027b71938fc6806d4ff44007deffb362ac85724bd40c2c6452fb6a0aa4531650eeddb98d8e5ee8a - languageName: node - linkType: hard - "c8@npm:^10.1.2": version: 10.1.2 resolution: "c8@npm:10.1.2" @@ -1051,26 +782,6 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": - version: 1.0.7 - resolution: "call-bind@npm:1.0.7" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - set-function-length: "npm:^1.2.1" - checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d - languageName: node - linkType: hard - -"callsites@npm:^3.0.0": - version: 3.1.0 - resolution: "callsites@npm:3.1.0" - checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 - languageName: node - linkType: hard - "camelcase-keys@npm:^7.0.0": version: 7.0.2 resolution: "camelcase-keys@npm:7.0.2" @@ -1090,13 +801,6 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001640": - version: 1.0.30001646 - resolution: "caniuse-lite@npm:1.0.30001646" - checksum: 10c0/ecdd87c08cd63fa32e11311dfa3543a52613b0b99498b6fe6f2c66af65cc27e2f7436fa5b2bc2bcf72174448a7670715b284d420de838bcf3e811864371a2465 - languageName: node - linkType: hard - "ccount@npm:^2.0.0": version: 2.0.1 resolution: "ccount@npm:2.0.1" @@ -1139,7 +843,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0": +"chalk@npm:^4.1.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -1224,15 +928,6 @@ __metadata: languageName: node linkType: hard -"clean-regexp@npm:^1.0.0": - version: 1.0.0 - resolution: "clean-regexp@npm:1.0.0" - dependencies: - escape-string-regexp: "npm:^1.0.5" - checksum: 10c0/fd9c7446551b8fc536f95e8a286d431017cd4ba1ec2e53997ec9159385e9c317672f6dfc4d49fdb97449fdb53b0bacd0a8bab9343b8fdd2e46c7ddf6173d0db7 - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -1317,13 +1012,6 @@ __metadata: languageName: node linkType: hard -"comment-parser@npm:1.4.1": - version: 1.4.1 - resolution: "comment-parser@npm:1.4.1" - checksum: 10c0/d6c4be3f5be058f98b24f2d557f745d8fe1cc9eb75bebbdccabd404a0e1ed41563171b16285f593011f8b6a5ec81f564fb1f2121418ac5cbf0f49255bf0840dd - languageName: node - linkType: hard - "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -1357,15 +1045,6 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.37.0": - version: 3.37.1 - resolution: "core-js-compat@npm:3.37.1" - dependencies: - browserslist: "npm:^4.23.0" - checksum: 10c0/4e2da9c900f2951a57947af7aeef4d16f2c75d7f7e966c0d0b62953f65225003ade5e84d3ae98847f65b24c109c606821d9dc925db8ca418fb761e7c81963c2a - languageName: node - linkType: hard - "create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -1373,7 +1052,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": +"cross-spawn@npm:^7.0.0": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -1384,40 +1063,7 @@ __metadata: languageName: node linkType: hard -"data-view-buffer@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-buffer@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10c0/8984119e59dbed906a11fcfb417d7d861936f16697a0e7216fe2c6c810f6b5e8f4a5281e73f2c28e8e9259027190ac4a33e2a65fdd7fa86ac06b76e838918583 - languageName: node - linkType: hard - -"data-view-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10c0/b7d9e48a0cf5aefed9ab7d123559917b2d7e0d65531f43b2fd95b9d3a6b46042dd3fca597c42bba384e66b70d7ad66ff23932f8367b241f53d93af42cfe04ec2 - languageName: node - linkType: hard - -"data-view-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "data-view-byte-offset@npm:1.0.0" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10c0/21b0d2e53fd6e20cc4257c873bf6d36d77bd6185624b84076c0a1ddaa757b49aaf076254006341d35568e89f52eecd1ccb1a502cfb620f2beca04f48a6a62a8f - languageName: node - linkType: hard - -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.3.4, debug@npm:^4.3.5": version: 4.3.6 resolution: "debug@npm:4.3.6" dependencies: @@ -1429,15 +1075,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.2.7": - version: 3.2.7 - resolution: "debug@npm:3.2.7" - dependencies: - ms: "npm:^2.1.1" - checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a - languageName: node - linkType: hard - "decamelize-keys@npm:^1.1.0": version: 1.1.1 resolution: "decamelize-keys@npm:1.1.1" @@ -1485,35 +1122,6 @@ __metadata: languageName: node linkType: hard -"deep-is@npm:^0.1.3": - version: 0.1.4 - resolution: "deep-is@npm:0.1.4" - checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c - languageName: node - linkType: hard - -"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": - version: 1.1.4 - resolution: "define-data-property@npm:1.1.4" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - gopd: "npm:^1.0.1" - checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 - languageName: node - linkType: hard - -"define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": - version: 1.2.1 - resolution: "define-properties@npm:1.2.1" - dependencies: - define-data-property: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.0" - object-keys: "npm:^1.1.1" - checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 - languageName: node - linkType: hard - "del-cli@npm:^5.1.0": version: 5.1.0 resolution: "del-cli@npm:5.1.0" @@ -1582,15 +1190,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^2.1.0": - version: 2.1.0 - resolution: "doctrine@npm:2.1.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10c0/b6416aaff1f380bf56c3b552f31fdf7a69b45689368deca72d28636f41c16bb28ec3ebc40ace97db4c1afc0ceeb8120e8492fe0046841c94c2933b2e30a7d5ac - languageName: node - linkType: hard - "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -1598,13 +1197,6 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.820": - version: 1.5.4 - resolution: "electron-to-chromium@npm:1.5.4" - checksum: 10c0/139abf1b7281c2f3288819fb9b114f09d541ac38c9f0373f194ce2d483d82d118b8751f1b2a59b04ed0d8f414071b58508a40050fc0f23b5aa7e38d11d0cf30c - languageName: node - linkType: hard - "emoji-regex@npm:^10.2.1": version: 10.3.0 resolution: "emoji-regex@npm:10.3.0" @@ -1635,16 +1227,6 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.12.0": - version: 5.17.1 - resolution: "enhanced-resolve@npm:5.17.1" - dependencies: - graceful-fs: "npm:^4.2.4" - tapable: "npm:^2.2.0" - checksum: 10c0/81a0515675eca17efdba2cf5bad87abc91a528fc1191aad50e275e74f045b41506167d420099022da7181c8d787170ea41e4a11a0b10b7a16f6237daecb15370 - languageName: node - linkType: hard - "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -1668,124 +1250,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2": - version: 1.23.3 - resolution: "es-abstract@npm:1.23.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - arraybuffer.prototype.slice: "npm:^1.0.3" - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - data-view-buffer: "npm:^1.0.1" - data-view-byte-length: "npm:^1.0.1" - data-view-byte-offset: "npm:^1.0.0" - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-set-tostringtag: "npm:^2.0.3" - es-to-primitive: "npm:^1.2.1" - function.prototype.name: "npm:^1.1.6" - get-intrinsic: "npm:^1.2.4" - get-symbol-description: "npm:^1.0.2" - globalthis: "npm:^1.0.3" - gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.0.3" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.2" - internal-slot: "npm:^1.0.7" - is-array-buffer: "npm:^3.0.4" - is-callable: "npm:^1.2.7" - is-data-view: "npm:^1.0.1" - is-negative-zero: "npm:^2.0.3" - is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.3" - is-string: "npm:^1.0.7" - is-typed-array: "npm:^1.1.13" - is-weakref: "npm:^1.0.2" - object-inspect: "npm:^1.13.1" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.5" - regexp.prototype.flags: "npm:^1.5.2" - safe-array-concat: "npm:^1.1.2" - safe-regex-test: "npm:^1.0.3" - string.prototype.trim: "npm:^1.2.9" - string.prototype.trimend: "npm:^1.0.8" - string.prototype.trimstart: "npm:^1.0.8" - typed-array-buffer: "npm:^1.0.2" - typed-array-byte-length: "npm:^1.0.1" - typed-array-byte-offset: "npm:^1.0.2" - typed-array-length: "npm:^1.0.6" - unbox-primitive: "npm:^1.0.2" - which-typed-array: "npm:^1.1.15" - checksum: 10c0/d27e9afafb225c6924bee9971a7f25f20c314f2d6cb93a63cada4ac11dcf42040896a6c22e5fb8f2a10767055ed4ddf400be3b1eb12297d281726de470b75666 - languageName: node - linkType: hard - -"es-define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "es-define-property@npm:1.0.0" - dependencies: - get-intrinsic: "npm:^1.2.4" - checksum: 10c0/6bf3191feb7ea2ebda48b577f69bdfac7a2b3c9bcf97307f55fd6ef1bbca0b49f0c219a935aca506c993d8c5d8bddd937766cb760cd5e5a1071351f2df9f9aa4 - languageName: node - linkType: hard - -"es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": - version: 1.3.0 - resolution: "es-errors@npm:1.3.0" - checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 - languageName: node - linkType: hard - -"es-module-lexer@npm:^1.5.3": - version: 1.5.4 - resolution: "es-module-lexer@npm:1.5.4" - checksum: 10c0/300a469488c2f22081df1e4c8398c78db92358496e639b0df7f89ac6455462aaf5d8893939087c1a1cbcbf20eed4610c70e0bcb8f3e4b0d80a5d2611c539408c - languageName: node - linkType: hard - -"es-object-atoms@npm:^1.0.0": - version: 1.0.0 - resolution: "es-object-atoms@npm:1.0.0" - dependencies: - es-errors: "npm:^1.3.0" - checksum: 10c0/1fed3d102eb27ab8d983337bb7c8b159dd2a1e63ff833ec54eea1311c96d5b08223b433060ba240541ca8adba9eee6b0a60cdbf2f80634b784febc9cc8b687b4 - languageName: node - linkType: hard - -"es-set-tostringtag@npm:^2.0.3": - version: 2.0.3 - resolution: "es-set-tostringtag@npm:2.0.3" - dependencies: - get-intrinsic: "npm:^1.2.4" - has-tostringtag: "npm:^1.0.2" - hasown: "npm:^2.0.1" - checksum: 10c0/f22aff1585eb33569c326323f0b0d175844a1f11618b86e193b386f8be0ea9474cfbe46df39c45d959f7aa8f6c06985dc51dd6bce5401645ec5a74c4ceaa836a - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" - dependencies: - hasown: "npm:^2.0.0" - checksum: 10c0/f495af7b4b7601a4c0cfb893581c352636e5c08654d129590386a33a0432cf13a7bdc7b6493801cadd990d838e2839b9013d1de3b880440cb537825e834fe783 - languageName: node - linkType: hard - -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: "npm:^1.1.4" - is-date-object: "npm:^1.0.1" - is-symbol: "npm:^1.0.2" - checksum: 10c0/0886572b8dc075cb10e50c0af62a03d03a68e1e69c388bd4f10c0649ee41b1fbb24840a1b7e590b393011b5cdbe0144b776da316762653685432df37d6de60f1 - languageName: node - linkType: hard - -"escalade@npm:^3.1.1, escalade@npm:^3.1.2": +"escalade@npm:^3.1.1": version: 3.1.2 resolution: "escalade@npm:3.1.2" checksum: 10c0/6b4adafecd0682f3aa1cd1106b8fff30e492c7015b178bc81b2d2f75106dabea6c6d6e8508fc491bd58e597c74abb0e8e2368f943ecb9393d4162e3c2f3cf287 @@ -1813,287 +1278,6 @@ __metadata: languageName: node linkType: hard -"eslint-config-prettier@npm:^9.1.0": - version: 9.1.0 - resolution: "eslint-config-prettier@npm:9.1.0" - peerDependencies: - eslint: ">=7.0.0" - bin: - eslint-config-prettier: bin/cli.js - checksum: 10c0/6d332694b36bc9ac6fdb18d3ca2f6ac42afa2ad61f0493e89226950a7091e38981b66bac2b47ba39d15b73fff2cd32c78b850a9cf9eed9ca9a96bfb2f3a2f10d - languageName: node - linkType: hard - -"eslint-import-resolver-node@npm:^0.3.9": - version: 0.3.9 - resolution: "eslint-import-resolver-node@npm:0.3.9" - dependencies: - debug: "npm:^3.2.7" - is-core-module: "npm:^2.13.0" - resolve: "npm:^1.22.4" - checksum: 10c0/0ea8a24a72328a51fd95aa8f660dcca74c1429806737cf10261ab90cfcaaf62fd1eff664b76a44270868e0a932711a81b250053942595bcd00a93b1c1575dd61 - languageName: node - linkType: hard - -"eslint-import-resolver-typescript@npm:^3.6.1": - version: 3.6.1 - resolution: "eslint-import-resolver-typescript@npm:3.6.1" - dependencies: - debug: "npm:^4.3.4" - enhanced-resolve: "npm:^5.12.0" - eslint-module-utils: "npm:^2.7.4" - fast-glob: "npm:^3.3.1" - get-tsconfig: "npm:^4.5.0" - is-core-module: "npm:^2.11.0" - is-glob: "npm:^4.0.3" - peerDependencies: - eslint: "*" - eslint-plugin-import: "*" - checksum: 10c0/cb1cb4389916fe78bf8c8567aae2f69243dbfe624bfe21078c56ad46fa1ebf0634fa7239dd3b2055ab5c27359e4b4c28b69b11fcb3a5df8a9e6f7add8e034d86 - languageName: node - linkType: hard - -"eslint-module-utils@npm:^2.7.4, eslint-module-utils@npm:^2.8.0": - version: 2.8.1 - resolution: "eslint-module-utils@npm:2.8.1" - dependencies: - debug: "npm:^3.2.7" - peerDependenciesMeta: - eslint: - optional: true - checksum: 10c0/1aeeb97bf4b688d28de136ee57c824480c37691b40fa825c711a4caf85954e94b99c06ac639d7f1f6c1d69223bd21bcb991155b3e589488e958d5b83dfd0f882 - languageName: node - linkType: hard - -"eslint-plugin-es@npm:^3.0.0": - version: 3.0.1 - resolution: "eslint-plugin-es@npm:3.0.1" - dependencies: - eslint-utils: "npm:^2.0.0" - regexpp: "npm:^3.0.0" - peerDependencies: - eslint: ">=4.19.1" - checksum: 10c0/12ae730aa9603e680af048e1653aac15e529411b68b8d0da6e290700b17c695485af7c3f5360f531f80970786cab7288c2c1d4a58c35ec1bb89649897c016c4a - languageName: node - linkType: hard - -"eslint-plugin-import@npm:^2.29.1": - version: 2.29.1 - resolution: "eslint-plugin-import@npm:2.29.1" - dependencies: - array-includes: "npm:^3.1.7" - array.prototype.findlastindex: "npm:^1.2.3" - array.prototype.flat: "npm:^1.3.2" - array.prototype.flatmap: "npm:^1.3.2" - debug: "npm:^3.2.7" - doctrine: "npm:^2.1.0" - eslint-import-resolver-node: "npm:^0.3.9" - eslint-module-utils: "npm:^2.8.0" - hasown: "npm:^2.0.0" - is-core-module: "npm:^2.13.1" - is-glob: "npm:^4.0.3" - minimatch: "npm:^3.1.2" - object.fromentries: "npm:^2.0.7" - object.groupby: "npm:^1.0.1" - object.values: "npm:^1.1.7" - semver: "npm:^6.3.1" - tsconfig-paths: "npm:^3.15.0" - peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: 10c0/5f35dfbf4e8e67f741f396987de9504ad125c49f4144508a93282b4ea0127e052bde65ab6def1f31b6ace6d5d430be698333f75bdd7dca3bc14226c92a083196 - languageName: node - linkType: hard - -"eslint-plugin-jsdoc@npm:^48.7.0": - version: 48.10.2 - resolution: "eslint-plugin-jsdoc@npm:48.10.2" - dependencies: - "@es-joy/jsdoccomment": "npm:~0.46.0" - are-docs-informative: "npm:^0.0.2" - comment-parser: "npm:1.4.1" - debug: "npm:^4.3.5" - escape-string-regexp: "npm:^4.0.0" - espree: "npm:^10.1.0" - esquery: "npm:^1.6.0" - parse-imports: "npm:^2.1.1" - semver: "npm:^7.6.3" - spdx-expression-parse: "npm:^4.0.0" - synckit: "npm:^0.9.1" - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/b0954db45fc087b36b984f550236a7c2d8386bf3bc57477f2c95c24a612922bb81b1ffee598226b5004e50890e2e6fada33432db38111a0c40bdbc759614382e - languageName: node - linkType: hard - -"eslint-plugin-node@npm:^11.1.0": - version: 11.1.0 - resolution: "eslint-plugin-node@npm:11.1.0" - dependencies: - eslint-plugin-es: "npm:^3.0.0" - eslint-utils: "npm:^2.0.0" - ignore: "npm:^5.1.1" - minimatch: "npm:^3.0.4" - resolve: "npm:^1.10.1" - semver: "npm:^6.1.0" - peerDependencies: - eslint: ">=5.16.0" - checksum: 10c0/c7716adac4020cb852fd2410dcd8bdb13a227004de77f96d7f9806d0cf2274f24e0920a7ca73bcd72d90003696c1f17fdd9fe3ca218e64ee03dc2b840e4416fa - languageName: node - linkType: hard - -"eslint-plugin-unicorn@npm:^55.0.0": - version: 55.0.0 - resolution: "eslint-plugin-unicorn@npm:55.0.0" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.24.5" - "@eslint-community/eslint-utils": "npm:^4.4.0" - ci-info: "npm:^4.0.0" - clean-regexp: "npm:^1.0.0" - core-js-compat: "npm:^3.37.0" - esquery: "npm:^1.5.0" - globals: "npm:^15.7.0" - indent-string: "npm:^4.0.0" - is-builtin-module: "npm:^3.2.1" - jsesc: "npm:^3.0.2" - pluralize: "npm:^8.0.0" - read-pkg-up: "npm:^7.0.1" - regexp-tree: "npm:^0.1.27" - regjsparser: "npm:^0.10.0" - semver: "npm:^7.6.1" - strip-indent: "npm:^3.0.0" - peerDependencies: - eslint: ">=8.56.0" - checksum: 10c0/31620da5c823abc791a3f4c9a0ab19baf21820bd38f018eafbc862ea0bbc3e4baedbdaaaf48f2dc1b2a59dfc7b341e654f2126c394f5d62fb5216e632d8a2c03 - languageName: node - linkType: hard - -"eslint-scope@npm:^8.0.2": - version: 8.0.2 - resolution: "eslint-scope@npm:8.0.2" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^5.2.0" - checksum: 10c0/477f820647c8755229da913025b4567347fd1f0bf7cbdf3a256efff26a7e2e130433df052bd9e3d014025423dc00489bea47eb341002b15553673379c1a7dc36 - languageName: node - linkType: hard - -"eslint-utils@npm:^2.0.0": - version: 2.1.0 - resolution: "eslint-utils@npm:2.1.0" - dependencies: - eslint-visitor-keys: "npm:^1.1.0" - checksum: 10c0/69521c5d6569384b24093125d037ba238d3d6e54367f7143af9928f5286369e912c26cad5016d730c0ffb9797ac9e83831059d7f1d863f7dc84330eb02414611 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^1.1.0": - version: 1.3.0 - resolution: "eslint-visitor-keys@npm:1.3.0" - checksum: 10c0/10c91fdbbe36810dd4308e57f9a8bc7177188b2a70247e54e3af1fa05ebc66414ae6fd4ce3c6c6821591f43a556e9037bc6b071122e099b5f8b7d2f76df553e3 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": - version: 3.4.3 - resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^4.0.0": - version: 4.0.0 - resolution: "eslint-visitor-keys@npm:4.0.0" - checksum: 10c0/76619f42cf162705a1515a6868e6fc7567e185c7063a05621a8ac4c3b850d022661262c21d9f1fc1d144ecf0d5d64d70a3f43c15c3fc969a61ace0fb25698cf5 - languageName: node - linkType: hard - -"eslint@npm:^9.7.0": - version: 9.8.0 - resolution: "eslint@npm:9.8.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.11.0" - "@eslint/config-array": "npm:^0.17.1" - "@eslint/eslintrc": "npm:^3.1.0" - "@eslint/js": "npm:9.8.0" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@humanwhocodes/retry": "npm:^0.3.0" - "@nodelib/fs.walk": "npm:^1.2.8" - ajv: "npm:^6.12.4" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" - debug: "npm:^4.3.2" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^8.0.2" - eslint-visitor-keys: "npm:^4.0.0" - espree: "npm:^10.1.0" - esquery: "npm:^1.5.0" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^8.0.0" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" - bin: - eslint: bin/eslint.js - checksum: 10c0/a2ee0cce1147565d011fe185733af482f34d5466f5df5f390d0ea2ecf78097883cf568ed6c771d687138609c63cd55cd1e3ff12de7393c03f54fcffcdd0f225d - languageName: node - linkType: hard - -"espree@npm:^10.0.1, espree@npm:^10.1.0": - version: 10.1.0 - resolution: "espree@npm:10.1.0" - dependencies: - acorn: "npm:^8.12.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^4.0.0" - checksum: 10c0/52e6feaa77a31a6038f0c0e3fce93010a4625701925b0715cd54a2ae190b3275053a0717db698697b32653788ac04845e489d6773b508d6c2e8752f3c57470a0 - languageName: node - linkType: hard - -"esquery@npm:^1.5.0, esquery@npm:^1.6.0": - version: 1.6.0 - resolution: "esquery@npm:1.6.0" - dependencies: - estraverse: "npm:^5.1.0" - checksum: 10c0/cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2 - languageName: node - linkType: hard - -"esrecurse@npm:^4.3.0": - version: 4.3.0 - resolution: "esrecurse@npm:4.3.0" - dependencies: - estraverse: "npm:^5.2.0" - checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 - languageName: node - linkType: hard - -"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": - version: 5.3.0 - resolution: "estraverse@npm:5.3.0" - checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 - languageName: node - linkType: hard - -"esutils@npm:^2.0.2": - version: 2.0.3 - resolution: "esutils@npm:2.0.3" - checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 - languageName: node - linkType: hard - "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -2108,14 +1292,7 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": - version: 3.1.3 - resolution: "fast-deep-equal@npm:3.1.3" - checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 - languageName: node - linkType: hard - -"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.1": +"fast-glob@npm:^3.3.0": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -2128,20 +1305,6 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0": - version: 2.1.0 - resolution: "fast-json-stable-stringify@npm:2.1.0" - checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b - languageName: node - linkType: hard - -"fast-levenshtein@npm:^2.0.6": - version: 2.0.6 - resolution: "fast-levenshtein@npm:2.0.6" - checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 - languageName: node - linkType: hard - "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -2151,15 +1314,6 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^8.0.0": - version: 8.0.0 - resolution: "file-entry-cache@npm:8.0.0" - dependencies: - flat-cache: "npm:^4.0.0" - checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 - languageName: node - linkType: hard - "file-type@npm:^19.2.0": version: 19.3.0 resolution: "file-type@npm:19.3.0" @@ -2180,16 +1334,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.1.0": - version: 4.1.0 - resolution: "find-up@npm:4.1.0" - dependencies: - locate-path: "npm:^5.0.0" - path-exists: "npm:^4.0.0" - checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1 - languageName: node - linkType: hard - "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -2200,16 +1344,6 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^4.0.0": - version: 4.0.1 - resolution: "flat-cache@npm:4.0.1" - dependencies: - flatted: "npm:^3.2.9" - keyv: "npm:^4.5.4" - checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc - languageName: node - linkType: hard - "flat@npm:^5.0.2": version: 5.0.2 resolution: "flat@npm:5.0.2" @@ -2219,22 +1353,6 @@ __metadata: languageName: node linkType: hard -"flatted@npm:^3.2.9": - version: 3.3.1 - resolution: "flatted@npm:3.3.1" - checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf - languageName: node - linkType: hard - -"for-each@npm:^0.3.3": - version: 0.3.3 - resolution: "for-each@npm:0.3.3" - dependencies: - is-callable: "npm:^1.1.3" - checksum: 10c0/22330d8a2db728dbf003ec9182c2d421fbcd2969b02b4f97ec288721cda63eb28f2c08585ddccd0f77cb2930af8d958005c9e72f47141dc51816127a118f39aa - languageName: node - linkType: hard - "foreground-child@npm:^3.1.0, foreground-child@npm:^3.1.1": version: 3.2.1 resolution: "foreground-child@npm:3.2.1" @@ -2291,27 +1409,8 @@ __metadata: "function-bind@npm:^1.1.2": version: 1.1.2 - resolution: "function-bind@npm:1.1.2" - checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 - languageName: node - linkType: hard - -"function.prototype.name@npm:^1.1.6": - version: 1.1.6 - resolution: "function.prototype.name@npm:1.1.6" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - functions-have-names: "npm:^1.2.3" - checksum: 10c0/9eae11294905b62cb16874adb4fc687927cda3162285e0ad9612e6a1d04934005d46907362ea9cdb7428edce05a2f2c3dabc3b2d21e9fd343e9bb278230ad94b - languageName: node - linkType: hard - -"functions-have-names@npm:^1.2.3": - version: 1.2.3 - resolution: "functions-have-names@npm:1.2.3" - checksum: 10c0/33e77fd29bddc2d9bb78ab3eb854c165909201f88c75faa8272e35899e2d35a8a642a15e7420ef945e1f64a9670d6aa3ec744106b2aa42be68ca5114025954ca + resolution: "function-bind@npm:1.1.2" + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 languageName: node linkType: hard @@ -2329,39 +1428,6 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": - version: 1.2.4 - resolution: "get-intrinsic@npm:1.2.4" - dependencies: - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - has-proto: "npm:^1.0.1" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.0" - checksum: 10c0/0a9b82c16696ed6da5e39b1267104475c47e3a9bdbe8b509dfe1710946e38a87be70d759f4bb3cda042d76a41ef47fe769660f3b7c0d1f68750299344ffb15b7 - languageName: node - linkType: hard - -"get-symbol-description@npm:^1.0.2": - version: 1.0.2 - resolution: "get-symbol-description@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.5" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - checksum: 10c0/867be6d63f5e0eb026cb3b0ef695ec9ecf9310febb041072d2e142f260bd91ced9eeb426b3af98791d1064e324e653424afa6fd1af17dee373bea48ae03162bc - languageName: node - linkType: hard - -"get-tsconfig@npm:^4.5.0": - version: 4.7.6 - resolution: "get-tsconfig@npm:4.7.6" - dependencies: - resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/2240e1b13e996dfbb947d177f422f83d09d1f93c9ce16959ebb3c2bdf8bdf4f04f98eba043859172da1685f9c7071091f0acfa964ebbe4780394d83b7dc3f58a - languageName: node - linkType: hard - "glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -2371,15 +1437,6 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^6.0.2": - version: 6.0.2 - resolution: "glob-parent@npm:6.0.2" - dependencies: - is-glob: "npm:^4.0.3" - checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8 - languageName: node - linkType: hard - "glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.1": version: 10.4.5 resolution: "glob@npm:10.4.5" @@ -2423,44 +1480,6 @@ __metadata: languageName: node linkType: hard -"globals@npm:^14.0.0": - version: 14.0.0 - resolution: "globals@npm:14.0.0" - checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d - languageName: node - linkType: hard - -"globals@npm:^15.7.0, globals@npm:^15.8.0": - version: 15.9.0 - resolution: "globals@npm:15.9.0" - checksum: 10c0/de4b553e412e7e830998578d51b605c492256fb2a9273eaeec6ec9ee519f1c5aa50de57e3979911607fd7593a4066420e01d8c3d551e7a6a236e96c521aee36c - languageName: node - linkType: hard - -"globalthis@npm:^1.0.3": - version: 1.0.4 - resolution: "globalthis@npm:1.0.4" - dependencies: - define-properties: "npm:^1.2.1" - gopd: "npm:^1.0.1" - checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846 - languageName: node - linkType: hard - -"globby@npm:^11.1.0": - version: 11.1.0 - resolution: "globby@npm:11.1.0" - dependencies: - array-union: "npm:^2.1.0" - dir-glob: "npm:^3.0.1" - fast-glob: "npm:^3.2.9" - ignore: "npm:^5.2.0" - merge2: "npm:^1.4.1" - slash: "npm:^3.0.0" - checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 - languageName: node - linkType: hard - "globby@npm:^13.1.2": version: 13.2.2 resolution: "globby@npm:13.2.2" @@ -2474,29 +1493,13 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.0.1": - version: 1.0.1 - resolution: "gopd@npm:1.0.1" - dependencies: - get-intrinsic: "npm:^1.1.3" - checksum: 10c0/505c05487f7944c552cee72087bf1567debb470d4355b1335f2c262d218ebbff805cd3715448fe29b4b380bae6912561d0467233e4165830efd28da241418c63 - languageName: node - linkType: hard - -"graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 languageName: node linkType: hard -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31 - languageName: node - linkType: hard - "hard-rejection@npm:^2.1.0": version: 2.1.0 resolution: "hard-rejection@npm:2.1.0" @@ -2504,13 +1507,6 @@ __metadata: languageName: node linkType: hard -"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": - version: 1.0.2 - resolution: "has-bigints@npm:1.0.2" - checksum: 10c0/724eb1485bfa3cdff6f18d95130aa190561f00b3fcf9f19dc640baf8176b5917c143b81ec2123f8cddb6c05164a198c94b13e1377c497705ccc8e1a80306e83b - languageName: node - linkType: hard - "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" @@ -2525,39 +1521,7 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": - version: 1.0.2 - resolution: "has-property-descriptors@npm:1.0.2" - dependencies: - es-define-property: "npm:^1.0.0" - checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 - languageName: node - linkType: hard - -"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": - version: 1.0.3 - resolution: "has-proto@npm:1.0.3" - checksum: 10c0/35a6989f81e9f8022c2f4027f8b48a552de714938765d019dbea6bb547bd49ce5010a3c7c32ec6ddac6e48fc546166a3583b128f5a7add8b058a6d8b4afec205 - languageName: node - linkType: hard - -"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: 10c0/e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3 - languageName: node - linkType: hard - -"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": - version: 1.0.2 - resolution: "has-tostringtag@npm:1.0.2" - dependencies: - has-symbols: "npm:^1.0.3" - checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c - languageName: node - linkType: hard - -"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -2575,13 +1539,6 @@ __metadata: languageName: node linkType: hard -"hosted-git-info@npm:^2.1.4": - version: 2.8.9 - resolution: "hosted-git-info@npm:2.8.9" - checksum: 10c0/317cbc6b1bbbe23c2a40ae23f3dafe9fa349ce42a89a36f930e3f9c0530c179a3882d2ef1e4141a4c3674d6faaea862138ec55b43ad6f75e387fda2483a13c70 - languageName: node - linkType: hard - "hosted-git-info@npm:^4.0.1": version: 4.1.0 resolution: "hosted-git-info@npm:4.1.0" @@ -2650,23 +1607,13 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.0.0, ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": +"ignore@npm:^5.0.0, ignore@npm:^5.2.4": version: 5.3.1 resolution: "ignore@npm:5.3.1" checksum: 10c0/703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd languageName: node linkType: hard -"import-fresh@npm:^3.2.1": - version: 3.3.0 - resolution: "import-fresh@npm:3.3.0" - dependencies: - parent-module: "npm:^1.0.0" - resolve-from: "npm:^4.0.0" - checksum: 10c0/7f882953aa6b740d1f0e384d0547158bc86efbf2eea0f1483b8900a6f65c5a5123c2cf09b0d542cc419d0b98a759ecaeb394237e97ea427f2da221dc3cd80cc3 - languageName: node - linkType: hard - "import-meta-resolve@npm:^4.0.0": version: 4.1.0 resolution: "import-meta-resolve@npm:4.1.0" @@ -2719,17 +1666,6 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.7": - version: 1.0.7 - resolution: "internal-slot@npm:1.0.7" - dependencies: - es-errors: "npm:^1.3.0" - hasown: "npm:^2.0.0" - side-channel: "npm:^1.0.4" - checksum: 10c0/f8b294a4e6ea3855fc59551bbf35f2b832cf01fd5e6e2a97f5c201a071cc09b49048f856e484b67a6c721da5e55736c5b6ddafaf19e2dbeb4a3ff1821680de6c - languageName: node - linkType: hard - "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -2757,16 +1693,6 @@ __metadata: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.4": - version: 3.0.4 - resolution: "is-array-buffer@npm:3.0.4" - dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.2.1" - checksum: 10c0/42a49d006cc6130bc5424eae113e948c146f31f9d24460fc0958f855d9d810e6fd2e4519bf19aab75179af9c298ea6092459d8cafdec523cd19e529b26eab860 - languageName: node - linkType: hard - "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -2774,15 +1700,6 @@ __metadata: languageName: node linkType: hard -"is-bigint@npm:^1.0.1": - version: 1.0.4 - resolution: "is-bigint@npm:1.0.4" - dependencies: - has-bigints: "npm:^1.0.1" - checksum: 10c0/eb9c88e418a0d195ca545aff2b715c9903d9b0a5033bc5922fec600eb0c3d7b1ee7f882dbf2e0d5a6e694e42391be3683e4368737bd3c4a77f8ac293e7773696 - languageName: node - linkType: hard - "is-binary-path@npm:~2.1.0": version: 2.1.0 resolution: "is-binary-path@npm:2.1.0" @@ -2792,33 +1709,7 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.1.0": - version: 1.1.2 - resolution: "is-boolean-object@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/6090587f8a8a8534c0f816da868bc94f32810f08807aa72fa7e79f7e11c466d281486ffe7a788178809c2aa71fe3e700b167fe80dd96dad68026bfff8ebf39f7 - languageName: node - linkType: hard - -"is-builtin-module@npm:^3.2.1": - version: 3.2.1 - resolution: "is-builtin-module@npm:3.2.1" - dependencies: - builtin-modules: "npm:^3.3.0" - checksum: 10c0/5a66937a03f3b18803381518f0ef679752ac18cdb7dd53b5e23ee8df8d440558737bd8dcc04d2aae555909d2ecb4a81b5c0d334d119402584b61e6a003e31af1 - languageName: node - linkType: hard - -"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": - version: 1.2.7 - resolution: "is-callable@npm:1.2.7" - checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f - languageName: node - linkType: hard - -"is-core-module@npm:^2.11.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1, is-core-module@npm:^2.5.0": +"is-core-module@npm:^2.5.0": version: 2.15.0 resolution: "is-core-module@npm:2.15.0" dependencies: @@ -2827,24 +1718,6 @@ __metadata: languageName: node linkType: hard -"is-data-view@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-view@npm:1.0.1" - dependencies: - is-typed-array: "npm:^1.1.13" - checksum: 10c0/a3e6ec84efe303da859107aed9b970e018e2bee7ffcb48e2f8096921a493608134240e672a2072577e5f23a729846241d9634806e8a0e51d9129c56d5f65442d - languageName: node - linkType: hard - -"is-date-object@npm:^1.0.1": - version: 1.0.5 - resolution: "is-date-object@npm:1.0.5" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/eed21e5dcc619c48ccef804dfc83a739dbb2abee6ca202838ee1bd5f760fe8d8a93444f0d49012ad19bb7c006186e2884a1b92f6e1c056da7fd23d0a9ad5992e - languageName: node - linkType: hard - "is-decimal@npm:^2.0.0": version: 2.0.1 resolution: "is-decimal@npm:2.0.1" @@ -2873,7 +1746,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": +"is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -2896,22 +1769,6 @@ __metadata: languageName: node linkType: hard -"is-negative-zero@npm:^2.0.3": - version: 2.0.3 - resolution: "is-negative-zero@npm:2.0.3" - checksum: 10c0/bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e - languageName: node - linkType: hard - -"is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/aad266da1e530f1804a2b7bd2e874b4869f71c98590b3964f9d06cc9869b18f8d1f4778f838ecd2a11011bce20aeecb53cb269ba916209b79c24580416b74b1b - languageName: node - linkType: hard - "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -2926,13 +1783,6 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.3": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 - languageName: node - linkType: hard - "is-path-inside@npm:^4.0.0": version: 4.0.0 resolution: "is-path-inside@npm:4.0.0" @@ -2961,52 +1811,6 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.1.4": - version: 1.1.4 - resolution: "is-regex@npm:1.1.4" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/bb72aae604a69eafd4a82a93002058c416ace8cde95873589a97fc5dac96a6c6c78a9977d487b7b95426a8f5073969124dd228f043f9f604f041f32fcc465fc1 - languageName: node - linkType: hard - -"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": - version: 1.0.3 - resolution: "is-shared-array-buffer@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - checksum: 10c0/adc11ab0acbc934a7b9e5e9d6c588d4ec6682f6fea8cda5180721704fa32927582ede5b123349e32517fdadd07958973d24716c80e7ab198970c47acc09e59c7 - languageName: node - linkType: hard - -"is-string@npm:^1.0.5, is-string@npm:^1.0.7": - version: 1.0.7 - resolution: "is-string@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/905f805cbc6eedfa678aaa103ab7f626aac9ebbdc8737abb5243acaa61d9820f8edc5819106b8fcd1839e33db21de9f0116ae20de380c8382d16dc2a601921f6 - languageName: node - linkType: hard - -"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": - version: 1.0.4 - resolution: "is-symbol@npm:1.0.4" - dependencies: - has-symbols: "npm:^1.0.2" - checksum: 10c0/9381dd015f7c8906154dbcbf93fad769de16b4b961edc94f88d26eb8c555935caa23af88bda0c93a18e65560f6d7cca0fd5a3f8a8e1df6f1abbb9bead4502ef7 - languageName: node - linkType: hard - -"is-typed-array@npm:^1.1.13": - version: 1.1.13 - resolution: "is-typed-array@npm:1.1.13" - dependencies: - which-typed-array: "npm:^1.1.14" - checksum: 10c0/fa5cb97d4a80e52c2cc8ed3778e39f175a1a2ae4ddf3adae3187d69586a1fd57cfa0b095db31f66aa90331e9e3da79184cea9c6abdcd1abc722dc3c3edd51cca - languageName: node - linkType: hard - "is-unicode-supported@npm:^0.1.0": version: 0.1.0 resolution: "is-unicode-supported@npm:0.1.0" @@ -3014,22 +1818,6 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2": - version: 1.0.2 - resolution: "is-weakref@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - checksum: 10c0/1545c5d172cb690c392f2136c23eec07d8d78a7f57d0e41f10078aa4f5daf5d7f57b6513a67514ab4f073275ad00c9822fc8935e00229d0a2089e1c02685d4b1 - languageName: node - linkType: hard - -"isarray@npm:^2.0.5": - version: 2.0.5 - resolution: "isarray@npm:2.0.5" - checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -3110,38 +1898,6 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~4.0.0": - version: 4.0.0 - resolution: "jsdoc-type-pratt-parser@npm:4.0.0" - checksum: 10c0/b23ef7bbbe2f56d72630d1c5a233dc9fecaff399063d373c57bef136908c1b05e723dac107177303c03ccf8d75aa51507510b282aa567600477479c5ea0c36d1 - languageName: node - linkType: hard - -"jsesc@npm:^3.0.2": - version: 3.0.2 - resolution: "jsesc@npm:3.0.2" - bin: - jsesc: bin/jsesc - checksum: 10c0/ef22148f9e793180b14d8a145ee6f9f60f301abf443288117b4b6c53d0ecd58354898dc506ccbb553a5f7827965cd38bc5fb726575aae93c5e8915e2de8290e1 - languageName: node - linkType: hard - -"jsesc@npm:~0.5.0": - version: 0.5.0 - resolution: "jsesc@npm:0.5.0" - bin: - jsesc: bin/jsesc - checksum: 10c0/f93792440ae1d80f091b65f8ceddf8e55c4bb7f1a09dee5dcbdb0db5612c55c0f6045625aa6b7e8edb2e0a4feabd80ee48616dbe2d37055573a84db3d24f96d9 - languageName: node - linkType: hard - -"json-buffer@npm:3.0.1": - version: 3.0.1 - resolution: "json-buffer@npm:3.0.1" - checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 - languageName: node - linkType: hard - "json-parse-even-better-errors@npm:^2.3.0": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" @@ -3156,31 +1912,6 @@ __metadata: languageName: node linkType: hard -"json-schema-traverse@npm:^0.4.1": - version: 0.4.1 - resolution: "json-schema-traverse@npm:0.4.1" - checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce - languageName: node - linkType: hard - -"json-stable-stringify-without-jsonify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 - languageName: node - linkType: hard - -"json5@npm:^1.0.2": - version: 1.0.2 - resolution: "json5@npm:1.0.2" - dependencies: - minimist: "npm:^1.2.0" - bin: - json5: lib/cli.js - checksum: 10c0/9ee316bf21f000b00752e6c2a3b79ecf5324515a5c60ee88983a1910a45426b643a4f3461657586e8aeca87aaf96f0a519b0516d2ae527a6c3e7eed80f68717f - languageName: node - linkType: hard - "json5@npm:^2.0.0": version: 2.2.3 resolution: "json5@npm:2.2.3" @@ -3190,15 +1921,6 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.4": - version: 4.5.4 - resolution: "keyv@npm:4.5.4" - dependencies: - json-buffer: "npm:3.0.1" - checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e - languageName: node - linkType: hard - "kind-of@npm:^6.0.3": version: 6.0.3 resolution: "kind-of@npm:6.0.3" @@ -3206,16 +1928,6 @@ __metadata: languageName: node linkType: hard -"levn@npm:^0.4.1": - version: 0.4.1 - resolution: "levn@npm:0.4.1" - dependencies: - prelude-ls: "npm:^1.2.1" - type-check: "npm:~0.4.0" - checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e - languageName: node - linkType: hard - "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -3240,15 +1952,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^5.0.0": - version: 5.0.0 - resolution: "locate-path@npm:5.0.0" - dependencies: - p-locate: "npm:^4.1.0" - checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59 - languageName: node - linkType: hard - "locate-path@npm:^6.0.0": version: 6.0.0 resolution: "locate-path@npm:6.0.0" @@ -3258,13 +1961,6 @@ __metadata: languageName: node linkType: hard -"lodash.merge@npm:^4.6.2": - version: 4.6.2 - resolution: "lodash.merge@npm:4.6.2" - checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506 - languageName: node - linkType: hard - "log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" @@ -3805,14 +2501,14 @@ __metadata: languageName: node linkType: hard -"min-indent@npm:^1.0.0, min-indent@npm:^1.0.1": +"min-indent@npm:^1.0.1": version: 1.0.1 resolution: "min-indent@npm:1.0.1" checksum: 10c0/7e207bd5c20401b292de291f02913230cb1163abca162044f7db1d951fa245b174dc00869d40dd9a9f32a885ad6a5f3e767ee104cf278f399cb4e92d3f582d5c languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.1.1": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -3850,7 +2546,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.0.0, minimist@npm:^1.2.0, minimist@npm:^1.2.6": +"minimist@npm:^1.0.0": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -3988,7 +2684,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:^2.1.1, ms@npm:^2.1.3": +"ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 @@ -3999,32 +2695,21 @@ __metadata: version: 0.0.0-use.local resolution: "music-metadata@workspace:." dependencies: - "@eslint/compat": "npm:^1.1.1" - "@eslint/eslintrc": "npm:^3.1.0" - "@eslint/js": "npm:^9.7.0" + "@biomejs/biome": "npm:1.8.3" "@tokenizer/token": "npm:^0.3.0" "@types/chai": "npm:^4.3.16" "@types/chai-as-promised": "npm:^7.1.8" "@types/debug": "npm:^4.1.12" + "@types/media-typer": "npm:^1.1.3" "@types/mocha": "npm:^10.0.7" "@types/node": "npm:^22.1.0" - "@typescript-eslint/eslint-plugin": "npm:^7.16.1" - "@typescript-eslint/parser": "npm:^7.16.1" c8: "npm:^10.1.2" chai: "npm:^5.1.1" chai-as-promised: "npm:^8.0.0" content-type: "npm:^1.0.5" debug: "npm:^4.3.4" del-cli: "npm:^5.1.0" - eslint: "npm:^9.7.0" - eslint-config-prettier: "npm:^9.1.0" - eslint-import-resolver-typescript: "npm:^3.6.1" - eslint-plugin-import: "npm:^2.29.1" - eslint-plugin-jsdoc: "npm:^48.7.0" - eslint-plugin-node: "npm:^11.1.0" - eslint-plugin-unicorn: "npm:^55.0.0" file-type: "npm:^19.2.0" - globals: "npm:^15.8.0" media-typer: "npm:^1.1.0" mime: "npm:^4.0.4" mocha: "npm:^10.6.0" @@ -4039,13 +2724,6 @@ __metadata: languageName: unknown linkType: soft -"natural-compare@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare@npm:1.4.0" - checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 - languageName: node - linkType: hard - "negotiator@npm:^0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" @@ -4073,13 +2751,6 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.18 - resolution: "node-releases@npm:2.0.18" - checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27 - languageName: node - linkType: hard - "nopt@npm:^7.0.0, nopt@npm:^7.2.1": version: 7.2.1 resolution: "nopt@npm:7.2.1" @@ -4091,18 +2762,6 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.5.0": - version: 2.5.0 - resolution: "normalize-package-data@npm:2.5.0" - dependencies: - hosted-git-info: "npm:^2.1.4" - resolve: "npm:^1.10.0" - semver: "npm:2 || 3 || 4 || 5" - validate-npm-package-license: "npm:^3.0.1" - checksum: 10c0/357cb1646deb42f8eb4c7d42c4edf0eec312f3628c2ef98501963cc4bbe7277021b2b1d977f982b2edce78f5a1014613ce9cf38085c3df2d76730481357ca504 - languageName: node - linkType: hard - "normalize-package-data@npm:^3.0.2": version: 3.0.3 resolution: "normalize-package-data@npm:3.0.3" @@ -4153,83 +2812,23 @@ __metadata: version: 11.0.3 resolution: "npm-package-arg@npm:11.0.3" dependencies: - hosted-git-info: "npm:^7.0.0" - proc-log: "npm:^4.0.0" - semver: "npm:^7.3.5" - validate-npm-package-name: "npm:^5.0.0" - checksum: 10c0/e18333485e05c3a8774f4b5701ef74f4799533e650b70a68ca8dd697666c9a8d46932cb765fc593edce299521033bd4025a40323d5240cea8a393c784c0c285a - languageName: node - linkType: hard - -"npm-pick-manifest@npm:^9.0.0": - version: 9.1.0 - resolution: "npm-pick-manifest@npm:9.1.0" - dependencies: - npm-install-checks: "npm:^6.0.0" - npm-normalize-package-bin: "npm:^3.0.0" - npm-package-arg: "npm:^11.0.0" - semver: "npm:^7.3.5" - checksum: 10c0/8765f4199755b381323da2bff2202b4b15b59f59dba0d1be3f2f793b591321cd19e1b5a686ef48d9753a6bd4868550da632541a45dfb61809d55664222d73e44 - languageName: node - linkType: hard - -"object-inspect@npm:^1.13.1": - version: 1.13.2 - resolution: "object-inspect@npm:1.13.2" - checksum: 10c0/b97835b4c91ec37b5fd71add84f21c3f1047d1d155d00c0fcd6699516c256d4fcc6ff17a1aced873197fe447f91a3964178fd2a67a1ee2120cdaf60e81a050b4 - languageName: node - linkType: hard - -"object-keys@npm:^1.1.1": - version: 1.1.1 - resolution: "object-keys@npm:1.1.1" - checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d - languageName: node - linkType: hard - -"object.assign@npm:^4.1.5": - version: 4.1.5 - resolution: "object.assign@npm:4.1.5" - dependencies: - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - has-symbols: "npm:^1.0.3" - object-keys: "npm:^1.1.1" - checksum: 10c0/60108e1fa2706f22554a4648299b0955236c62b3685c52abf4988d14fffb0e7731e00aa8c6448397e3eb63d087dcc124a9f21e1980f36d0b2667f3c18bacd469 - languageName: node - linkType: hard - -"object.fromentries@npm:^2.0.7": - version: 2.0.8 - resolution: "object.fromentries@npm:2.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/cd4327e6c3369cfa805deb4cbbe919bfb7d3aeebf0bcaba291bb568ea7169f8f8cdbcabe2f00b40db0c20cd20f08e11b5f3a5a36fb7dd3fe04850c50db3bf83b - languageName: node - linkType: hard - -"object.groupby@npm:^1.0.1": - version: 1.0.3 - resolution: "object.groupby@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - checksum: 10c0/60d0455c85c736fbfeda0217d1a77525956f76f7b2495edeca9e9bbf8168a45783199e77b894d30638837c654d0cc410e0e02cbfcf445bc8de71c3da1ede6a9c + hosted-git-info: "npm:^7.0.0" + proc-log: "npm:^4.0.0" + semver: "npm:^7.3.5" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10c0/e18333485e05c3a8774f4b5701ef74f4799533e650b70a68ca8dd697666c9a8d46932cb765fc593edce299521033bd4025a40323d5240cea8a393c784c0c285a languageName: node linkType: hard -"object.values@npm:^1.1.7": - version: 1.2.0 - resolution: "object.values@npm:1.2.0" +"npm-pick-manifest@npm:^9.0.0": + version: 9.1.0 + resolution: "npm-pick-manifest@npm:9.1.0" dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/15809dc40fd6c5529501324fec5ff08570b7d70fb5ebbe8e2b3901afec35cf2b3dc484d1210c6c642cd3e7e0a5e18dd1d6850115337fef46bdae14ab0cb18ac3 + npm-install-checks: "npm:^6.0.0" + npm-normalize-package-bin: "npm:^3.0.0" + npm-package-arg: "npm:^11.0.0" + semver: "npm:^7.3.5" + checksum: 10c0/8765f4199755b381323da2bff2202b4b15b59f59dba0d1be3f2f793b591321cd19e1b5a686ef48d9753a6bd4868550da632541a45dfb61809d55664222d73e44 languageName: node linkType: hard @@ -4242,29 +2841,6 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.9.3": - version: 0.9.4 - resolution: "optionator@npm:0.9.4" - dependencies: - deep-is: "npm:^0.1.3" - fast-levenshtein: "npm:^2.0.6" - levn: "npm:^0.4.1" - prelude-ls: "npm:^1.2.1" - type-check: "npm:^0.4.0" - word-wrap: "npm:^1.2.5" - checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 - languageName: node - linkType: hard - -"p-limit@npm:^2.2.0": - version: 2.3.0 - resolution: "p-limit@npm:2.3.0" - dependencies: - p-try: "npm:^2.0.0" - checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12 - languageName: node - linkType: hard - "p-limit@npm:^3.0.2": version: 3.1.0 resolution: "p-limit@npm:3.1.0" @@ -4274,15 +2850,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^4.1.0": - version: 4.1.0 - resolution: "p-locate@npm:4.1.0" - dependencies: - p-limit: "npm:^2.2.0" - checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9 - languageName: node - linkType: hard - "p-locate@npm:^5.0.0": version: 5.0.0 resolution: "p-locate@npm:5.0.0" @@ -4310,13 +2877,6 @@ __metadata: languageName: node linkType: hard -"p-try@npm:^2.0.0": - version: 2.2.0 - resolution: "p-try@npm:2.2.0" - checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f - languageName: node - linkType: hard - "package-json-from-dist@npm:^1.0.0": version: 1.0.0 resolution: "package-json-from-dist@npm:1.0.0" @@ -4324,15 +2884,6 @@ __metadata: languageName: node linkType: hard -"parent-module@npm:^1.0.0": - version: 1.0.1 - resolution: "parent-module@npm:1.0.1" - dependencies: - callsites: "npm:^3.0.0" - checksum: 10c0/c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556 - languageName: node - linkType: hard - "parse-entities@npm:^4.0.0": version: 4.0.1 resolution: "parse-entities@npm:4.0.1" @@ -4349,17 +2900,7 @@ __metadata: languageName: node linkType: hard -"parse-imports@npm:^2.1.1": - version: 2.1.1 - resolution: "parse-imports@npm:2.1.1" - dependencies: - es-module-lexer: "npm:^1.5.3" - slashes: "npm:^3.0.12" - checksum: 10c0/c9bb0b4e1823f84f034d2d7bd2b37415b1715a5c963fda14968c706186b48b02c10e97d04bce042b9dcd679b42f29c391ea120799ddf581c7f54786edd99e3a9 - languageName: node - linkType: hard - -"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": +"parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -4405,13 +2946,6 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.7": - version: 1.0.7 - resolution: "path-parse@npm:1.0.7" - checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 - languageName: node - linkType: hard - "path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" @@ -4450,7 +2984,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": +"picocolors@npm:^1.0.0": version: 1.0.1 resolution: "picocolors@npm:1.0.1" checksum: 10c0/c63cdad2bf812ef0d66c8db29583802355d4ca67b9285d846f390cc15c2f6ccb94e8cb7eb6a6e97fc5990a6d3ad4ae42d86c84d3146e667c739a4234ed50d400 @@ -4471,20 +3005,6 @@ __metadata: languageName: node linkType: hard -"possible-typed-array-names@npm:^1.0.0": - version: 1.0.0 - resolution: "possible-typed-array-names@npm:1.0.0" - checksum: 10c0/d9aa22d31f4f7680e20269db76791b41c3a32c01a373e25f8a4813b4d45f7456bfc2b6d68f752dc4aab0e0bb0721cb3d76fb678c9101cb7a16316664bc2c73fd - languageName: node - linkType: hard - -"prelude-ls@npm:^1.2.1": - version: 1.2.1 - resolution: "prelude-ls@npm:1.2.1" - checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd - languageName: node - linkType: hard - "prettier@npm:^3.3.3": version: 3.3.3 resolution: "prettier@npm:3.3.3" @@ -4518,13 +3038,6 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0": - version: 2.3.1 - resolution: "punycode@npm:2.3.1" - checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 - languageName: node - linkType: hard - "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -4565,17 +3078,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^7.0.1": - version: 7.0.1 - resolution: "read-pkg-up@npm:7.0.1" - dependencies: - find-up: "npm:^4.1.0" - read-pkg: "npm:^5.2.0" - type-fest: "npm:^0.8.1" - checksum: 10c0/82b3ac9fd7c6ca1bdc1d7253eb1091a98ff3d195ee0a45386582ce3e69f90266163c34121e6a0a02f1630073a6c0585f7880b3865efcae9c452fa667f02ca385 - languageName: node - linkType: hard - "read-pkg-up@npm:^8.0.0": version: 8.0.0 resolution: "read-pkg-up@npm:8.0.0" @@ -4587,18 +3089,6 @@ __metadata: languageName: node linkType: hard -"read-pkg@npm:^5.2.0": - version: 5.2.0 - resolution: "read-pkg@npm:5.2.0" - dependencies: - "@types/normalize-package-data": "npm:^2.4.0" - normalize-package-data: "npm:^2.5.0" - parse-json: "npm:^5.0.0" - type-fest: "npm:^0.6.0" - checksum: 10c0/b51a17d4b51418e777029e3a7694c9bd6c578a5ab99db544764a0b0f2c7c0f58f8a6bc101f86a6fceb8ba6d237d67c89acf6170f6b98695d0420ddc86cf109fb - languageName: node - linkType: hard - "read-pkg@npm:^6.0.0": version: 6.0.0 resolution: "read-pkg@npm:6.0.0" @@ -4641,45 +3131,6 @@ __metadata: languageName: node linkType: hard -"regexp-tree@npm:^0.1.27": - version: 0.1.27 - resolution: "regexp-tree@npm:0.1.27" - bin: - regexp-tree: bin/regexp-tree - checksum: 10c0/f636f44b4a0d93d7d6926585ecd81f63e4ce2ac895bc417b2ead0874cd36b337dcc3d0fedc63f69bf5aaeaa4340f36ca7e750c9687cceaf8087374e5284e843c - languageName: node - linkType: hard - -"regexp.prototype.flags@npm:^1.5.2": - version: 1.5.2 - resolution: "regexp.prototype.flags@npm:1.5.2" - dependencies: - call-bind: "npm:^1.0.6" - define-properties: "npm:^1.2.1" - es-errors: "npm:^1.3.0" - set-function-name: "npm:^2.0.1" - checksum: 10c0/0f3fc4f580d9c349f8b560b012725eb9c002f36daa0041b3fbf6f4238cb05932191a4d7d5db3b5e2caa336d5150ad0402ed2be81f711f9308fe7e1a9bf9bd552 - languageName: node - linkType: hard - -"regexpp@npm:^3.0.0": - version: 3.2.0 - resolution: "regexpp@npm:3.2.0" - checksum: 10c0/d1da82385c8754a1681416b90b9cca0e21b4a2babef159099b88f640637d789c69011d0bc94705dacab85b81133e929d027d85210e8b8b03f8035164dbc14710 - languageName: node - linkType: hard - -"regjsparser@npm:^0.10.0": - version: 0.10.0 - resolution: "regjsparser@npm:0.10.0" - dependencies: - jsesc: "npm:~0.5.0" - bin: - regjsparser: bin/parser - checksum: 10c0/0f0508c142eddbceae55dab9715e714305c19e1e130db53168e8fa5f9f7ff9a4901f674cf6f71e04a0973b2f883882ba05808c80778b2d52b053d925050010f4 - languageName: node - linkType: hard - "remark-cli@npm:^12.0.1": version: 12.0.1 resolution: "remark-cli@npm:12.0.1" @@ -5380,46 +3831,6 @@ __metadata: languageName: node linkType: hard -"resolve-from@npm:^4.0.0": - version: 4.0.0 - resolution: "resolve-from@npm:4.0.0" - checksum: 10c0/8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190 - languageName: node - linkType: hard - -"resolve-pkg-maps@npm:^1.0.0": - version: 1.0.0 - resolution: "resolve-pkg-maps@npm:1.0.0" - checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab - languageName: node - linkType: hard - -"resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.22.4": - version: 1.22.8 - resolution: "resolve@npm:1.22.8" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10c0/07e179f4375e1fd072cfb72ad66d78547f86e6196c4014b31cb0b8bb1db5f7ca871f922d08da0fbc05b94e9fd42206f819648fa3b5b873ebbc8e1dc68fec433a - languageName: node - linkType: hard - -"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.10.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": - version: 1.22.8 - resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10c0/0446f024439cd2e50c6c8fa8ba77eaa8370b4180f401a96abf3d1ebc770ac51c1955e12764cde449fde3fff480a61f84388e3505ecdbab778f4bef5f8212c729 - languageName: node - linkType: hard - "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -5454,18 +3865,6 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.1.2": - version: 1.1.2 - resolution: "safe-array-concat@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.7" - get-intrinsic: "npm:^1.2.4" - has-symbols: "npm:^1.0.3" - isarray: "npm:^2.0.5" - checksum: 10c0/12f9fdb01c8585e199a347eacc3bae7b5164ae805cdc8c6707199dbad5b9e30001a50a43c4ee24dc9ea32dbb7279397850e9208a7e217f4d8b1cf5d90129dec9 - languageName: node - linkType: hard - "safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" @@ -5473,17 +3872,6 @@ __metadata: languageName: node linkType: hard -"safe-regex-test@npm:^1.0.3": - version: 1.0.3 - resolution: "safe-regex-test@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-regex: "npm:^1.1.4" - checksum: 10c0/900bf7c98dc58f08d8523b7012b468e4eb757afa624f198902c0643d7008ba777b0bdc35810ba0b758671ce887617295fb742b3f3968991b178ceca54cb07603 - languageName: node - linkType: hard - "safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -5491,25 +3879,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 - languageName: node - linkType: hard - -"semver@npm:^6.1.0, semver@npm:^6.3.1": - version: 6.3.1 - resolution: "semver@npm:6.3.1" - bin: - semver: bin/semver.js - checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d - languageName: node - linkType: hard - -"semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.6.1, semver@npm:^7.6.3": +"semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -5527,32 +3897,6 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1": - version: 1.2.2 - resolution: "set-function-length@npm:1.2.2" - dependencies: - define-data-property: "npm:^1.1.4" - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.2" - checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c - languageName: node - linkType: hard - -"set-function-name@npm:^2.0.1": - version: 2.0.2 - resolution: "set-function-name@npm:2.0.2" - dependencies: - define-data-property: "npm:^1.1.4" - es-errors: "npm:^1.3.0" - functions-have-names: "npm:^1.2.3" - has-property-descriptors: "npm:^1.0.2" - checksum: 10c0/fce59f90696c450a8523e754abb305e2b8c73586452619c2bad5f7bf38c7b6b4651895c9db895679c5bef9554339cf3ef1c329b66ece3eda7255785fbe299316 - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -5569,18 +3913,6 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.6 - resolution: "side-channel@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - object-inspect: "npm:^1.13.1" - checksum: 10c0/d2afd163dc733cc0a39aa6f7e39bf0c436293510dbccbff446733daeaf295857dbccf94297092ec8c53e2503acac30f0b78830876f0485991d62a90e9cad305f - languageName: node - linkType: hard - "signal-exit@npm:^4.0.1": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" @@ -5588,13 +3920,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^3.0.0": - version: 3.0.0 - resolution: "slash@npm:3.0.0" - checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b - languageName: node - linkType: hard - "slash@npm:^4.0.0": version: 4.0.0 resolution: "slash@npm:4.0.0" @@ -5602,13 +3927,6 @@ __metadata: languageName: node linkType: hard -"slashes@npm:^3.0.12": - version: 3.0.12 - resolution: "slashes@npm:3.0.12" - checksum: 10c0/71ca2a1fcd1ab6814b0fdb8cf9c33a3d54321deec2aa8d173510f0086880201446021a9b9e6a18561f7c472b69a2145977c6a8fb9c53a8ff7be31778f203d175 - languageName: node - linkType: hard - "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -5671,16 +3989,6 @@ __metadata: languageName: node linkType: hard -"spdx-expression-parse@npm:^4.0.0": - version: 4.0.0 - resolution: "spdx-expression-parse@npm:4.0.0" - dependencies: - spdx-exceptions: "npm:^2.1.0" - spdx-license-ids: "npm:^3.0.0" - checksum: 10c0/965c487e77f4fb173f1c471f3eef4eb44b9f0321adc7f93d95e7620da31faa67d29356eb02523cd7df8a7fc1ec8238773cdbf9e45bd050329d2b26492771b736 - languageName: node - linkType: hard - "spdx-license-ids@npm:^3.0.0": version: 3.0.18 resolution: "spdx-license-ids@npm:3.0.18" @@ -5737,40 +4045,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.9": - version: 1.2.9 - resolution: "string.prototype.trim@npm:1.2.9" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.0" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/dcef1a0fb61d255778155006b372dff8cc6c4394bc39869117e4241f41a2c52899c0d263ffc7738a1f9e61488c490b05c0427faa15151efad721e1a9fb2663c2 - languageName: node - linkType: hard - -"string.prototype.trimend@npm:^1.0.8": - version: 1.0.8 - resolution: "string.prototype.trimend@npm:1.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/0a0b54c17c070551b38e756ae271865ac6cc5f60dabf2e7e343cceae7d9b02e1a1120a824e090e79da1b041a74464e8477e2da43e2775c85392be30a6f60963c - languageName: node - linkType: hard - -"string.prototype.trimstart@npm:^1.0.8": - version: 1.0.8 - resolution: "string.prototype.trimstart@npm:1.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/d53af1899959e53c83b64a5fd120be93e067da740e7e75acb433849aa640782fb6c7d4cd5b84c954c84413745a3764df135a8afeb22908b86a835290788d8366 - languageName: node - linkType: hard - "string_decoder@npm:^1.1.1": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" @@ -5808,22 +4082,6 @@ __metadata: languageName: node linkType: hard -"strip-bom@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-bom@npm:3.0.0" - checksum: 10c0/51201f50e021ef16672593d7434ca239441b7b760e905d9f33df6e4f3954ff54ec0e0a06f100d028af0982d6f25c35cd5cda2ce34eaebccd0250b8befb90d8f1 - languageName: node - linkType: hard - -"strip-indent@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-indent@npm:3.0.0" - dependencies: - min-indent: "npm:^1.0.0" - checksum: 10c0/ae0deaf41c8d1001c5d4fbe16cb553865c1863da4fae036683b474fa926af9fc121e155cb3fc57a68262b2ae7d5b8420aa752c97a6428c315d00efe2a3875679 - languageName: node - linkType: hard - "strip-indent@npm:^4.0.0": version: 4.0.0 resolution: "strip-indent@npm:4.0.0" @@ -5894,30 +4152,6 @@ __metadata: languageName: node linkType: hard -"supports-preserve-symlinks-flag@npm:^1.0.0": - version: 1.0.0 - resolution: "supports-preserve-symlinks-flag@npm:1.0.0" - checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39 - languageName: node - linkType: hard - -"synckit@npm:^0.9.1": - version: 0.9.1 - resolution: "synckit@npm:0.9.1" - dependencies: - "@pkgr/core": "npm:^0.1.0" - tslib: "npm:^2.6.2" - checksum: 10c0/d8b89e1bf30ba3ffb469d8418c836ad9c0c062bf47028406b4d06548bc66af97155ea2303b96c93bf5c7c0f0d66153a6fbd6924c76521b434e6a9898982abc2e - languageName: node - linkType: hard - -"tapable@npm:^2.2.0": - version: 2.2.1 - resolution: "tapable@npm:2.2.1" - checksum: 10c0/bc40e6efe1e554d075469cedaba69a30eeb373552aaf41caeaaa45bf56ffacc2674261b106245bd566b35d8f3329b52d838e851ee0a852120acae26e622925c9 - languageName: node - linkType: hard - "tar@npm:^6.1.11, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" @@ -5983,15 +4217,6 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.3.0": - version: 1.3.0 - resolution: "ts-api-utils@npm:1.3.0" - peerDependencies: - typescript: ">=4.2.0" - checksum: 10c0/f54a0ba9ed56ce66baea90a3fa087a484002e807f28a8ccb2d070c75e76bde64bd0f6dce98b3802834156306050871b67eec325cb4e918015a360a3f0868c77c - languageName: node - linkType: hard - "ts-node@npm:^10.9.2": version: 10.9.2 resolution: "ts-node@npm:10.9.2" @@ -6030,48 +4255,6 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^3.15.0": - version: 3.15.0 - resolution: "tsconfig-paths@npm:3.15.0" - dependencies: - "@types/json5": "npm:^0.0.29" - json5: "npm:^1.0.2" - minimist: "npm:^1.2.6" - strip-bom: "npm:^3.0.0" - checksum: 10c0/5b4f301a2b7a3766a986baf8fc0e177eb80bdba6e396792ff92dc23b5bca8bb279fc96517dcaaef63a3b49bebc6c4c833653ec58155780bc906bdbcf7dda0ef5 - languageName: node - linkType: hard - -"tslib@npm:^2.6.2": - version: 2.6.3 - resolution: "tslib@npm:2.6.3" - checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a - languageName: node - linkType: hard - -"type-check@npm:^0.4.0, type-check@npm:~0.4.0": - version: 0.4.0 - resolution: "type-check@npm:0.4.0" - dependencies: - prelude-ls: "npm:^1.2.1" - checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 - languageName: node - linkType: hard - -"type-fest@npm:^0.6.0": - version: 0.6.0 - resolution: "type-fest@npm:0.6.0" - checksum: 10c0/0c585c26416fce9ecb5691873a1301b5aff54673c7999b6f925691ed01f5b9232db408cdbb0bd003d19f5ae284322523f44092d1f81ca0a48f11f7cf0be8cd38 - languageName: node - linkType: hard - -"type-fest@npm:^0.8.1": - version: 0.8.1 - resolution: "type-fest@npm:0.8.1" - checksum: 10c0/dffbb99329da2aa840f506d376c863bd55f5636f4741ad6e65e82f5ce47e6914108f44f340a0b74009b0cb5d09d6752ae83203e53e98b1192cf80ecee5651636 - languageName: node - linkType: hard - "type-fest@npm:^1.0.1, type-fest@npm:^1.2.1, type-fest@npm:^1.2.2": version: 1.4.0 resolution: "type-fest@npm:1.4.0" @@ -6086,58 +4269,6 @@ __metadata: languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-buffer@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-typed-array: "npm:^1.1.13" - checksum: 10c0/9e043eb38e1b4df4ddf9dde1aa64919ae8bb909571c1cc4490ba777d55d23a0c74c7d73afcdd29ec98616d91bb3ae0f705fad4421ea147e1daf9528200b562da - languageName: node - linkType: hard - -"typed-array-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "typed-array-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10c0/fcebeffb2436c9f355e91bd19e2368273b88c11d1acc0948a2a306792f1ab672bce4cfe524ab9f51a0505c9d7cd1c98eff4235c4f6bfef6a198f6cfc4ff3d4f3 - languageName: node - linkType: hard - -"typed-array-byte-offset@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-byte-offset@npm:1.0.2" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10c0/d2628bc739732072e39269389a758025f75339de2ed40c4f91357023c5512d237f255b633e3106c461ced41907c1bf9a533c7e8578066b0163690ca8bc61b22f - languageName: node - linkType: hard - -"typed-array-length@npm:^1.0.6": - version: 1.0.6 - resolution: "typed-array-length@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - possible-typed-array-names: "npm:^1.0.0" - checksum: 10c0/74253d7dc488eb28b6b2711cf31f5a9dcefc9c41b0681fd1c178ed0a1681b4468581a3626d39cd4df7aee3d3927ab62be06aa9ca74e5baf81827f61641445b77 - languageName: node - linkType: hard - "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" @@ -6172,18 +4303,6 @@ __metadata: languageName: node linkType: hard -"unbox-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "unbox-primitive@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - has-bigints: "npm:^1.0.2" - has-symbols: "npm:^1.0.3" - which-boxed-primitive: "npm:^1.0.2" - checksum: 10c0/81ca2e81134167cc8f75fa79fbcc8a94379d6c61de67090986a2273850989dd3bae8440c163121b77434b68263e34787a675cbdcb34bb2f764c6b9c843a11b66 - languageName: node - linkType: hard - "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" @@ -6379,29 +4498,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.0": - version: 1.1.0 - resolution: "update-browserslist-db@npm:1.1.0" - dependencies: - escalade: "npm:^3.1.2" - picocolors: "npm:^1.0.1" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10c0/a7452de47785842736fb71547651c5bbe5b4dc1e3722ccf48a704b7b34e4dcf633991eaa8e4a6a517ffb738b3252eede3773bef673ef9021baa26b056d63a5b9 - languageName: node - linkType: hard - -"uri-js@npm:^4.2.2": - version: 4.4.1 - resolution: "uri-js@npm:4.4.1" - dependencies: - punycode: "npm:^2.1.0" - checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c - languageName: node - linkType: hard - "util-deprecate@npm:^1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -6518,32 +4614,6 @@ __metadata: languageName: node linkType: hard -"which-boxed-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "which-boxed-primitive@npm:1.0.2" - dependencies: - is-bigint: "npm:^1.0.1" - is-boolean-object: "npm:^1.1.0" - is-number-object: "npm:^1.0.4" - is-string: "npm:^1.0.5" - is-symbol: "npm:^1.0.3" - checksum: 10c0/0a62a03c00c91dd4fb1035b2f0733c341d805753b027eebd3a304b9cb70e8ce33e25317add2fe9b5fea6f53a175c0633ae701ff812e604410ddd049777cd435e - languageName: node - linkType: hard - -"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15": - version: 1.1.15 - resolution: "which-typed-array@npm:1.1.15" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-tostringtag: "npm:^1.0.2" - checksum: 10c0/4465d5348c044032032251be54d8988270e69c6b7154f8fcb2a47ff706fe36f7624b3a24246b8d9089435a8f4ec48c1c1025c5d6b499456b9e5eff4f48212983 - languageName: node - linkType: hard - "which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" @@ -6566,13 +4636,6 @@ __metadata: languageName: node linkType: hard -"word-wrap@npm:^1.2.5": - version: 1.2.5 - resolution: "word-wrap@npm:1.2.5" - checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 - languageName: node - linkType: hard - "workerpool@npm:^6.5.1": version: 6.5.1 resolution: "workerpool@npm:6.5.1"