diff --git a/packages/@d-zero/dom-scanner/README.md b/packages/@d-zero/dom-scanner/README.md new file mode 100644 index 00000000..7e51fecb --- /dev/null +++ b/packages/@d-zero/dom-scanner/README.md @@ -0,0 +1,69 @@ +# `@d-zero/dom-scanner` + +指定ディレクトリ内のHTMLファイルとPugファイルから特定のCSSセレクタにマッチする要素を検索して報告するCLIツールです。 + +## 使い方 + +### 基本的な使い方 + +```sh +npx @d-zero/dom-scanner [options] +``` + +**引数** + +- `selector` - CSSセレクタ(必須) + +**オプション** + +- `-d, --dir, --directory ` - 検索対象のディレクトリパス(デフォルト: 現在のディレクトリ) +- `--ext, --extension ` - 検索対象の拡張子(カンマ区切り、デフォルト: `html`) + - 例: `--ext html,pug` でHTMLとPugファイルの両方を検索 +- `-p, --processor ` - 使用するプロセッサーを明示的に指定(`html` または `pug`) + - 例: `--processor pug` で全てのファイルをPugプロセッサーで処理 + - 拡張子ごとのデフォルトプロセッサー: `html` → `html`, `pug` → `pug` +- `-x, --exclude-dirs ` - 除外するディレクトリ名(カンマ区切り) + - 例: `--exclude-dirs node_modules,dist` で特定のディレクトリを除外 +- `--verbose` - 詳細なログを表示 +- `--ignore ` - 無視するファイルパターン(複数指定可能) + +### 使用例 + +```sh +# 現在のディレクトリでHTMLファイルのみを検索(デフォルト) +npx @d-zero/dom-scanner "button" + +# 指定ディレクトリで検索 +npx @d-zero/dom-scanner "button" --dir ./src + +# HTMLとPugファイルの両方を検索 +npx @d-zero/dom-scanner "button" --dir ./src --ext html,pug + +# HTMLファイルをPugプロセッサーで処理(極端な例) +npx @d-zero/dom-scanner "button" --dir ./src --ext html --processor pug + +# 除外ディレクトリをカスタマイズ +npx @d-zero/dom-scanner "button" --exclude-dirs node_modules,dist +``` + +## API + +このパッケージはAPIとしても使用できます。 + +### 基本的な使い方 + +```typescript +import { scanDirectory } from '@d-zero/dom-scanner'; + +const results = await scanDirectory('./src', 'button', { + extensions: ['html', 'pug'], +}); + +for (const result of results) { + console.log(`${result.filePath}: ${result.count}件`); +} +``` + +## 動作環境 + +- Node.js 20.11以降 diff --git a/packages/@d-zero/dom-scanner/package.json b/packages/@d-zero/dom-scanner/package.json new file mode 100644 index 00000000..fdbfe337 --- /dev/null +++ b/packages/@d-zero/dom-scanner/package.json @@ -0,0 +1,37 @@ +{ + "name": "@d-zero/dom-scanner", + "version": "1.0.0", + "description": "Scan HTML and Pug files in a directory to find elements matching a CSS selector", + "author": "D-ZERO", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "bin": "./dist/cli.js", + "files": [ + "dist" + ], + "scripts": { + "build": "tsc", + "watch": "tsc --watch", + "clean": "tsc --build --clean" + }, + "dependencies": { + "@d-zero/cli-core": "1.2.5", + "@d-zero/shared": "0.16.0", + "cheerio": "^1.0.0", + "pug": "^3.0.3" + }, + "devDependencies": { + "@types/node": "24.10.1" + } +} diff --git a/packages/@d-zero/dom-scanner/src/cli.ts b/packages/@d-zero/dom-scanner/src/cli.ts new file mode 100644 index 00000000..68485d2b --- /dev/null +++ b/packages/@d-zero/dom-scanner/src/cli.ts @@ -0,0 +1,121 @@ +#!/usr/bin/env node + +import type { ProcessorType } from './types.js'; +import type { BaseCLIOptions } from '@d-zero/cli-core'; + +import { cwd } from 'node:process'; + +import { createCLI, parseCommonOptions, parseList } from '@d-zero/cli-core'; + +import { scanDirectory } from './scanner.js'; + +interface DomScannerCLIOptions extends BaseCLIOptions { + dir?: string; + directory?: string; + ext?: string; + extension?: string; + processor?: string; + ignore?: string | string[]; + 'exclude-dirs'?: string; + excludeDirs?: string; +} + +const { options: cliOptions, args } = createCLI({ + aliases: { + d: 'dir', + D: 'directory', + e: 'ext', + E: 'extension', + p: 'processor', + i: 'ignore', + x: 'exclude-dirs', + v: 'verbose', + }, + usage: [ + 'Usage: dom-scanner [options]', + '', + 'Arguments:', + '\t CSS selector (required)', + '', + 'Options:', + '\t-d, --dir Directory to scan (default: current directory)', + '\t-D, --directory Alias for --dir', + '\t-e, --ext File extensions to search (comma-separated, default: html)', + '\t-E, --extension Alias for --ext', + '\t-p, --processor Processor to use: html or pug (default: auto-detect by extension)', + '\t-i, --ignore Ignore file patterns (can be specified multiple times)', + '\t-x, --exclude-dirs Exclude directories (comma-separated)', + '\t-v, --verbose Enable verbose logging', + '', + 'Examples:', + '\tdom-scanner "button"', + '\tdom-scanner "button" --dir ./src', + '\tdom-scanner "button" --ext html,pug', + '\tdom-scanner "button" --dir ./src --ext html --processor pug', + '\tdom-scanner "button" --exclude-dirs node_modules,dist', + ], + parseArgs: (cli) => ({ + ...parseCommonOptions(cli), + dir: cli.dir ?? cli.directory, + ext: cli.ext ?? cli.extension, + processor: cli.processor, + ignore: cli.ignore, + 'exclude-dirs': cli['exclude-dirs'] ?? cli.excludeDirs, + }), + validateArgs: (_options, cli) => { + return cli._.length > 0; + }, +}); + +const [selector] = args; + +if (!selector) { + process.stderr.write('Error: selector is required\n'); + process.exit(1); +} + +const directory = cliOptions.dir ?? cwd(); + +const extensions = cliOptions.ext + ? parseList(cliOptions.ext).map((ext) => ext.toLowerCase().trim()) + : undefined; + +const processor = cliOptions.processor as ProcessorType | undefined; +if (processor && processor !== 'html' && processor !== 'pug') { + process.stderr.write(`Error: processor must be 'html' or 'pug', got '${processor}'\n`); + process.exit(1); +} + +const ignorePatterns = cliOptions.ignore + ? Array.isArray(cliOptions.ignore) + ? cliOptions.ignore + : [cliOptions.ignore] + : undefined; + +const excludeDirs = cliOptions['exclude-dirs'] + ? parseList(cliOptions['exclude-dirs']).map((dir) => dir.trim()) + : undefined; + +const summary = await scanDirectory(directory, selector, { + extensions, + processor, + verbose: cliOptions.verbose, + ignore: ignorePatterns, + excludeDirs, +}); + +// 結果を表示 +if (summary.results.length === 0) { + process.stdout.write('検索結果: 見つかりませんでした\n'); +} else { + process.stdout.write('検索結果:\n'); + for (const result of summary.results) { + process.stdout.write(` ${result.filePath}: ${result.count}件\n`); + } + process.stdout.write('\n'); + process.stdout.write( + `合計: ${summary.totalFiles}ファイル, ${summary.totalMatches}件の要素が見つかりました\n`, + ); +} + +process.exit(0); diff --git a/packages/@d-zero/dom-scanner/src/index.ts b/packages/@d-zero/dom-scanner/src/index.ts new file mode 100644 index 00000000..ecdbcf24 --- /dev/null +++ b/packages/@d-zero/dom-scanner/src/index.ts @@ -0,0 +1,4 @@ +export { scanDirectory } from './scanner.js'; +export { parseFile, getDefaultProcessor } from './parser.js'; +export type { ScanOptions, ScanResult, ScanSummary, ProcessorType } from './types.js'; +export { DEFAULT_PROCESSOR_MAP, DEFAULT_EXTENSIONS } from './types.js'; diff --git a/packages/@d-zero/dom-scanner/src/parser.ts b/packages/@d-zero/dom-scanner/src/parser.ts new file mode 100644 index 00000000..86789c40 --- /dev/null +++ b/packages/@d-zero/dom-scanner/src/parser.ts @@ -0,0 +1,75 @@ +import type { ProcessorType } from './types.js'; + +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; + +import * as cheerio from 'cheerio'; +// @ts-expect-error - pug doesn't have type definitions +import pug from 'pug'; + +import { DEFAULT_PROCESSOR_MAP } from './types.js'; + +/** + * ファイル拡張子からデフォルトプロセッサーを取得 + * @param filePath + */ +export function getDefaultProcessor(filePath: string): ProcessorType { + const ext = path.extname(filePath).slice(1).toLowerCase(); + return DEFAULT_PROCESSOR_MAP[ext] ?? 'html'; +} + +/** + * HTMLファイルをパースして要素数をカウント + * @param html + * @param selector + */ +function parseHTML(html: string, selector: string): number { + const $ = cheerio.load(html); + return $(selector).length; +} + +/** + * PugファイルをコンパイルしてHTMLに変換し、要素数をカウント + * @param pugContent + * @param selector + */ +function parsePug(pugContent: string, selector: string): number { + try { + const compileFunction = pug.compile(pugContent, { + basedir: process.cwd(), + }); + const html = compileFunction(); + return parseHTML(html, selector); + } catch (error) { + throw new Error( + `Pugコンパイルエラー: ${error instanceof Error ? error.message : String(error)}`, + ); + } +} + +/** + * ファイルを処理して要素数をカウント + * @param filePath + * @param selector + * @param processor + */ +export async function parseFile( + filePath: string, + selector: string, + processor?: ProcessorType, +): Promise { + const content = await readFile(filePath, 'utf8'); + const actualProcessor = processor ?? getDefaultProcessor(filePath); + + switch (actualProcessor) { + case 'html': { + return parseHTML(content, selector); + } + case 'pug': { + return parsePug(content, selector); + } + default: { + throw new Error(`Unknown processor: ${actualProcessor}`); + } + } +} diff --git a/packages/@d-zero/dom-scanner/src/scanner.ts b/packages/@d-zero/dom-scanner/src/scanner.ts new file mode 100644 index 00000000..e0340fd5 --- /dev/null +++ b/packages/@d-zero/dom-scanner/src/scanner.ts @@ -0,0 +1,159 @@ +import type { ScanOptions, ScanResult, ScanSummary } from './types.js'; + +import { readdir } from 'node:fs/promises'; +import path from 'node:path'; + +import { parseFile } from './parser.js'; +import { DEFAULT_EXTENSIONS } from './types.js'; + +/** + * ファイルパスが無視パターンにマッチするかチェック + * @param filePath + * @param ignorePatterns + */ +function shouldIgnore(filePath: string, ignorePatterns?: string[]): boolean { + if (!ignorePatterns || ignorePatterns.length === 0) { + return false; + } + + for (const pattern of ignorePatterns) { + if (filePath.includes(pattern)) { + return true; + } + } + + return false; +} + +/** + * ファイル拡張子が対象かチェック + * @param filePath + * @param extensions + */ +function matchesExtension(filePath: string, extensions: string[]): boolean { + const ext = path.extname(filePath).slice(1).toLowerCase(); + return extensions.includes(ext); +} + +/** + * ディレクトリを再帰的にスキャンしてファイルを収集 + * @param dirPath + * @param extensions + * @param ignorePatterns + * @param excludeDirs + */ +async function collectFiles( + dirPath: string, + extensions: string[], + ignorePatterns?: string[], + excludeDirs?: string[], +): Promise { + const files: string[] = []; + const excludeDirsSet = + excludeDirs && excludeDirs.length > 0 ? new Set(excludeDirs) : new Set(); + + const entries = await readdir(dirPath, { withFileTypes: true }).catch(() => { + // エラーは無視(権限エラーなど) + return []; + }); + + for (const entry of entries) { + const fullPath = path.join(dirPath, entry.name); + + if (entry.isDirectory()) { + // 除外ディレクトリをスキップ + if (excludeDirsSet.has(entry.name)) { + continue; + } + + // 無視パターンにマッチする場合はスキップ + if (shouldIgnore(fullPath, ignorePatterns)) { + continue; + } + + // 再帰的に探索 + const subFiles = await collectFiles( + fullPath, + extensions, + ignorePatterns, + excludeDirs, + ); + files.push(...subFiles); + } else if (entry.isFile()) { + // 無視パターンにマッチする場合はスキップ + if (shouldIgnore(fullPath, ignorePatterns)) { + continue; + } + + // 拡張子が対象の場合のみ追加 + if (matchesExtension(fullPath, extensions)) { + files.push(fullPath); + } + } + } + + return files; +} + +/** + * ディレクトリをスキャンして要素を検索 + * @param directory + * @param selector + * @param options + */ +export async function scanDirectory( + directory: string, + selector: string, + options?: ScanOptions, +): Promise { + const extensions = options?.extensions ?? DEFAULT_EXTENSIONS; + const processor = options?.processor; + const verbose = options?.verbose ?? false; + const ignorePatterns = options?.ignore; + const excludeDirs = options?.excludeDirs; + + if (verbose) { + process.stdout.write(`スキャン中: ${directory}\n`); + process.stdout.write(`対象拡張子: ${extensions.join(', ')}\n`); + } + + const files = await collectFiles(directory, extensions, ignorePatterns, excludeDirs); + + if (verbose) { + process.stdout.write(`見つかったファイル数: ${files.length}\n`); + } + + const results: ScanResult[] = []; + let totalMatches = 0; + + for (const filePath of files) { + try { + const count = await parseFile(filePath, selector, processor); + + if (count > 0) { + results.push({ + filePath, + count, + }); + totalMatches += count; + } + + if (verbose) { + process.stdout.write(` ${filePath}: ${count}件\n`); + } + } catch (error) { + if (verbose) { + process.stderr.write( + ` ${filePath}: エラー - ${error instanceof Error ? error.message : String(error)}\n`, + ); + } + // エラーが発生したファイルはスキップ + } + } + + return { + results, + totalFiles: results.length, + totalMatches, + }; +} diff --git a/packages/@d-zero/dom-scanner/src/types.ts b/packages/@d-zero/dom-scanner/src/types.ts new file mode 100644 index 00000000..87d59b5f --- /dev/null +++ b/packages/@d-zero/dom-scanner/src/types.ts @@ -0,0 +1,28 @@ +export type ProcessorType = 'html' | 'pug'; + +export interface ScanOptions { + extensions?: string[]; + processor?: ProcessorType; + verbose?: boolean; + ignore?: string[]; + excludeDirs?: string[]; +} + +export interface ScanResult { + filePath: string; + count: number; +} + +export interface ScanSummary { + results: ScanResult[]; + totalFiles: number; + totalMatches: number; +} + +export const DEFAULT_PROCESSOR_MAP: Record = { + html: 'html', + htm: 'html', + pug: 'pug', +}; + +export const DEFAULT_EXTENSIONS = ['html', 'htm']; diff --git a/packages/@d-zero/dom-scanner/tsconfig.json b/packages/@d-zero/dom-scanner/tsconfig.json new file mode 100644 index 00000000..b5967f12 --- /dev/null +++ b/packages/@d-zero/dom-scanner/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "composite": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "references": [ + { + "path": "../cli-core" + }, + { + "path": "../shared" + } + ], + "include": ["./src/**/*"], + "exclude": ["node_modules", "dist", "./src/**/*.spec.ts"] +} diff --git a/yarn.lock b/yarn.lock index dae69ead..bc620bab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -57,7 +57,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.27.0": +"@babel/parser@npm:^7.27.0, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.9.6": version: 7.28.5 resolution: "@babel/parser@npm:7.28.5" dependencies: @@ -68,7 +68,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.28.5": +"@babel/types@npm:^7.28.5, @babel/types@npm:^7.6.1, @babel/types@npm:^7.9.6": version: 7.28.5 resolution: "@babel/types@npm:7.28.5" dependencies: @@ -1092,6 +1092,20 @@ __metadata: languageName: unknown linkType: soft +"@d-zero/dom-scanner@workspace:packages/@d-zero/dom-scanner": + version: 0.0.0-use.local + resolution: "@d-zero/dom-scanner@workspace:packages/@d-zero/dom-scanner" + dependencies: + "@d-zero/cli-core": "npm:1.2.5" + "@d-zero/shared": "npm:0.16.0" + "@types/node": "npm:24.10.1" + cheerio: "npm:^1.0.0" + pug: "npm:^3.0.3" + bin: + dom-scanner: ./dist/cli.js + languageName: unknown + linkType: soft + "@d-zero/eslint-config@npm:5.0.0-alpha.73": version: 5.0.0-alpha.73 resolution: "@d-zero/eslint-config@npm:5.0.0-alpha.73" @@ -4743,6 +4757,13 @@ __metadata: languageName: node linkType: hard +"asap@npm:~2.0.3": + version: 2.0.6 + resolution: "asap@npm:2.0.6" + checksum: 10c0/c6d5e39fe1f15e4b87677460bd66b66050cd14c772269cee6688824c1410a08ab20254bb6784f9afb75af9144a9f9a7692d49547f4d19d715aeb7c0318f3136d + languageName: node + linkType: hard + "asn1@npm:^0.2.6": version: 0.2.6 resolution: "asn1@npm:0.2.6" @@ -4752,6 +4773,13 @@ __metadata: languageName: node linkType: hard +"assert-never@npm:^1.2.1": + version: 1.4.0 + resolution: "assert-never@npm:1.4.0" + checksum: 10c0/494db08b89fb43d6231c9b4c48da22824f1912d88992bf0268e43b3dad0f64bd56d380addbb997d2dea7d859421d5e2904e8bd01243794f2bb5bfbc8d32d1fc6 + languageName: node + linkType: hard + "assertion-error@npm:^2.0.1": version: 2.0.1 resolution: "assertion-error@npm:2.0.1" @@ -4865,6 +4893,15 @@ __metadata: languageName: node linkType: hard +"babel-walk@npm:3.0.0-canary-5": + version: 3.0.0-canary-5 + resolution: "babel-walk@npm:3.0.0-canary-5" + dependencies: + "@babel/types": "npm:^7.9.6" + checksum: 10c0/17b689874d15c37714cedf6797dd9321dcb998d8e0dda9a8fe8c8bbbf128bbdeb8935cf56e8630d6b67eae76d2a0bc1e470751e082c3b0e30b80d58beafb5e64 + languageName: node + linkType: hard + "backlog-js@npm:0.15.0": version: 0.15.0 resolution: "backlog-js@npm:0.15.0" @@ -5068,6 +5105,13 @@ __metadata: languageName: node linkType: hard +"boolbase@npm:^1.0.0": + version: 1.0.0 + resolution: "boolbase@npm:1.0.0" + checksum: 10c0/e4b53deb4f2b85c52be0e21a273f2045c7b6a6ea002b0e139c744cb6f95e9ec044439a52883b0d74dedd1ff3da55ed140cfdddfed7fb0cccbed373de5dce1bcf + languageName: node + linkType: hard + "boundary@npm:^2.0.0": version: 2.0.0 resolution: "boundary@npm:2.0.0" @@ -5446,6 +5490,39 @@ __metadata: languageName: node linkType: hard +"cheerio-select@npm:^2.1.0": + version: 2.1.0 + resolution: "cheerio-select@npm:2.1.0" + dependencies: + boolbase: "npm:^1.0.0" + css-select: "npm:^5.1.0" + css-what: "npm:^6.1.0" + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.0.1" + checksum: 10c0/2242097e593919dba4aacb97d7b8275def8b9ec70b00aa1f43335456870cfc9e284eae2080bdc832ed232dabb9eefcf56c722d152da4a154813fb8814a55d282 + languageName: node + linkType: hard + +"cheerio@npm:^1.0.0": + version: 1.1.2 + resolution: "cheerio@npm:1.1.2" + dependencies: + cheerio-select: "npm:^2.1.0" + dom-serializer: "npm:^2.0.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.2" + encoding-sniffer: "npm:^0.2.1" + htmlparser2: "npm:^10.0.0" + parse5: "npm:^7.3.0" + parse5-htmlparser2-tree-adapter: "npm:^7.1.0" + parse5-parser-stream: "npm:^7.1.2" + undici: "npm:^7.12.0" + whatwg-mimetype: "npm:^4.0.0" + checksum: 10c0/2c6d2274666fe122f54fdca457ee76453e1a993b19563acaa23eb565bf7776f0f01e4c3800092f00e84aa13c83a161f0cf000ac0a8332d1d7f2b2387d6ecc5fc + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -5889,6 +5966,16 @@ __metadata: languageName: node linkType: hard +"constantinople@npm:^4.0.1": + version: 4.0.1 + resolution: "constantinople@npm:4.0.1" + dependencies: + "@babel/parser": "npm:^7.6.0" + "@babel/types": "npm:^7.6.1" + checksum: 10c0/15129adef19b1af2c3ade8bd38f97c34781bf461472a30ab414384b28d072be83070c8d2175787c045ef7c222c415101ae609936e7903427796a0c0eca8449fd + languageName: node + linkType: hard + "content-disposition@npm:^1.0.0": version: 1.0.1 resolution: "content-disposition@npm:1.0.1" @@ -6285,6 +6372,26 @@ __metadata: languageName: node linkType: hard +"css-select@npm:^5.1.0": + version: 5.2.2 + resolution: "css-select@npm:5.2.2" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.1.0" + domhandler: "npm:^5.0.2" + domutils: "npm:^3.0.1" + nth-check: "npm:^2.0.1" + checksum: 10c0/d79fffa97106007f2802589f3ed17b8c903f1c961c0fc28aa8a051eee0cbad394d8446223862efd4c1b40445a6034f626bb639cf2035b0bfc468544177593c99 + languageName: node + linkType: hard + +"css-what@npm:^6.1.0": + version: 6.2.2 + resolution: "css-what@npm:6.2.2" + checksum: 10c0/91e24c26fb977b4ccef30d7007d2668c1c10ac0154cc3f42f7304410e9594fb772aea4f30c832d2993b132ca8d99338050866476210316345ec2e7d47b248a56 + languageName: node + linkType: hard + "cssesc@npm:^3.0.0": version: 3.0.0 resolution: "cssesc@npm:3.0.0" @@ -6552,6 +6659,51 @@ __metadata: languageName: node linkType: hard +"doctypes@npm:^1.1.0": + version: 1.1.0 + resolution: "doctypes@npm:1.1.0" + checksum: 10c0/b3f9d597ad8b9ac6aeba9d64df61f0098174f7570e3d34f7ee245ebc736c7bee122d9738a18e22010b98983fd9a340d63043d3841f02d8a7742a2d96d2c72610 + languageName: node + linkType: hard + +"dom-serializer@npm:^2.0.0": + version: 2.0.0 + resolution: "dom-serializer@npm:2.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.2" + entities: "npm:^4.2.0" + checksum: 10c0/d5ae2b7110ca3746b3643d3ef60ef823f5f078667baf530cec096433f1627ec4b6fa8c072f09d079d7cda915fd2c7bc1b7b935681e9b09e591e1e15f4040b8e2 + languageName: node + linkType: hard + +"domelementtype@npm:^2.3.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: 10c0/686f5a9ef0fff078c1412c05db73a0dce096190036f33e400a07e2a4518e9f56b1e324f5c576a0a747ef0e75b5d985c040b0d51945ce780c0dd3c625a18cd8c9 + languageName: node + linkType: hard + +"domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": + version: 5.0.3 + resolution: "domhandler@npm:5.0.3" + dependencies: + domelementtype: "npm:^2.3.0" + checksum: 10c0/bba1e5932b3e196ad6862286d76adc89a0dbf0c773e5ced1eb01f9af930c50093a084eff14b8de5ea60b895c56a04d5de8bbc4930c5543d029091916770b2d2a + languageName: node + linkType: hard + +"domutils@npm:^3.0.1, domutils@npm:^3.2.1, domutils@npm:^3.2.2": + version: 3.2.2 + resolution: "domutils@npm:3.2.2" + dependencies: + dom-serializer: "npm:^2.0.0" + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + checksum: 10c0/47938f473b987ea71cd59e59626eb8666d3aa8feba5266e45527f3b636c7883cca7e582d901531961f742c519d7514636b7973353b648762b2e3bedbf235fada + languageName: node + linkType: hard + "dot-case@npm:^3.0.4": version: 3.0.4 resolution: "dot-case@npm:3.0.4" @@ -6704,6 +6856,16 @@ __metadata: languageName: node linkType: hard +"encoding-sniffer@npm:^0.2.1": + version: 0.2.1 + resolution: "encoding-sniffer@npm:0.2.1" + dependencies: + iconv-lite: "npm:^0.6.3" + whatwg-encoding: "npm:^3.1.1" + checksum: 10c0/d6b591880788f3baf8dd1744636dd189d24a1ec93e6f9817267c60ac3458a5191ca70ab1a186fb67731beff1c3489c6527dfdc4718158ed8460ab2f400dd5e7d + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -6741,7 +6903,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.4.0": +"entities@npm:^4.2.0, entities@npm:^4.4.0": version: 4.5.0 resolution: "entities@npm:4.5.0" checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 @@ -8623,6 +8785,18 @@ __metadata: languageName: node linkType: hard +"htmlparser2@npm:^10.0.0": + version: 10.0.0 + resolution: "htmlparser2@npm:10.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.1" + entities: "npm:^6.0.0" + checksum: 10c0/47cfa37e529c86a7ba9a1e0e6f951ad26ef8ca5af898ab6e8916fa02c0264c1453b4a65f28b7b8a7f9d0d29b5a70abead8203bf8b3f07bc69407e85e7d9a68e4 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.2.0 resolution: "http-cache-semantics@npm:4.2.0" @@ -8679,6 +8853,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + languageName: node + linkType: hard + "iconv-lite@npm:^0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" @@ -8688,15 +8871,6 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.6.2": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 - languageName: node - linkType: hard - "iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": version: 0.7.0 resolution: "iconv-lite@npm:0.7.0" @@ -9137,6 +9311,13 @@ __metadata: languageName: node linkType: hard +"is-promise@npm:^2.0.0": + version: 2.2.2 + resolution: "is-promise@npm:2.2.2" + checksum: 10c0/2dba959812380e45b3df0fb12e7cb4d4528c989c7abb03ececb1d1fd6ab1cbfee956ca9daa587b9db1d8ac3c1e5738cf217bdb3dfd99df8c691be4c00ae09069 + languageName: node + linkType: hard + "is-promise@npm:^4.0.0": version: 4.0.0 resolution: "is-promise@npm:4.0.0" @@ -9360,6 +9541,13 @@ __metadata: languageName: node linkType: hard +"js-stringify@npm:^1.0.2": + version: 1.0.2 + resolution: "js-stringify@npm:1.0.2" + checksum: 10c0/a450c04fde3a7e1c27f1c3c4300433f8d79322f9e3c2e76266843cef8c0b5a69b5f11b5f173212b2f15f2df09e068ef7ddf46ef775e2486f3006a6f4e912578d + languageName: node + linkType: hard + "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -9537,6 +9725,16 @@ __metadata: languageName: node linkType: hard +"jstransformer@npm:1.0.0": + version: 1.0.0 + resolution: "jstransformer@npm:1.0.0" + dependencies: + is-promise: "npm:^2.0.0" + promise: "npm:^7.0.1" + checksum: 10c0/11f9b4f368a55878dd7973154cd83b0adca27f974d21217728652530775b2bec281e92109de66f0c9e37c76af796d5b76b33f3e38363214a83d102d523a7285b + languageName: node + linkType: hard + "just-diff-apply@npm:^5.2.0": version: 5.5.0 resolution: "just-diff-apply@npm:5.5.0" @@ -11288,6 +11486,15 @@ __metadata: languageName: node linkType: hard +"nth-check@npm:^2.0.1": + version: 2.1.1 + resolution: "nth-check@npm:2.1.1" + dependencies: + boolbase: "npm:^1.0.0" + checksum: 10c0/5fee7ff309727763689cfad844d979aedd2204a817fbaaf0e1603794a7c20db28548d7b024692f953557df6ce4a0ee4ae46cd8ebd9b36cfb300b9226b567c479 + languageName: node + linkType: hard + "nx@npm:>=21.5.3 < 23.0.0": version: 22.1.3 resolution: "nx@npm:22.1.3" @@ -11942,6 +12149,25 @@ __metadata: languageName: node linkType: hard +"parse5-htmlparser2-tree-adapter@npm:^7.1.0": + version: 7.1.0 + resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0" + dependencies: + domhandler: "npm:^5.0.3" + parse5: "npm:^7.0.0" + checksum: 10c0/e5a4e0b834c84c9e244b5749f8d007f4baaeafac7a1da2c54be3421ffd9ef8fdec4f198bf55cda22e88e6ba95e9943f6ed5aa3ae5900b39972ebf5dc8c3f4722 + languageName: node + linkType: hard + +"parse5-parser-stream@npm:^7.1.2": + version: 7.1.2 + resolution: "parse5-parser-stream@npm:7.1.2" + dependencies: + parse5: "npm:^7.0.0" + checksum: 10c0/e236c61000d38ecad369e725a48506b051cebad8abb00e6d4e8bff7aa85c183820fcb45db1559cc90955bdbbdbd665ea94c41259594e74566fff411478dc7fcb + languageName: node + linkType: hard + "parse5@npm:8.0.0": version: 8.0.0 resolution: "parse5@npm:8.0.0" @@ -11965,6 +12191,15 @@ __metadata: languageName: node linkType: hard +"parse5@npm:^7.0.0, parse5@npm:^7.3.0": + version: 7.3.0 + resolution: "parse5@npm:7.3.0" + dependencies: + entities: "npm:^6.0.0" + checksum: 10c0/7fd2e4e247e85241d6f2a464d0085eed599a26d7b0a5233790c49f53473232eb85350e8133344d9b3fd58b89339e7ad7270fe1f89d28abe50674ec97b87f80b5 + languageName: node + linkType: hard + "parseurl@npm:^1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" @@ -12348,6 +12583,15 @@ __metadata: languageName: node linkType: hard +"promise@npm:^7.0.1": + version: 7.3.1 + resolution: "promise@npm:7.3.1" + dependencies: + asap: "npm:~2.0.3" + checksum: 10c0/742e5c0cc646af1f0746963b8776299701ad561ce2c70b49365d62c8db8ea3681b0a1bf0d4e2fe07910bf72f02d39e51e8e73dc8d7503c3501206ac908be107f + languageName: node + linkType: hard + "promzard@npm:^2.0.0": version: 2.0.0 resolution: "promzard@npm:2.0.0" @@ -12413,13 +12657,53 @@ __metadata: languageName: node linkType: hard -"pug-error@npm:^2.0.0": +"pug-attrs@npm:^3.0.0": + version: 3.0.0 + resolution: "pug-attrs@npm:3.0.0" + dependencies: + constantinople: "npm:^4.0.1" + js-stringify: "npm:^1.0.2" + pug-runtime: "npm:^3.0.0" + checksum: 10c0/28178e91c05e8eb9130861c78dccc61eae3e1610931346065bd32ad0b08b023a8dcf2470c3b2409ba45a5098d6d7ed15687717e91cf77770c6381a18626e5194 + languageName: node + linkType: hard + +"pug-code-gen@npm:^3.0.3": + version: 3.0.3 + resolution: "pug-code-gen@npm:3.0.3" + dependencies: + constantinople: "npm:^4.0.1" + doctypes: "npm:^1.1.0" + js-stringify: "npm:^1.0.2" + pug-attrs: "npm:^3.0.0" + pug-error: "npm:^2.1.0" + pug-runtime: "npm:^3.0.1" + void-elements: "npm:^3.1.0" + with: "npm:^7.0.0" + checksum: 10c0/517a93930dbc80bc7fa5f60ff324229a07cc5ab70ed9d344ce105e2fe24de68db5121c8457a9ba99cdc8d48dd18779dd34956ebfcab009b3c1c6843a3cade109 + languageName: node + linkType: hard + +"pug-error@npm:^2.0.0, pug-error@npm:^2.1.0": version: 2.1.0 resolution: "pug-error@npm:2.1.0" checksum: 10c0/bbce339b17fab9890de84975c0cd8723a847bf65f35653d3ebcf77018e8ad91529d56e978ab80f4c64c9f4f07ef9e56e7a9fda3be44249c344a93ba11fccff79 languageName: node linkType: hard +"pug-filters@npm:^4.0.0": + version: 4.0.0 + resolution: "pug-filters@npm:4.0.0" + dependencies: + constantinople: "npm:^4.0.1" + jstransformer: "npm:1.0.0" + pug-error: "npm:^2.0.0" + pug-walk: "npm:^2.0.0" + resolve: "npm:^1.15.1" + checksum: 10c0/7ddd62f5eb97f5242858bd56d93ffed387fef3742210a53770c980020cf91a34384b84b7fc8f0de185b43dfa77de2c4d0f63f575a4c5b3887fdef4e64b8d559d + languageName: node + linkType: hard + "pug-lexer@npm:^5.0.1": version: 5.0.1 resolution: "pug-lexer@npm:5.0.1" @@ -12431,6 +12715,75 @@ __metadata: languageName: node linkType: hard +"pug-linker@npm:^4.0.0": + version: 4.0.0 + resolution: "pug-linker@npm:4.0.0" + dependencies: + pug-error: "npm:^2.0.0" + pug-walk: "npm:^2.0.0" + checksum: 10c0/db754ff34cdd4ba9d9e2d9535cce2a74178f2172e848a5fa6381907cb5bfaa0d39d4cc3eb29893d35fc1c417e83ae3cfd434640ba7d3b635c63199104fae976c + languageName: node + linkType: hard + +"pug-load@npm:^3.0.0": + version: 3.0.0 + resolution: "pug-load@npm:3.0.0" + dependencies: + object-assign: "npm:^4.1.1" + pug-walk: "npm:^2.0.0" + checksum: 10c0/2a7659dfaf9872dd25d851f85e4c27fa447d907b1db3540030cd844614159ff181e067d8f2bedf90eb6b5b1ff03747253859ecbbb822e40f4834b15591d4e108 + languageName: node + linkType: hard + +"pug-parser@npm:^6.0.0": + version: 6.0.0 + resolution: "pug-parser@npm:6.0.0" + dependencies: + pug-error: "npm:^2.0.0" + token-stream: "npm:1.0.0" + checksum: 10c0/faa6cec43afdeb2705eb8c68dfdb2e65836238df8043ae55295ffb72450b8c7a990ea1be60adbde19f58988b9e1d18a84ea42453e2c4f104d0031f78fda737b2 + languageName: node + linkType: hard + +"pug-runtime@npm:^3.0.0, pug-runtime@npm:^3.0.1": + version: 3.0.1 + resolution: "pug-runtime@npm:3.0.1" + checksum: 10c0/0db8166d2e17695a6941d1de81dcb21c8a52921299b1e03bf6a0a3d2b0036b51cf98101b3937b731c745e8d3e0268cb0b728c02f61a80a25fcfaa15c594fb1be + languageName: node + linkType: hard + +"pug-strip-comments@npm:^2.0.0": + version: 2.0.0 + resolution: "pug-strip-comments@npm:2.0.0" + dependencies: + pug-error: "npm:^2.0.0" + checksum: 10c0/ca498adedaeba51dd836b20129bbd161e2d5a397a2baaa553b1e74e888caa2258dcd7326396fc6f8fed8c7b7f906cfebc4c386ccbee8888a27b2ca0d4d86d206 + languageName: node + linkType: hard + +"pug-walk@npm:^2.0.0": + version: 2.0.0 + resolution: "pug-walk@npm:2.0.0" + checksum: 10c0/005d63177bcf057f5a618b182f6d4600afb039200b07a381a0d89288a2b3126e763a0a6c40b758eab0731c8e63cad1bbcb46d96803b9ae9cfc879f6ef5a0f8f4 + languageName: node + linkType: hard + +"pug@npm:^3.0.3": + version: 3.0.3 + resolution: "pug@npm:3.0.3" + dependencies: + pug-code-gen: "npm:^3.0.3" + pug-filters: "npm:^4.0.0" + pug-lexer: "npm:^5.0.1" + pug-linker: "npm:^4.0.0" + pug-load: "npm:^3.0.0" + pug-parser: "npm:^6.0.0" + pug-runtime: "npm:^3.0.1" + pug-strip-comments: "npm:^2.0.0" + checksum: 10c0/bda53d3a6deea1d348cd5ab17427c77f3d74165510ad16f4fd182cc63618ad09388ecda317d17122ee890c8a68f9a54b96221fce7f44a332e463fdbb10a9d1e2 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.3 resolution: "pump@npm:3.0.3" @@ -13014,7 +13367,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0": +"resolve@npm:^1.10.0, resolve@npm:^1.15.1": version: 1.22.11 resolution: "resolve@npm:1.22.11" dependencies: @@ -13027,7 +13380,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin": +"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.15.1#optional!builtin": version: 1.22.11 resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin::version=1.22.11&hash=c3c19d" dependencies: @@ -14608,6 +14961,13 @@ __metadata: languageName: node linkType: hard +"token-stream@npm:1.0.0": + version: 1.0.0 + resolution: "token-stream@npm:1.0.0" + checksum: 10c0/c1924a89686fc035d579cbe856da12306571d5fe7408eeeebe80df7c25c5cc644b8ae102d5cbc0f085d0e105f391d1a48dc0e568520434c5b444ea6c7de2b822 + languageName: node + linkType: hard + "token-types@npm:^4.1.1": version: 4.2.1 resolution: "token-types@npm:4.2.1" @@ -14848,6 +15208,13 @@ __metadata: languageName: node linkType: hard +"undici@npm:^7.12.0": + version: 7.16.0 + resolution: "undici@npm:7.16.0" + checksum: 10c0/efd867792e9f233facf9efa0a087e2d9c3e4415c0b234061b9b40307ca4fa01d945fee4d43c7b564e1b80e0d519bcc682f9f6e0de13c717146c00a80e2f1fb0f + languageName: node + linkType: hard + "unicorn-magic@npm:^0.1.0": version: 0.1.0 resolution: "unicorn-magic@npm:0.1.0" @@ -15350,6 +15717,13 @@ __metadata: languageName: node linkType: hard +"void-elements@npm:^3.1.0": + version: 3.1.0 + resolution: "void-elements@npm:3.1.0" + checksum: 10c0/0b8686f9f9aa44012e9bd5eabf287ae0cde409b9a2854c5a2335cb83920c957668ac5876e3f0d158dd424744ac411a7270e64128556b451ed3bec875ef18534d + languageName: node + linkType: hard + "vscode-languageserver-textdocument@npm:^1.0.12": version: 1.0.12 resolution: "vscode-languageserver-textdocument@npm:1.0.12" @@ -15408,6 +15782,22 @@ __metadata: languageName: node linkType: hard +"whatwg-encoding@npm:^3.1.1": + version: 3.1.1 + resolution: "whatwg-encoding@npm:3.1.1" + dependencies: + iconv-lite: "npm:0.6.3" + checksum: 10c0/273b5f441c2f7fda3368a496c3009edbaa5e43b71b09728f90425e7f487e5cef9eb2b846a31bd760dd8077739c26faf6b5ca43a5f24033172b003b72cf61a93e + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^4.0.0": + version: 4.0.0 + resolution: "whatwg-mimetype@npm:4.0.0" + checksum: 10c0/a773cdc8126b514d790bdae7052e8bf242970cebd84af62fb2f35a33411e78e981f6c0ab9ed1fe6ec5071b09d5340ac9178e05b52d35a9c4bcf558ba1b1551df + languageName: node + linkType: hard + "which@npm:^1.2.14": version: 1.3.1 resolution: "which@npm:1.3.1" @@ -15473,6 +15863,18 @@ __metadata: languageName: node linkType: hard +"with@npm:^7.0.0": + version: 7.0.2 + resolution: "with@npm:7.0.2" + dependencies: + "@babel/parser": "npm:^7.9.6" + "@babel/types": "npm:^7.9.6" + assert-never: "npm:^1.2.1" + babel-walk: "npm:3.0.0-canary-5" + checksum: 10c0/99289e49afc4b1776afae0ef85e84cfa775e8e07464d2b9853a31b0822347031d1cf77f287d25adc8c3f81e4fa68f4ee31526a9c95d4981ba08a1fe24dee111a + languageName: node + linkType: hard + "word-wrap@npm:^1.0.3, word-wrap@npm:^1.2.3, word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5"