@markuplint/file-resolver
Advanced tools
Comparing version 4.0.0-alpha.3 to 4.0.0-dev.28
@@ -23,4 +23,4 @@ import { MLRule } from '@markuplint/ml-core'; | ||
} | ||
catch (e) { | ||
errors.push(e); | ||
catch (error) { | ||
errors.push(error); | ||
} | ||
@@ -43,4 +43,4 @@ if (seed) { | ||
} | ||
catch (e) { | ||
errors.push(e); | ||
catch (error) { | ||
errors.push(error); | ||
} | ||
@@ -59,6 +59,6 @@ if (seed) { | ||
// Clone | ||
rules: rules.slice(), | ||
rules: [...rules], | ||
// Clone | ||
errors: errors.slice(), | ||
errors: [...errors], | ||
}; | ||
} |
@@ -7,2 +7,6 @@ import type { MLFile } from './ml-file/index.js'; | ||
#private; | ||
recursiveLoad(key: string, cache: boolean, referrer: string, depth?: number): Promise<{ | ||
stack: Set<string>; | ||
errs: Error[]; | ||
}>; | ||
resolve(targetFile: Readonly<MLFile>, names: readonly Nullable<string>[], cache?: boolean): Promise<ConfigSet>; | ||
@@ -14,4 +18,3 @@ search(targetFile: Readonly<MLFile>): Promise<string | null>; | ||
private _pathResolve; | ||
private _recursiveLoad; | ||
private _validateConfig; | ||
} |
@@ -0,3 +1,7 @@ | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _ConfigProvider_cache, _ConfigProvider_held, _ConfigProvider_recursiveLoadKeyAndDepth, _ConfigProvider_store; | ||
import { __classPrivateFieldGet } from "tslib"; | ||
import { createRequire } from 'node:module'; | ||
@@ -10,3 +14,3 @@ import path from 'node:path'; | ||
import { nonNullableFilter, toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared'; | ||
import { load as loadConfig, search } from './cosmiconfig.js'; | ||
import { ConfigLoadError, load as loadConfig, search } from './cosmiconfig.js'; | ||
import { log } from './debug.js'; | ||
@@ -25,2 +29,40 @@ import { cacheClear, resolvePlugins } from './resolve-plugins.js'; | ||
} | ||
async recursiveLoad(key, cache, referrer, depth = 1) { | ||
const stack = new Set(); | ||
const errs = []; | ||
const ancestorDepth = __classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").get(key); | ||
if (ancestorDepth != null && ancestorDepth < depth) { | ||
return { | ||
stack, | ||
errs: [new CircularReferenceError(`Circular reference detected: ${key}`)], | ||
}; | ||
} | ||
__classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").set(key, depth); | ||
let config = __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(key); | ||
if (!config) { | ||
config = await this._load(key, cache, referrer); | ||
} | ||
if (!config) { | ||
return { stack, errs: [] }; | ||
} | ||
if (config instanceof ConfigLoadError) { | ||
stack.add(config.filePath); | ||
return { | ||
stack, | ||
errs: [config], | ||
}; | ||
} | ||
const depKeys = config.extends === null ? null : toNoEmptyStringArrayFromStringOrArray(config.extends); | ||
if (depKeys) { | ||
for (const depKey of depKeys) { | ||
const keys = await this.recursiveLoad(depKey, cache, key, depth + 1); | ||
for (const key of keys.stack) { | ||
stack.add(key); | ||
} | ||
errs.push(...keys.errs); | ||
} | ||
} | ||
stack.add(key); | ||
return { stack, errs }; | ||
} | ||
async resolve(targetFile, names, cache = true) { | ||
@@ -38,4 +80,4 @@ if (!cache) { | ||
} | ||
let configSet = await this._mergeConfigs(keys, cache); | ||
const filePath = Array.from(configSet.files).reverse()[0]; | ||
let configSet = await this._mergeConfigs(keys, cache, targetFile.path); | ||
const filePath = [...configSet.files].reverse()[0]; | ||
if (!filePath) { | ||
@@ -50,3 +92,3 @@ throw new ConfigParserError('Config file not found', { | ||
if (__classPrivateFieldGet(this, _ConfigProvider_held, "f").size > 0) { | ||
const extendHelds = Array.from(__classPrivateFieldGet(this, _ConfigProvider_held, "f").values()); | ||
const extendHelds = [...__classPrivateFieldGet(this, _ConfigProvider_held, "f").values()]; | ||
for (const held of extendHelds) { | ||
@@ -65,3 +107,3 @@ const [, prefix, namespace, name] = held.match(/^([a-z]+:)([^/]+)(?:\/(.+))?$/) ?? []; | ||
} | ||
configSet = await this._mergeConfigs([...keys, ...extendHelds], cache); | ||
configSet = await this._mergeConfigs([...keys, ...extendHelds], cache, targetFile.path); | ||
__classPrivateFieldGet(this, _ConfigProvider_held, "f").clear(); | ||
@@ -112,3 +154,3 @@ } | ||
} | ||
async _load(filePath, cache) { | ||
async _load(filePath, cache, referrer) { | ||
const entity = __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(filePath); | ||
@@ -127,3 +169,3 @@ if (entity) { | ||
__classPrivateFieldGet(this, _ConfigProvider_held, "f").add(filePath); | ||
return null; | ||
return; | ||
} | ||
@@ -133,5 +175,5 @@ if (!(await moduleExists(filePath)) && !path.isAbsolute(filePath)) { | ||
} | ||
const config = await load(filePath, cache); | ||
if (!config) { | ||
return null; | ||
const config = await load(filePath, cache, referrer); | ||
if (config instanceof ConfigLoadError) { | ||
return config; | ||
} | ||
@@ -142,3 +184,3 @@ const pathResolvedConfig = await this._pathResolve(config, filePath); | ||
} | ||
async _mergeConfigs(keys, cache) { | ||
async _mergeConfigs(keys, cache, referrer) { | ||
const resolvedKeys = new Set(); | ||
@@ -148,15 +190,15 @@ const errs = []; | ||
__classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").clear(); | ||
const keySet = await this._recursiveLoad(key, cache); | ||
const keySet = await this.recursiveLoad(key, cache, referrer); | ||
for (const k of keySet.stack) { | ||
resolvedKeys.add(k); | ||
} | ||
if (keySet.errs) { | ||
errs.push(...keySet.errs); | ||
} | ||
errs.push(...keySet.errs); | ||
} | ||
const configs = Array.from(resolvedKeys) | ||
.map(name => __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(name)) | ||
.filter(nonNullableFilter); | ||
const configs = [...resolvedKeys].map(name => __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(name)).filter(nonNullableFilter); | ||
let resultConfig = {}; | ||
for (const config of configs) { | ||
if (config instanceof ConfigLoadError) { | ||
errs.push(config); | ||
continue; | ||
} | ||
resultConfig = mergeConfig(resultConfig, config); | ||
@@ -182,52 +224,20 @@ } | ||
} | ||
async _recursiveLoad(key, cache, depth = 1) { | ||
const stack = new Set(); | ||
const errs = []; | ||
const ancestorDepth = __classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").get(key); | ||
if (ancestorDepth != null && ancestorDepth < depth) { | ||
return { | ||
stack, | ||
errs: [new CircularReferenceError(`Circular reference detected: ${key}`)], | ||
}; | ||
} | ||
__classPrivateFieldGet(this, _ConfigProvider_recursiveLoadKeyAndDepth, "f").set(key, depth); | ||
let config = __classPrivateFieldGet(this, _ConfigProvider_store, "f").get(key) ?? null; | ||
if (!config) { | ||
config = await this._load(key, cache); | ||
} | ||
if (!config) { | ||
return { stack, errs: null }; | ||
} | ||
const depKeys = config.extends !== null ? toNoEmptyStringArrayFromStringOrArray(config.extends) : null; | ||
if (depKeys) { | ||
for (const depKey of depKeys) { | ||
const keys = await this._recursiveLoad(depKey, cache, depth + 1); | ||
for (const key of keys.stack) { | ||
stack.add(key); | ||
} | ||
if (keys.errs) { | ||
errs.push(...keys.errs); | ||
} | ||
} | ||
} | ||
stack.add(key); | ||
return { stack, errs }; | ||
} | ||
_validateConfig(config, filePath) { | ||
const errors = []; | ||
config.nodeRules?.forEach(rule => { | ||
if (rule.selector) { | ||
try { | ||
createSelector(rule.selector); | ||
} | ||
catch (error) { | ||
if (error instanceof InvalidSelectorError) { | ||
errors.push(new ConfigParserError(error.message, { | ||
filePath, | ||
raw: rule.selector, | ||
})); | ||
if (config.nodeRules) | ||
for (const rule of config.nodeRules) { | ||
if (rule.selector) { | ||
try { | ||
createSelector(rule.selector); | ||
} | ||
catch (error) { | ||
if (error instanceof InvalidSelectorError) { | ||
errors.push(new ConfigParserError(error.message, { | ||
filePath, | ||
raw: rule.selector, | ||
})); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
return errors; | ||
@@ -237,11 +247,16 @@ } | ||
_ConfigProvider_cache = new WeakMap(), _ConfigProvider_held = new WeakMap(), _ConfigProvider_recursiveLoadKeyAndDepth = new WeakMap(), _ConfigProvider_store = new WeakMap(); | ||
async function load(filePath, cache) { | ||
async function load(filePath, cache, referrer) { | ||
if (!fileExists(filePath) && (await moduleExists(filePath))) { | ||
const mod = await import(filePath); | ||
const config = mod?.default ?? null; | ||
const config = mod?.default ?? new ConfigLoadError('Module is not found', filePath, referrer); | ||
return config; | ||
} | ||
const res = await loadConfig(filePath, !cache); | ||
if (!res) { | ||
return null; | ||
const res = await loadConfig(filePath, !cache, referrer).catch((error) => { | ||
if (error instanceof ConfigLoadError) { | ||
return error; | ||
} | ||
throw error; | ||
}); | ||
if (res instanceof ConfigLoadError) { | ||
return res; | ||
} | ||
@@ -301,7 +316,5 @@ return res.config; | ||
} | ||
catch (err) { | ||
if (err instanceof Error) { | ||
if (/^Parse failure/i.test(err.message)) { | ||
return true; | ||
} | ||
catch (error) { | ||
if (error instanceof Error && /^parse failure/i.test(error.message)) { | ||
return true; | ||
} | ||
@@ -311,8 +324,8 @@ try { | ||
} | ||
catch (err) { | ||
catch (error) { | ||
if ( | ||
// @ts-ignore | ||
'code' in err && | ||
'code' in error && | ||
// @ts-ignore | ||
err.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') { | ||
error.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') { | ||
// Even if there are issues with the fields, | ||
@@ -324,8 +337,8 @@ // assume that the module exists and return true. | ||
// @ts-ignore | ||
'code' in err && | ||
'code' in error && | ||
// @ts-ignore | ||
err.code === 'MODULE_NOT_FOUND') { | ||
error.code === 'MODULE_NOT_FOUND') { | ||
return false; | ||
} | ||
throw err; | ||
throw error; | ||
} | ||
@@ -332,0 +345,0 @@ } |
import type { LoaderSync } from 'cosmiconfig'; | ||
type CosmiConfig = ReturnType<LoaderSync>; | ||
export declare function search<T = CosmiConfig>(dir: string, cacheClear: boolean): Promise<{ | ||
export declare function search<T = CosmiConfig>(filePath: string, cacheClear: boolean): Promise<{ | ||
filePath: string; | ||
config: T; | ||
} | null>; | ||
export declare function load<T = CosmiConfig>(filePath: string, cacheClear: boolean): Promise<{ | ||
export declare function load<T = CosmiConfig>(filePath: string, cacheClear: boolean, referrer: string): Promise<ConfigLoadError | { | ||
filePath: string; | ||
config: T; | ||
} | null>; | ||
}>; | ||
export declare class ConfigLoadError extends Error { | ||
filePath: string; | ||
name: string; | ||
referrer: string; | ||
constructor(message: string, filePath: string, referrer: string); | ||
} | ||
export {}; |
@@ -22,9 +22,9 @@ import path from 'node:path'; | ||
}); | ||
export async function search(dir, cacheClear) { | ||
export async function search(filePath, cacheClear) { | ||
if (cacheClear) { | ||
explorer.clearCaches(); | ||
} | ||
dir = path.dirname(dir); | ||
const dir = path.dirname(filePath); | ||
searchLog('Search dir: %s', dir); | ||
const result = await explorer.search(dir).catch(cacheConfigError(dir)); | ||
const result = await explorer.search(dir).catch(cacheConfigError(dir, filePath)); | ||
searchLog('Search result: %O', result); | ||
@@ -39,9 +39,9 @@ if (!result || result.isEmpty) { | ||
} | ||
export async function load(filePath, cacheClear) { | ||
export async function load(filePath, cacheClear, referrer) { | ||
if (cacheClear) { | ||
explorer.clearCaches(); | ||
} | ||
const result = await explorer.load(filePath).catch(cacheConfigError(filePath)); | ||
const result = await explorer.load(filePath).catch(cacheConfigError(filePath, referrer)); | ||
if (!result || result.isEmpty) { | ||
return null; | ||
return new ConfigLoadError('Config file is empty', filePath, referrer); | ||
} | ||
@@ -53,13 +53,15 @@ return { | ||
} | ||
class ConfigLoadError extends Error { | ||
constructor(message, filePath) { | ||
super(message + ` in ${filePath}`); | ||
export class ConfigLoadError extends Error { | ||
constructor(message, filePath, referrer) { | ||
super(message + ` in ${referrer}`); | ||
this.name = 'ConfigLoadError'; | ||
this.filePath = filePath; | ||
this.referrer = referrer; | ||
} | ||
} | ||
function cacheConfigError(fileOrDirPath) { | ||
function cacheConfigError(fileOrDirPath, referrer) { | ||
return (reason) => { | ||
if (reason instanceof Error) { | ||
switch (reason.name) { | ||
case 'YAMLException': | ||
case 'YAMLException': { | ||
throw new ConfigParserError(reason.message, { | ||
@@ -69,4 +71,5 @@ // @ts-ignore | ||
}); | ||
} | ||
} | ||
throw new ConfigLoadError(reason.message, fileOrDirPath); | ||
throw new ConfigLoadError(reason.message, fileOrDirPath, referrer); | ||
} | ||
@@ -73,0 +76,0 @@ throw reason; |
@@ -0,3 +1,13 @@ | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _MLFile_basename, _MLFile_code, _MLFile_dirname, _MLFile_stat, _MLFile_type; | ||
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; | ||
import { promises as fs } from 'node:fs'; | ||
@@ -99,3 +109,3 @@ import path from 'node:path'; | ||
async _fetch() { | ||
const code = await fs.readFile(this.path, { encoding: 'utf-8' }); | ||
const code = await fs.readFile(this.path, { encoding: 'utf8' }); | ||
__classPrivateFieldSet(this, _MLFile_code, code, "f"); | ||
@@ -117,11 +127,11 @@ return code; | ||
} | ||
catch (err) { | ||
catch (error) { | ||
if ( | ||
// @ts-ignore | ||
'code' in err && | ||
'code' in error && | ||
// @ts-ignore | ||
err.code === 'ENOENT') { | ||
error.code === 'ENOENT') { | ||
return null; | ||
} | ||
throw err; | ||
throw error; | ||
} | ||
@@ -128,0 +138,0 @@ } |
@@ -13,2 +13,3 @@ import path from 'node:path'; | ||
for (const pattern of Object.keys(parserConfig)) { | ||
// eslint-disable-next-line unicorn/prefer-regexp-test | ||
if (path.basename(file.path).match(toRegexp(pattern))) { | ||
@@ -15,0 +16,0 @@ const modName = parserConfig[pattern]; |
@@ -8,3 +8,3 @@ const cache = new Map(); | ||
// Clone | ||
return plugins.slice(); | ||
return [...plugins]; | ||
} | ||
@@ -36,3 +36,3 @@ export function cacheClear() { | ||
.replace(/^(?:markuplint-rule-|@markuplint\/rule-)/i, '') | ||
.replace(/\s+|\/|\\|\./g, '-'); | ||
.replaceAll(/\s+|\/|\\|\./g, '-'); | ||
// eslint-disable-next-line no-console | ||
@@ -53,3 +53,3 @@ console.info(`The plugin name became "${name}"`); | ||
async function failSafeImport(name) { | ||
const res = await import(name).catch(e => e); | ||
const res = await import(name).catch(error => error); | ||
if ('code' in res && res === 'MODULE_NOT_FOUND') { | ||
@@ -56,0 +56,0 @@ return null; |
@@ -10,7 +10,7 @@ import { MLRule } from '@markuplint/ml-core'; | ||
const rules = importPreset ? await importPresetRules() : []; | ||
plugins.forEach(plugin => { | ||
for (const plugin of plugins) { | ||
if (!plugin.rules) { | ||
return; | ||
continue; | ||
} | ||
Object.entries(plugin.rules).forEach(([name, seed]) => { | ||
for (const [name, seed] of Object.entries(plugin.rules)) { | ||
const rule = new MLRule({ | ||
@@ -21,16 +21,16 @@ name: `${plugin.name}/${name}`, | ||
rules.push(rule); | ||
}); | ||
}); | ||
} | ||
} | ||
if (autoLoad) { | ||
const { rules: additionalRules } = await autoLoadRules(ruleset); | ||
additionalRules.forEach(rule => { | ||
for (const rule of additionalRules) { | ||
rules.push(rule); | ||
}); | ||
} | ||
} | ||
// Clone | ||
return rules.slice(); | ||
return [...rules]; | ||
} | ||
async function importPresetRules() { | ||
if (cachedPresetRules) { | ||
return cachedPresetRules.slice(); | ||
return [...cachedPresetRules]; | ||
} | ||
@@ -49,3 +49,3 @@ const modName = '@markuplint/rules'; | ||
// Clone | ||
return ruleList.slice(); | ||
return [...ruleList]; | ||
} |
@@ -44,2 +44,3 @@ import path from 'node:path'; | ||
for (const pattern of Object.keys(specConfig)) { | ||
// eslint-disable-next-line unicorn/prefer-regexp-test | ||
if (path.basename(filePath).match(toRegexp(pattern))) { | ||
@@ -69,3 +70,4 @@ const specModName = specConfig[pattern]; | ||
} | ||
const spec = (await import(specModName)).default; | ||
const mod = await import(specModName); | ||
const spec = mod.default; | ||
// @ts-ignore | ||
@@ -72,0 +74,0 @@ caches.set(specModName, spec); |
@@ -12,3 +12,3 @@ import fs from 'node:fs'; | ||
export function toRegexp(pattern) { | ||
const matched = pattern.match(/^\/(.+)\/([ig]*)$/i); | ||
const matched = pattern.match(/^\/(.+)\/([gi]*)$/i); | ||
if (matched && matched[1]) { | ||
@@ -15,0 +15,0 @@ return new RegExp(matched[1], matched[2]); |
{ | ||
"name": "@markuplint/file-resolver", | ||
"version": "4.0.0-alpha.3", | ||
"version": "4.0.0-dev.28+0131de5e", | ||
"description": "The file resolver of markuplint", | ||
@@ -27,13 +27,13 @@ "repository": "git@github.com:markuplint/markuplint.git", | ||
"devDependencies": { | ||
"@types/node": "20.8.3" | ||
"@types/node": "20.8.7" | ||
}, | ||
"dependencies": { | ||
"@markuplint/html-parser": "4.0.0-alpha.3", | ||
"@markuplint/ml-ast": "4.0.0-alpha.3", | ||
"@markuplint/ml-config": "4.0.0-alpha.3", | ||
"@markuplint/ml-core": "4.0.0-alpha.3", | ||
"@markuplint/ml-spec": "4.0.0-alpha.3", | ||
"@markuplint/parser-utils": "4.0.0-alpha.3", | ||
"@markuplint/selector": "4.0.0-alpha.3", | ||
"@markuplint/shared": "4.0.0-alpha.3", | ||
"@markuplint/html-parser": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/ml-ast": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/ml-config": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/ml-core": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/ml-spec": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/parser-utils": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/selector": "4.0.0-dev.28+0131de5e", | ||
"@markuplint/shared": "4.0.0-dev.28+0131de5e", | ||
"cosmiconfig": "^8.3.6", | ||
@@ -44,6 +44,5 @@ "debug": "^4.3.4", | ||
"jsonc": "^2.0.0", | ||
"minimatch": "^9.0.3", | ||
"tslib": "^2.6.2" | ||
"minimatch": "^9.0.3" | ||
}, | ||
"gitHead": "380836f7adc1ff7e8eaf9d869e68d29eee8f3b7e" | ||
"gitHead": "0131de5ea9dd6d3fd5472d7b414b66644c758881" | ||
} |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
40361
14
1096
1
- Removedtslib@^2.6.2
- Removed@markuplint/config-presets@4.0.0-alpha.3(transitive)
- Removed@markuplint/html-parser@4.0.0-alpha.3(transitive)
- Removed@markuplint/html-spec@4.0.0-alpha.3(transitive)
- Removed@markuplint/i18n@4.0.0-alpha.3(transitive)
- Removed@markuplint/ml-ast@4.0.0-alpha.3(transitive)
- Removed@markuplint/ml-config@4.0.0-alpha.3(transitive)
- Removed@markuplint/ml-core@4.0.0-alpha.3(transitive)
- Removed@markuplint/ml-spec@4.0.0-alpha.3(transitive)
- Removed@markuplint/parser-utils@4.0.0-alpha.3(transitive)
- Removed@markuplint/selector@4.0.0-alpha.3(transitive)
- Removed@markuplint/shared@4.0.0-alpha.3(transitive)
- Removed@markuplint/types@4.0.0-alpha.3(transitive)
- Removed@types/bcp-47@2.0.4(transitive)
- Removed@types/css-tree@2.3.10(transitive)
- Removed@types/debug@4.1.12(transitive)
- Removed@types/ms@2.1.0(transitive)
- Removed@types/mustache@4.2.5(transitive)
- Removed@types/uuid@9.0.8(transitive)
- Removed@types/whatwg-mimetype@3.0.0(transitive)
- Removedbcp-47@2.1.0(transitive)
- Removedcss-tree@2.3.1(transitive)
- Removedcssesc@3.0.0(transitive)
- Removeddeepmerge@4.3.1(transitive)
- Removeddom-accessibility-api@0.6.3(transitive)
- Removedentities@4.5.0(transitive)
- Removedhtml-entities@2.5.2(transitive)
- Removedis-alphabetical@2.0.1(transitive)
- Removedis-alphanumerical@2.0.1(transitive)
- Removedis-decimal@2.0.1(transitive)
- Removedis-plain-object@5.0.0(transitive)
- Removedleven@4.0.0(transitive)
- Removedmdn-data@2.0.30(transitive)
- Removedmustache@4.2.0(transitive)
- Removedparse5@7.1.2(transitive)
- Removedpostcss-selector-parser@6.1.2(transitive)
- Removedsource-map-js@1.2.1(transitive)
- Removedtslib@2.8.1(transitive)
- Removedtype-fest@4.35.0(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removeduuid@9.0.1(transitive)
- Removedwhatwg-mimetype@3.0.0(transitive)