diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 00000000..eceab8e5 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,15 @@ +{ + "permissions": { + "allow": [ + "Bash(echo:*)", + "Bash(head:*)", + "Bash(wc:*)", + "Bash(echo === $\\(basename $pkg\\) ===:*)", + "Bash(python3:*)", + "WebSearch", + "Bash(npx mocha:*)", + "Bash(test:*)", + "Bash(node:*)" + ] + } +} diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index c9b918a0..00000000 --- a/.eslintignore +++ /dev/null @@ -1,9 +0,0 @@ -.nyc_output -node_modules -coverage - -#TODO: need for actualize -packages/bemjson-to-jsx-demo - -#Remove after AVA done -packages/config/test/*.test.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 91aaca62..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; - -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 9 - }, - env: { - node: true, - es6: true, - }, - // plugins: ['node', 'promise', 'unicorn'], - extends: 'pedant', - - overrides: [ - { - files: ['*.test.js'], - env: { mocha: true }, - globals: { 'utils': true }, - rules: { - 'no-unused-expressions': 0 - } - }, - { - files: ['*.spec.js'], - globals: { 'lib': true, 'utils': true }, - rules: { - 'no-unexpected-multiline': 'no', - 'no-unused-expressions': 0 - } - }, - { - files: ['*.bench.js'], - globals: { 'suite': true, 'set': true, 'bench': true } - } - ], - - rules: { - /* Strict Mode ========================================================================= */ - /* http://eslint.org/docs/rules/#strict-mode */ - /* ===================================================================================== */ - 'strict': ['error', 'safe'] - } -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..2d564301 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + - run: npm install + - run: npm test diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 43c97e71..00000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0f6f97c5..00000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -sudo: false - -branches: - only: - - master - -language: node_js - -matrix: - include: - - node_js: "8" - env: COVERALLS=1 - - node_js: "10.4" - -install: - - npm i -g lerna - - lerna bootstrap --no-ci - -after_success: - - if [ "x$COVERALLS" = "x1" ]; then - npm i coveralls; - nyc report --reporter=text-lcov | coveralls; - fi diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..e7b38edf --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +Всегда общайся с пользователем на русском языке. diff --git a/DEPENDENCY_UPDATE_PLAN.md b/DEPENDENCY_UPDATE_PLAN.md new file mode 100644 index 00000000..6283d7d4 --- /dev/null +++ b/DEPENDENCY_UPDATE_PLAN.md @@ -0,0 +1,200 @@ +# План обновления зависимостей bem-sdk + +## Общая ситуация + +Проект — Lerna-монорепо с 22 пакетами. Последний коммит в основную ветку — ~2019 год. +Зависимости сильно устарели (3–7 лет), некоторые deprecated, некоторые можно заменить нативными средствами Node.js. + +**Текущее окружение:** Node >= 8.0 (в большинстве пакетов) +**Рекомендуемое обновление:** Node >= 18.0 (LTS, поддержка до 2025-04) + +--- + +## Фаза 0: Инфраструктура монорепо + +### 0.1 Lerna 2.2.0 → замена на npm workspaces или Lerna 9.x + +| Что | Сейчас | Предложение | +|-----|--------|-------------| +| lerna.json `"lerna": "2.2.0"` | Lerna 2.x (deprecated) | **Вариант A (рекомендуется):** Перейти на `npm workspaces` (нативная поддержка в npm 7+) — убрать зависимость от lerna целиком | +| | | **Вариант B:** Обновить до Lerna 9.0.4 (требует Nx) | + +**Обоснование варианта A:** Для данного проекта (без publish pipeline) npm workspaces достаточно — это нативное решение без внешних зависимостей. Нужно добавить `"workspaces": ["packages/*"]` в корневой `package.json`. + +### 0.2 CI/CD: Travis CI + AppVeyor → GitHub Actions + +| Что | Сейчас | Предложение | +|-----|--------|-------------| +| `.travis.yml` | Travis CI, Node 8 / 10.4 | Удалить, заменить на GitHub Actions | +| `appveyor.yml` | AppVeyor, Node 8 / 10 | Удалить, заменить на GitHub Actions | + +GitHub Actions позволяет тестировать на Linux/macOS/Windows в одном workflow с матрицей Node 18 / 20 / 22. + +### 0.3 Node.js engine + +В `package.json` всех пакетов обновить `"engines": { "node": ">= 18.0" }`. + +--- + +## Фаза 1: Тестирование и покрытие (devDependencies корня) + +| Пакет | Сейчас | Последняя | Рекомендация | Breaking changes / заметки | +|-------|--------|-----------|-------------|---------------------------| +| **mocha** | 3.4.2 | 11.7.5 | → **11.x** | ESM-first, новый CLI. Большой скачок — нужна проверка всех тестов | +| **chai** | 4.1.2 | 6.2.2 | → **6.x** | v5+ — ESM-only. Если проект остаётся CJS — **оставить 4.x** или мигрировать на `node:assert` | +| **nyc** | 11.0.3 | 17.1.0 | → **заменить на c8** (10.1.3) | `c8` — нативное покрытие через V8, не нужен babel/istanbul. Рекомендуется для Node 18+ | +| **sinon** | 2.3.6 | 21.0.1 | → **21.x** | Полностью ESM с v15+. Для CJS — **оставить 14.x** или мигрировать | +| **proxyquire** | 1.8.0 | 2.1.3 | → **2.1.3** | Минорное обновление | +| **mock-fs** | 4.4.1 | 5.5.0 | → **5.5.0** | v5 — breaking: изменён API для symlinks | +| **typescript** | 2.4.1 | 5.9.3 | → **5.9.x** | Огромный скачок. Нужна ревизия всех .d.ts файлов | +| **@types/chai** | 4.0.1 | 5.2.3 | → **Не нужен** если chai 6 (встроенные типы) или при переходе на node:assert | +| **@types/sinon** | 2.1.2 | 21.0.0 | → **Обновить вслед за sinon** | +| **@types/proxyquire** | 1.3.27 | 1.3.31 | → **1.3.31** | +| **@types/node** | 8.0 | 25.3.0 | → **18.x** (соответственно минимальной Node) | + +--- + +## Фаза 2: Линтинг (devDependencies корня) + +| Пакет | Сейчас | Последняя | Рекомендация | Заметки | +|-------|--------|-----------|-------------|---------| +| **eslint** | 4.19.1 | 10.0.1 | → **9.x или 10.x** | v9 — flat config (`eslint.config.js`). Полностью другая конфигурация | +| **eslint-config-pedant** | 0.10.0 | 1.0.1 | → **1.0.1** | Проверить совместимость с ESLint 9+ | +| **tslint** | 5.0.0 | 6.1.3 (DEPRECATED) | → **Удалить** | TSLint deprecated с 2019. Заменить на `@typescript-eslint/eslint-plugin` + `@typescript-eslint/parser` | +| **tslint-config-typings** | 0.3.1 | 0.3.1 | → **Удалить** вместе с TSLint | + +### Замена TSLint: +``` +Удалить: tslint, tslint-config-typings +Добавить: @typescript-eslint/eslint-plugin, @typescript-eslint/parser +``` +Создать правила для .d.ts файлов в едином конфиге ESLint. + +--- + +## Фаза 3: Продакшн-зависимости пакетов + +### 3.1 Замена на нативные средства Node.js 18+ + +| Пакет | Используется в | Замена | Обоснование | +|-------|---------------|--------|-------------| +| **pinkie-promise** (2.0.1) | config | **Удалить** | `Promise` встроен в Node.js с v4. Полностью не нужен | +| **es6-promisify** (5.0.0) | decl | **Удалить** | `util.promisify()` встроен в Node.js с v8 | +| **mz** (2.4.0) | deps | **Заменить на `fs/promises`** | `fs.promises` / `require('fs/promises')` встроен в Node 18+ | +| **graceful-fs** (4.1.11) | decl | **Удалить** или заменить на нативный `fs` | В Node 18+ EMFILE-проблемы редки. Для простых операций нативный fs достаточен | +| **async-each** (1.0.1) | walk | **Заменить на `Promise.all` / `for...of`** | Тривиальная утилита, не нужна с async/await | +| **es6-error** (4.0.2) | graph, entity-name | **Удалить** | Нативный `class MyError extends Error {}` работает с Node 6+ | +| **json5** (0.5.1) | decl | → **2.2.3** или заменить | v0.5 — очень старая. Если JSON5 нужен — обновить до 2.x. Если нет — использовать JSON.parse() | +| **hash-set** (1.0.1) | graph, import-notation | **Заменить на нативный `Set`** | ES6 `Set` встроен в Node.js | +| **ho-iter** (0.3.0) | graph | **Заменить на нативные итераторы/генераторы** | Symbol.iterator и генераторы встроены | +| **uniq** (1.0.1) | (если используется) | **Заменить на `[...new Set(arr)]`** | Тривиальная операция | + +### 3.2 Обновление до актуальных версий + +| Пакет | Сейчас | Последняя | Рекомендация | Заметки | +|-------|--------|-----------|-------------|---------| +| **depd** | 1.1.0 | 2.0.0 | → **2.0.0** | Deprecation-предупреждения. v2 — ESM+CJS dual | +| **debug** | 2.6.9 | 4.4.3 | → **4.4.x** | Популярная библиотека отладки. v3+ — breaking changes в форматтерах | +| **glob** | ^7.0.5 | 13.0.6 | → **10.x+** | v8+ — breaking: убраны callbacks, только promises. v10+ — ESM. Или заменить на `fast-glob` (3.3.3) | +| **betterc** | ^1.3.0 | 1.3.0 | **Актуальна** | Без изменений | +| **node-eval** | 1.1.0 / ^2.0.0 | 2.0.0 | → **2.0.0** везде | Унифицировать версию | +| **camel-case** | ^3.0.0 | 5.0.0 | → **4.x** (CJS) или **5.x** (ESM) | v4+ — breaking API. Используется в bemjson-to-jsx | +| **pascal-case** | ^2.0.1 | 4.0.0 | → **3.x** (CJS) или **4.x** (ESM) | Аналогично camel-case | +| **stringify-object** | ^3.2.0 | 6.0.0 | → **5.x** (CJS) или **6.x** (ESM) | Используется в bemjson-to-decl | +| **xamel** | ^0.3.1 | 0.3.1 | **Актуальна** | Без изменений | +| **is-glob** | ^3.1.0 | 4.0.3 | → **4.0.3** | Минорное обновление | + +### 3.3 Lodash — консолидация и замена + +| Пакет | Используется в | Рекомендация | +|-------|---------------|-------------| +| **lodash** (4.17.15) | graph | → **4.17.23** (security patches) | +| **lodash.clonedeep** | config | → `structuredClone()` (Node 17+) | +| **lodash.flatten** | config | → `Array.prototype.flat()` (Node 11+) | +| **lodash.isequal** | config | Оставить или заменить на `util.isDeepStrictEqual()` (Node 9+) | +| **lodash.mergewith** | config | Оставить (нет нативного аналога) или написать простую функцию | +| **lodash.uniqwith** | config | Оставить или заменить на кастомную функцию с `Set` | + +**Рекомендация:** заменить `lodash.clonedeep` → `structuredClone()`, `lodash.flatten` → `.flat()`, `lodash.isequal` → `util.isDeepStrictEqual()`. Для `mergewith` и `uniqwith` — оставить lodash или использовать единый импорт `lodash/mergeWith` вместо отдельных пакетов. + +--- + +## Фаза 4: DevDependencies пакетов + +| Пакет | Используется в | Рекомендация | +|-------|---------------|-------------| +| **matcha** (^0.7.0) | decl (бенчмарки) | → заменить на **benchmark** (2.1.4) или **tinybench** | matcha заброшен | +| **benchmark** (^2.1.0) | walk | → **2.1.4** (актуальна) | +| **chai-as-promised** (^7.0.0) | config | → **8.0.2** | +| **@types/chai-as-promised** (0.0.31) | config | → обновить или убрать если chai обновлён | +| **chai-subset** (^1.6.0) | walk | → **1.6.0** (актуальна) | +| **common-tags** (^1.8.0) | keyset | → **1.8.2** (актуальна) | +| **stream-to-array** (^2.3.0) | walk, deps | → **2.3.0** (актуальна) | +| **through2** (^2.0.1) | deps | → заменить на нативный `stream.Transform` (Node 18+) | +| **promise-map-series** (^0.2.2) | walk | → заменить на `for...of` + `await` | + +--- + +## Фаза 5: Решение по CJS vs ESM + +**Ключевой вопрос:** мигрировать на ESM или оставить CJS? + +### Вариант A: Оставить CJS (минимальные усилия) +- chai оставить на 4.x, sinon на 14.x +- camel-case/pascal-case на 4.x +- glob заменить на fast-glob 3.x + +### Вариант B: Полная миграция на ESM (рекомендуется для нового проекта) +- Добавить `"type": "module"` во все package.json +- Обновить все зависимости до последних ESM-версий +- Переписать require → import +- Значительный объём работы + +### Рекомендация: **Вариант A** (CJS) — проект не активно развивается, минимальные усилия. + +--- + +## Порядок выполнения + +``` +Фаза 0: Инфраструктура (npm workspaces, GH Actions, Node >= 18) + ↓ +Фаза 3.1: Замена на нативные средства (pinkie-promise, es6-promisify, mz, ...) + ↓ +Фаза 3.3: Lodash — замена clonedeep/flatten/isequal на нативные + ↓ +Фаза 3.2: Обновление prod-зависимостей (depd, debug, glob, ...) + ↓ +Фаза 2: Линтинг (ESLint 9+, удаление TSLint) + ↓ +Фаза 1: Тестирование (mocha 11, c8, sinon 14, ...) + ↓ +Фаза 4: Dev-зависимости пакетов + ↓ +Фаза 5: (Опционально) ESM-миграция +``` + +--- + +## Сводка: что можно полностью удалить (замена на нативные средства Node 18+) + +| Удаляемый пакет | Нативная замена | +|-----------------|-----------------| +| pinkie-promise | `Promise` (встроен) | +| es6-promisify | `util.promisify()` | +| mz | `fs/promises`, `child_process` с promisify | +| es6-error | `class Err extends Error {}` | +| graceful-fs | `fs` / `fs/promises` | +| async-each | `Promise.all()` / `for await...of` | +| hash-set | `Set` | +| ho-iter | Нативные итераторы/генераторы | +| lodash.clonedeep | `structuredClone()` | +| lodash.flatten | `Array.prototype.flat()` | +| lodash.isequal | `util.isDeepStrictEqual()` | +| tslint | `@typescript-eslint` (через ESLint) | +| tslint-config-typings | `@typescript-eslint` | +| through2 | `stream.Transform` | +| promise-map-series | `for...of` + `await` | +| nyc | `c8` (V8 native coverage) | + +**Итого: 16 пакетов можно удалить**, заменив на встроенные средства Node.js 18+. diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index cd27ec85..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: "{build}" - -branches: - only: - - master - -environment: - matrix: - - nodejs_version: "8" - - nodejs_version: "10" - -install: - - ps: Install-Product node $env:nodejs_version - - node --version - - npm --version - - npm install lerna - - ./node_modules/.bin/lerna bootstrap --no-ci -- --force - -test_script: - - ./node_modules/.bin/lerna run test - -build: off diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..325dfd58 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,75 @@ +import js from '@eslint/js'; + +export default [ + js.configs.recommended, + { + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + console: 'readonly', + process: 'readonly', + setTimeout: 'readonly', + clearTimeout: 'readonly', + setInterval: 'readonly', + clearInterval: 'readonly', + URL: 'readonly', + Buffer: 'readonly', + structuredClone: 'readonly', + } + }, + rules: { + 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + } + }, + { + files: ['**/*.test.js'], + languageOptions: { + globals: { + describe: 'readonly', + it: 'readonly', + before: 'readonly', + beforeEach: 'readonly', + after: 'readonly', + afterEach: 'readonly', + utils: 'readonly', + } + }, + rules: { + 'no-unused-expressions': 'off', + } + }, + { + files: ['**/*.spec.js'], + languageOptions: { + globals: { + describe: 'readonly', + it: 'readonly', + before: 'readonly', + beforeEach: 'readonly', + after: 'readonly', + afterEach: 'readonly', + lib: 'readonly', + utils: 'readonly', + xit: 'readonly', + } + }, + rules: { + 'no-unexpected-multiline': 'off', + 'no-unused-expressions': 'off', + } + }, + { + files: ['**/*.bench.js'], + languageOptions: { + globals: { + suite: 'readonly', + set: 'readonly', + bench: 'readonly', + } + } + }, + { + ignores: ['node_modules/**', 'packages/*/node_modules/**', '.claude/**'] + } +]; diff --git a/lerna.json b/lerna.json deleted file mode 100644 index f65c1bc5..00000000 --- a/lerna.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "lerna": "2.2.0", - "packages": [ - "packages/*" - ], - "hoist": true, - "independent": true, - "version": "independent", - "npmClient": "npm", - "npmClientArgs": ["--no-package-lock"] -} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..ba578ff3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3184 @@ +{ + "name": "@bem/sdk", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@bem/sdk", + "version": "0.0.1", + "license": "MPL-2.0", + "workspaces": [ + "packages/*" + ], + "devDependencies": { + "@eslint/js": "^10.0.0", + "@types/node": "^24.0.0", + "@types/sinon": "^21.0.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "c8": "^11.0.0", + "chai": "^6.0.0", + "chai-as-promised": "^8.0.0", + "chai-subset": "^1.6.0", + "eslint": "^10.0.0", + "esmock": "^2.6.0", + "mocha": "^11.0.0", + "mock-fs": "^5.5.0", + "sinon": "^21.0.0", + "typescript": "^5.9.0" + }, + "engines": { + "node": ">= 24.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@bem/sdk.bemjson-node": { + "resolved": "packages/bemjson-node", + "link": true + }, + "node_modules/@bem/sdk.bemjson-to-decl": { + "resolved": "packages/bemjson-to-decl", + "link": true + }, + "node_modules/@bem/sdk.bemjson-to-jsx": { + "resolved": "packages/bemjson-to-jsx", + "link": true + }, + "node_modules/@bem/sdk.bundle": { + "resolved": "packages/bundle", + "link": true + }, + "node_modules/@bem/sdk.cell": { + "resolved": "packages/cell", + "link": true + }, + "node_modules/@bem/sdk.config": { + "resolved": "packages/config", + "link": true + }, + "node_modules/@bem/sdk.decl": { + "resolved": "packages/decl", + "link": true + }, + "node_modules/@bem/sdk.deps": { + "resolved": "packages/deps", + "link": true + }, + "node_modules/@bem/sdk.entity-name": { + "resolved": "packages/entity-name", + "link": true + }, + "node_modules/@bem/sdk.file": { + "resolved": "packages/file", + "link": true + }, + "node_modules/@bem/sdk.graph": { + "resolved": "packages/graph", + "link": true + }, + "node_modules/@bem/sdk.import-notation": { + "resolved": "packages/import-notation", + "link": true + }, + "node_modules/@bem/sdk.keyset": { + "resolved": "packages/keyset", + "link": true + }, + "node_modules/@bem/sdk.naming.cell.match": { + "resolved": "packages/naming.cell.match", + "link": true + }, + "node_modules/@bem/sdk.naming.cell.pattern-parser": { + "resolved": "packages/naming.cell.pattern-parser", + "link": true + }, + "node_modules/@bem/sdk.naming.cell.stringify": { + "resolved": "packages/naming.cell.stringify", + "link": true + }, + "node_modules/@bem/sdk.naming.entity": { + "resolved": "packages/naming.entity", + "link": true + }, + "node_modules/@bem/sdk.naming.entity.parse": { + "resolved": "packages/naming.entity.parse", + "link": true + }, + "node_modules/@bem/sdk.naming.entity.stringify": { + "resolved": "packages/naming.entity.stringify", + "link": true + }, + "node_modules/@bem/sdk.naming.file.stringify": { + "resolved": "packages/naming.file.stringify", + "link": true + }, + "node_modules/@bem/sdk.naming.presets": { + "resolved": "packages/naming.presets", + "link": true + }, + "node_modules/@bem/sdk.walk": { + "resolved": "packages/walk", + "link": true + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.2.tgz", + "integrity": "sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.2", + "debug": "^4.3.1", + "minimatch": "^10.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", + "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.1.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", + "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.2.tgz", + "integrity": "sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz", + "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.1.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.0.tgz", + "integrity": "sha512-cqfapCxwTGsrR80FEgOoPsTonoefMBY7dnUEbQ+GRcved0jvkJLzvX6F4WtN+HBqbPX/SiFsIRUp+IrCW/2I2w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", + "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.13.tgz", + "integrity": "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/sinon": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz", + "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/c8": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-11.0.0.tgz", + "integrity": "sha512-e/uRViGHSVIJv7zsaDKM7VRn2390TgHXqUSvYwPHBQaU6L7E9L0n9JbdkwdYPvshDT0KymBmmlwSpms3yBaMNg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.1", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^8.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": "20 || >=22" + }, + "peerDependencies": { + "monocart-coverage-reports": "^2" + }, + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true + } + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/chai-as-promised": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.2.tgz", + "integrity": "sha512-1GadL+sEJVLzDjcawPM4kjfnL+p/9vrxiEUonowKOAzvVg0PixJUdtuDzdkDeQhK3zfOE76GqGkZIQ7/Adcrqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "check-error": "^2.1.1" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 7" + } + }, + "node_modules/chai-subset": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz", + "integrity": "sha512-K3d+KmqdS5XKW5DWPd5sgNffL3uxdDe+6GdnJh3AYPhwnBGRY5urfvfcbRtWIvvpz+KxkL9FeBB6MZewLUNwug==", + "deprecated": "functionality of this lib is built-in to chai now. see more details here: https://github.com/debitoor/chai-subset/pull/85", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "license": "MIT" + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.2.tgz", + "integrity": "sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.2", + "@eslint/config-helpers": "^0.5.2", + "@eslint/core": "^1.1.0", + "@eslint/plugin-kit": "^0.6.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.1", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.1.1", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.1", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.1.tgz", + "integrity": "sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/esmock": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esmock/-/esmock-2.7.3.tgz", + "integrity": "sha512-/M/YZOjgyLaVoY6K83pwCsGE1AJQnj4S4GyXLYgi/Y79KL8EeW6WU7Rmjc89UO7jv6ec8+j34rKeWOfiLeEu0A==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14.16.0" + } + }, + "node_modules/espree": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.1.tgz", + "integrity": "sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", + "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mocha": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mock-fs": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.5.0.tgz", + "integrity": "sha512-d/P1M/RacgM3dB0sJ8rjeRNXxtapkPCUnMGmIN0ixJ16F/E4GUZCvWcSGfWGz8eaXYvn1s9baUwNjI4LOPEjiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sinon": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.1.tgz", + "integrity": "sha512-Z0NVCW45W8Mg5oC/27/+fCqIHFnW8kpkFOq0j9XJIev4Ld0mKmERaZv5DMLAb9fGCevjKwaEeIQz5+MBXfZcDw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^15.1.0", + "@sinonjs/samsam": "^8.0.3", + "diff": "^8.0.2", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz", + "integrity": "sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^13.0.6", + "minimatch": "^10.2.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "packages/bemjson-node": { + "name": "@bem/sdk.bemjson-node", + "version": "0.0.6", + "license": "MPL-2.0", + "engines": { + "node": ">= 24.0" + } + }, + "packages/bemjson-to-decl": { + "name": "@bem/sdk.bemjson-to-decl", + "version": "0.2.15", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.decl": "^0.3.10", + "@bem/sdk.entity-name": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/bemjson-to-jsx": { + "name": "@bem/sdk.bemjson-to-jsx", + "version": "0.2.9", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.naming.entity.stringify": "^1.1.2", + "@bem/sdk.naming.presets": "^0.2.3", + "change-case": "^5.0.0" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/bundle": { + "name": "@bem/sdk.bundle", + "version": "0.2.15", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.bemjson-to-decl": "^0.2.15" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/cell": { + "name": "@bem/sdk.cell", + "version": "0.2.9", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.entity-name": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/config": { + "name": "@bem/sdk.config", + "version": "0.1.0", + "license": "MPL-2.0", + "dependencies": { + "cosmiconfig": "^9.0.0" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/decl": { + "name": "@bem/sdk.decl", + "version": "0.3.10", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.cell": "^0.2.9", + "@bem/sdk.entity-name": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/deps": { + "name": "@bem/sdk.deps", + "version": "0.3.1", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.config": "^0.1.0", + "@bem/sdk.decl": "^0.3.10", + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.graph": "^0.3.3", + "@bem/sdk.walk": "^0.6.0" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/entity-name": { + "name": "@bem/sdk.entity-name", + "version": "0.2.11", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.naming.entity.stringify": "^1.1.2", + "@bem/sdk.naming.presets": "^0.2.3" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/file": { + "name": "@bem/sdk.file", + "version": "0.3.5", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.cell": "^0.2.9" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/graph": { + "name": "@bem/sdk.graph", + "version": "0.3.3", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.cell": "^0.2.9", + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.naming.entity": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/import-notation": { + "name": "@bem/sdk.import-notation", + "version": "0.0.7", + "license": "MPL-2.0", + "engines": { + "node": ">= 24.0" + } + }, + "packages/keyset": { + "name": "@bem/sdk.keyset", + "version": "0.1.1", + "license": "MPL-2.0", + "dependencies": { + "fast-xml-parser": "^4.5.3" + }, + "devDependencies": { + "common-tags": "^1.8.0" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.cell.match": { + "name": "@bem/sdk.naming.cell.match", + "version": "0.1.3", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.cell": "^0.2.9", + "@bem/sdk.naming.cell.pattern-parser": "^0.0.7", + "@bem/sdk.naming.entity.parse": "^0.2.9" + }, + "devDependencies": { + "@bem/sdk.naming.presets": "^0.2.3" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.cell.pattern-parser": { + "name": "@bem/sdk.naming.cell.pattern-parser", + "version": "0.0.7", + "license": "MPL-2.0", + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.cell.stringify": { + "name": "@bem/sdk.naming.cell.stringify", + "version": "0.0.13", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.naming.cell.pattern-parser": "^0.0.7" + }, + "devDependencies": { + "@bem/sdk.cell": "^0.2.9", + "@bem/sdk.naming.entity": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.entity": { + "name": "@bem/sdk.naming.entity", + "version": "0.2.11", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.naming.entity.parse": "^0.2.9", + "@bem/sdk.naming.entity.stringify": "^1.1.2", + "@bem/sdk.naming.presets": "^0.2.3" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.entity.parse": { + "name": "@bem/sdk.naming.entity.parse", + "version": "0.2.9", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.entity-name": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.entity.stringify": { + "name": "@bem/sdk.naming.entity.stringify", + "version": "1.1.2", + "license": "MPL-2.0", + "devDependencies": { + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.naming.presets": "^0.2.3" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.file.stringify": { + "name": "@bem/sdk.naming.file.stringify", + "version": "0.1.11", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.naming.cell.stringify": "^0.0.13" + }, + "devDependencies": { + "@bem/sdk.file": "^0.3.5" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/naming.presets": { + "name": "@bem/sdk.naming.presets", + "version": "0.2.3", + "license": "MPL-2.0", + "devDependencies": { + "@bem/sdk.cell": "^0.2.9", + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.naming.cell.stringify": "^0.0.13", + "@bem/sdk.naming.entity": "^0.2.11" + }, + "engines": { + "node": ">= 24.0" + } + }, + "packages/walk": { + "name": "@bem/sdk.walk", + "version": "0.6.0", + "license": "MPL-2.0", + "dependencies": { + "@bem/sdk.cell": "^0.2.9", + "@bem/sdk.config": "^0.1.0", + "@bem/sdk.entity-name": "^0.2.11", + "@bem/sdk.file": "^0.3.5", + "@bem/sdk.naming.cell.match": "^0.1.3", + "@bem/sdk.naming.entity.parse": "^0.2.9", + "@bem/sdk.naming.entity.stringify": "^1.1.2", + "@bem/sdk.naming.presets": "^0.2.3" + }, + "engines": { + "node": ">= 24.0" + } + } + } +} diff --git a/package.json b/package.json index bbcd4f45..daea3a64 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,14 @@ "name": "@bem/sdk", "version": "0.0.1", "description": "BEM SDK", + "type": "module", "keywords": [ "bem", "sdk" ], + "workspaces": [ + "packages/*" + ], "repository": "bem/bem-sdk", "author": "Alexey Yaroshevich (github.com/zxqfox)", "license": "MPL-2.0", @@ -14,37 +18,28 @@ }, "homepage": "https://github.com/bem/bem-sdk#readme", "engines": { - "node": ">= 4.0" + "node": ">= 24.0" }, "devDependencies": { - "@types/chai": "^4.0.1", - "@types/proxyquire": "^1.3.27", - "@types/sinon": "^2.1.2", - "chai": "^4.1.2", - "eslint": "^4.19.1", - "eslint-config-pedant": "^0.10.0", - "mocha": "^3.4.2", - "mock-fs": "^4.4.1", - "nyc": "^11.0.3", - "proxyquire": "^1.8.0", - "sinon": "^2.3.6", - "tslint": "^5.0.0", - "tslint-config-typings": "^0.3.1", - "typescript": "^2.4.1" + "@eslint/js": "^10.0.0", + "@types/node": "^24.0.0", + "@types/sinon": "^21.0.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "c8": "^11.0.0", + "chai": "^6.0.0", + "chai-as-promised": "^8.0.0", + "chai-subset": "^1.6.0", + "eslint": "^10.0.0", + "esmock": "^2.6.0", + "mocha": "^11.0.0", + "mock-fs": "^5.5.0", + "sinon": "^21.0.0", + "typescript": "^5.9.0" }, "scripts": { - "lint": "npm run lint:js && npm run lint:dts", - "lint:js": "eslint .", - "lint:dts": "tslint packages/*/types/*.d.ts", + "lint": "eslint .", "pretest": "npm run lint", - "test": "nyc mocha 'packages/*/{test,spec}/**/*.{test,spec}.js'", - "test:specs": "mocha tests", - "test:cover": "nyc mocha tests" - }, - "nyc": { - "exclude": [ - "**/*.test.js", - "**/*.spec.js" - ] + "test": "c8 mocha \"packages/*/{test,spec}/**/*.{test,spec}.js\"" } } diff --git a/packages/bemjson-node/index.js b/packages/bemjson-node/index.js index a8ac0460..af9730d3 100644 --- a/packages/bemjson-node/index.js +++ b/packages/bemjson-node/index.js @@ -1,3 +1 @@ -'use strict'; - -module.exports = require('./lib/bemjson-node'); +export { default } from './lib/bemjson-node.js'; diff --git a/packages/bemjson-node/lib/bemjson-node.js b/packages/bemjson-node/lib/bemjson-node.js index e0780014..d2e264c7 100644 --- a/packages/bemjson-node/lib/bemjson-node.js +++ b/packages/bemjson-node/lib/bemjson-node.js @@ -1,7 +1,5 @@ -'use strict'; - -const assert = require('assert'); -const util = require('util'); +import assert from 'node:assert'; +import util from 'node:util'; class BemjsonNode { /** @@ -48,7 +46,7 @@ class BemjsonNode { * Returns the block name of bemjson node. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button' }); * * node.block; // button @@ -63,7 +61,7 @@ class BemjsonNode { * If node's entity is not an element then returns null. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button', elem: 'text' }); * * node.elem; // text @@ -76,7 +74,7 @@ class BemjsonNode { * Returns modifiers of block entity of bemjson node (or of a scope). * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button', mods: { m: 'v' }, elem: 'text' }); * * node.mods; // { m: 'v' } @@ -89,7 +87,7 @@ class BemjsonNode { * Returns modifiers of element entity of bemjson node or null if there is no element. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button', elem: 'e', elemMods: { m: 'v' } }); * * node.elemMods; // { m: 'v' } @@ -114,7 +112,7 @@ class BemjsonNode { * This method will be called to get custom string representation of the object. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button', mix: { block: x } }); * * node.valueOf(); @@ -144,7 +142,7 @@ class BemjsonNode { * Returns raw data for `JSON.stringify()` purposes. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * * const node = new BemjsonNode({ block: 'input', mods: { available: true } }); * @@ -163,7 +161,7 @@ class BemjsonNode { * you should use `@bem/naming` package. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button', mod: 'focused' }); * * node.toString(); // button_focused @@ -190,7 +188,7 @@ class BemjsonNode { * This method will be called to get custom string representation of the object. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * const node = new BemjsonNode({ block: 'button' }); * * console.log(name); // BemjsonNode { block: 'button' } @@ -211,7 +209,7 @@ class BemjsonNode { * Determines whether specified argument is instance of BemjsonNode. * * @example - * const BemjsonNode = require('@bem/sdk.bemjson-node'); + * import BemjsonNode from '@bem/sdk.bemjson-node'; * * const bemjsonNode = new BemjsonNode({ block: 'input' }); * @@ -226,9 +224,4 @@ class BemjsonNode { } } -module.exports = BemjsonNode; - -// TypeScript imports the `default` property for -// an ES2015 default import (`import BemjsonNode from '@bem/sdk.bemjson-node'`) -// See: https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-83694181 -module.exports.default = BemjsonNode; +export default BemjsonNode; diff --git a/packages/bemjson-node/package.json b/packages/bemjson-node/package.json index d5cb7559..8c6744ed 100644 --- a/packages/bemjson-node/package.json +++ b/packages/bemjson-node/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.bemjson-node", "version": "0.0.6", "description": "BEM tree node representation", + "type": "module", "publishConfig": { "access": "public" }, @@ -27,19 +28,10 @@ "index.d.ts" ], "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, - "devDependencies": { - "@types/node": "^8.0" - }, - "scripts": { +"scripts": { "test": "npm run specs", - "specs": "mocha", - "cover": "nyc mocha" - }, - "greenkeeper": { - "ignore": [ - "@types/node" - ] + "specs": "mocha" } } diff --git a/packages/bemjson-node/test/constructor/constructor.test.js b/packages/bemjson-node/test/constructor/constructor.test.js index 5eb28fd4..0149e978 100644 --- a/packages/bemjson-node/test/constructor/constructor.test.js +++ b/packages/bemjson-node/test/constructor/constructor.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemjsonNode = require('../..'); +import BemjsonNode from '../../index.js'; describe('constructor tests', () => { diff --git a/packages/bemjson-node/test/constructor/errors.test.js b/packages/bemjson-node/test/constructor/errors.test.js index 37c8bd62..e9f621d2 100644 --- a/packages/bemjson-node/test/constructor/errors.test.js +++ b/packages/bemjson-node/test/constructor/errors.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemjsonNode = require('../..'); +import BemjsonNode from '../../index.js'; describe('test errors', () => { it('should throw error if not `block` field', () => { diff --git a/packages/bemjson-node/test/constructor/normalize.test.js b/packages/bemjson-node/test/constructor/normalize.test.js index 70ad1f34..0f2272a4 100644 --- a/packages/bemjson-node/test/constructor/normalize.test.js +++ b/packages/bemjson-node/test/constructor/normalize.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemjsonNode = require('../..'); +import BemjsonNode from '../../index.js'; describe('normalize', () => { diff --git a/packages/bemjson-node/test/mocha.opts b/packages/bemjson-node/test/mocha.opts deleted file mode 100644 index 0d6c0257..00000000 --- a/packages/bemjson-node/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---require test/setup --recursive diff --git a/packages/bemjson-node/test/setup.js b/packages/bemjson-node/test/setup.js index 66d704ca..62e1fa15 100644 --- a/packages/bemjson-node/test/setup.js +++ b/packages/bemjson-node/test/setup.js @@ -1,3 +1,2 @@ -'use strict'; // To silence deprecation warnings from being output process.env.NO_DEPRECATION = '@bem/sdk.entity-name'; diff --git a/packages/bemjson-to-decl/index.js b/packages/bemjson-to-decl/index.js index 48fffc58..c0621917 100644 --- a/packages/bemjson-to-decl/index.js +++ b/packages/bemjson-to-decl/index.js @@ -1,8 +1,6 @@ -'use strict'; - -const stringifyObj = require('stringify-object'); -const normalize = require('@bem/sdk.decl').normalize; -const BemEntity = require('@bem/sdk.entity-name'); +import { inspect } from 'node:util'; +import { normalize } from '@bem/sdk.decl'; +import BemEntity from '@bem/sdk.entity-name'; function getEntities(bemjson, ctx) { const visited = {}; @@ -80,10 +78,10 @@ function stringify(bemjson, ctx, opts) { opts || (opts = {}); opts.indent || (opts.indent = ' '); - return stringifyObj(getEntities(bemjson, ctx).map(entity => entity.toJSON()), opts); + return inspect(getEntities(bemjson, ctx).map(entity => entity.toJSON()), { depth: Infinity, compact: false }); } -module.exports = { +export default { convert: getEntities, stringify: stringify }; diff --git a/packages/bemjson-to-decl/package.json b/packages/bemjson-to-decl/package.json index 2439ebcf..c052b7e9 100644 --- a/packages/bemjson-to-decl/package.json +++ b/packages/bemjson-to-decl/package.json @@ -2,13 +2,13 @@ "name": "@bem/sdk.bemjson-to-decl", "version": "0.2.15", "description": "BEMJSON to BEMDECL helper", + "type": "module", "publishConfig": { "access": "public" }, "main": "index.js", "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" }, "repository": "bem/bem-sdk", @@ -26,11 +26,10 @@ "author": "Vladimir Grinenko", "license": "MPL-2.0", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "dependencies": { "@bem/sdk.decl": "^0.3.10", - "@bem/sdk.entity-name": "^0.2.11", - "stringify-object": "^3.2.0" + "@bem/sdk.entity-name": "^0.2.11" } } diff --git a/packages/bemjson-to-decl/test/get-entities.test.js b/packages/bemjson-to-decl/test/get-entities.test.js index a3f96f2e..dd46beb0 100644 --- a/packages/bemjson-to-decl/test/get-entities.test.js +++ b/packages/bemjson-to-decl/test/get-entities.test.js @@ -1,10 +1,9 @@ -'use strict'; +import { expect, use } from 'chai'; +import helpers from './helpers.js'; +use(helpers); -const chai = require('chai'); -chai.use(require('./helpers')); -const expect = require('chai').expect; - -const parse = require('..').convert; +import bemjsonToDecl from '../index.js'; +const parse = bemjsonToDecl.convert; it('should return an array', () => { expect(parse({ block: 'button2' })).to.be.an('Array'); diff --git a/packages/bemjson-to-decl/test/helpers.js b/packages/bemjson-to-decl/test/helpers.js index 57bce5d0..af77dea4 100644 --- a/packages/bemjson-to-decl/test/helpers.js +++ b/packages/bemjson-to-decl/test/helpers.js @@ -1,9 +1,9 @@ -'use strict'; +import BemEntity from '@bem/sdk.entity-name'; +import { inspect } from 'node:util'; -const b_ = require('@bem/sdk.entity-name').create; -const util = require('util'); +const b_ = BemEntity.create; -module.exports = function bemeql(chai) { +export default function bemeql(chai) { var Assertion = chai.Assertion; Assertion.addMethod('bemeql', function (obj) { @@ -13,8 +13,8 @@ module.exports = function bemeql(chai) { this.assert(false, 'expected #{act} to deeply equal #{exp}', 'expected #{act} to not deeply equal #{exp}', - obj.map(inspect), - this._obj.map(inspect), + obj.map(inspectEl), + this._obj.map(inspectEl), true ); } @@ -24,15 +24,15 @@ module.exports = function bemeql(chai) { bemObj.every((e, i) => e.isEqual ? e.isEqual(this._obj[i]) : false), 'expected #{act} to deeply equal #{exp}', 'expected #{act} to not deeply equal #{exp}', - bemObj.map(inspect), - this._obj.map(inspect), + bemObj.map(inspectEl), + this._obj.map(inspectEl), true ); } - function inspect(el) { - return util.inspect(el, { breakLength: Infinity, maxArrayLength: null, depth: null }); + function inspectEl(el) { + return inspect(el, { breakLength: Infinity, maxArrayLength: null, depth: null }); } }); -}; +} diff --git a/packages/bemjson-to-decl/test/mocha.opts b/packages/bemjson-to-decl/test/mocha.opts deleted file mode 100644 index 736443bb..00000000 --- a/packages/bemjson-to-decl/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---require test/helpers diff --git a/packages/bemjson-to-decl/test/stringify.test.js b/packages/bemjson-to-decl/test/stringify.test.js index c2073c36..e25e5fcf 100644 --- a/packages/bemjson-to-decl/test/stringify.test.js +++ b/packages/bemjson-to-decl/test/stringify.test.js @@ -1,14 +1,13 @@ -'use strict'; - -const expect = require('chai').expect; -const stringify = require('..').stringify; +import { expect } from 'chai'; +import bemjsonToDecl from '../index.js'; +const stringify = bemjsonToDecl.stringify; it('should stringify simple bemjson', () => { expect(stringify({ block: 'button2' })).to.equal( `[ - { - block: 'button2' - } + { + block: 'button2' + } ]`); }); @@ -21,33 +20,33 @@ it('should stringify bemjson with several entities', () => { { block: 'icon', mods: { type: 'right' }} ]})).to.equal( `[ - { - block: 'button2' - }, - { - block: 'icon' - }, - { - block: 'icon', - mod: { - name: 'type', - val: true - } - }, - { - block: 'icon', - mod: { - name: 'type', - val: 'left' - } - }, - { - block: 'icon', - mod: { - name: 'type', - val: 'right' - } + { + block: 'button2' + }, + { + block: 'icon' + }, + { + block: 'icon', + mod: { + name: 'type', + val: true + } + }, + { + block: 'icon', + mod: { + name: 'type', + val: 'left' } + }, + { + block: 'icon', + mod: { + name: 'type', + val: 'right' + } + } ]`); }); @@ -55,10 +54,10 @@ it('should stringify bemjson with several entities', () => { it('should stringify bemjson with ctx', () => { expect(stringify({ elem: 'text' }, { block: 'button2' })).to.equal( `[ - { - block: 'button2', - elem: 'text' - } + { + block: 'button2', + elem: 'text' + } ]`); }); diff --git a/packages/bemjson-to-jsx/lib/helpers.js b/packages/bemjson-to-jsx/lib/helpers.js index c0b7c438..49aa3ed6 100644 --- a/packages/bemjson-to-jsx/lib/helpers.js +++ b/packages/bemjson-to-jsx/lib/helpers.js @@ -1,5 +1,3 @@ -'use strict'; - function valToStr(val) { switch(typeof val) { case 'string': @@ -31,7 +29,7 @@ function styleToObj(style) { if (typeof style === 'string') { return style.split(';').reduce((acc, st) => { if (st.length) { - var prop = st.split(':'); + const prop = st.split(':'); acc[prop[0]] = prop[1]; } return acc; @@ -40,7 +38,7 @@ function styleToObj(style) { return style; } -module.exports = { +export { objToStr, arrToStr, styleToObj, diff --git a/packages/bemjson-to-jsx/lib/index.js b/packages/bemjson-to-jsx/lib/index.js index f886bab9..2ade6340 100644 --- a/packages/bemjson-to-jsx/lib/index.js +++ b/packages/bemjson-to-jsx/lib/index.js @@ -1,15 +1,12 @@ -'use strict'; +import createStringify from '@bem/sdk.naming.entity.stringify'; +import createNamingPreset from '@bem/sdk.naming.presets/create.js'; +import BemEntity from '@bem/sdk.entity-name'; +import { pascalCase } from 'change-case'; -var createStringify = require('@bem/sdk.naming.entity.stringify'); -var createNamingPreset = require('@bem/sdk.naming.presets/create'); -var BemEntity = require('@bem/sdk.entity-name'); -var pascalCase = require('pascal-case'); +import reactMappings from './reactMappings.js'; +import { valToStr, styleToObj } from './helpers.js'; -var reactMappings = require('./reactMappings'); -var valToStr = require('./helpers').valToStr; -var styleToObj = require('./helpers').styleToObj; - -var plugins = require('./plugins'); +import * as plugins from './plugins.js'; function JSXNode(tag, props, children) { this.tag = tag || 'div'; @@ -20,7 +17,7 @@ function JSXNode(tag, props, children) { this.simpleText = ''; } -var propsToStr = props => Object.keys(props).reduce((acc, k) => { +const propsToStr = props => Object.keys(props).reduce((acc, k) => { if (typeof props[k] === 'string') { return acc + ` ${k}=${valToStr(props[k])}` } else if (props[k] instanceof JSXNode) { @@ -29,20 +26,20 @@ var propsToStr = props => Object.keys(props).reduce((acc, k) => { return acc + ` ${k}={${valToStr(props[k])}}` } }, ''); -var tagToClass = tag => reactMappings[tag] ? tag : pascalCase(tag); +const tagToClass = tag => reactMappings[tag] ? tag : pascalCase(tag); JSXNode.prototype.toString = function() { if (this.isText) { return this.simpleText; } - var tag = tagToClass(this.tag); - var children = [].concat(this.children) + const tag = tagToClass(this.tag); + const children = [].concat(this.children) .filter(Boolean) // remove empty text nodes .filter(child => !(child.isText && child.simpleText === '')); - var str = children.length ? + const str = children.length ? `<${tag}${propsToStr(this.props)}>\n${children.join('\n')}\n` : `<${tag}${propsToStr(this.props)}/>`; return str; @@ -55,19 +52,19 @@ function Transformer(options) { } Transformer.prototype.process = function(bemjson) { - var nodes = [{ + const nodes = [{ json: bemjson, id: 0, blockName: '', tree: [] }]; - var root = nodes[0]; + const root = nodes[0]; - var node; + let node; - var setJsx = (json) => { - var jsx = new JSXNode(); - var _blockName = json.block || node.blockName; + const setJsx = (json) => { + const jsx = new JSXNode(); + const _blockName = json.block || node.blockName; if (typeof json === 'string') { jsx.isText = true; @@ -85,21 +82,21 @@ Transformer.prototype.process = function(bemjson) { }; while((node = nodes.shift())) { - var json = node.json, i; + let json = node.json, i; if (Array.isArray(json)) { for (i = 0; i < json.length; i++) { nodes.push({ json: json[i], id: i, tree: node.tree, blockName: node.blockName}); } } else { - var res = undefined; - var blockName = json.block || node.blockName; + let res = undefined; + const blockName = json.block || node.blockName; - var jsx = setJsx(json); + const jsx = setJsx(json); - for (var key in json) { + for (const key in json) { if (!~['mix', 'content', 'attrs'].indexOf(key) && typeof Object(json[key]).block === 'string') { - var nestedJSX = setJsx(json[key]); + const nestedJSX = setJsx(json[key]); for (i = 0; i < this.plugins.length; i++) { this.plugins[i](nestedJSX, Object.assign({ block: json[key].block }, json[key])); @@ -110,7 +107,7 @@ Transformer.prototype.process = function(bemjson) { } for (i = 0; i < this.plugins.length; i++) { - var plugin = this.plugins[i]; + const plugin = this.plugins[i]; res = plugin(jsx, Object.assign({ block: blockName }, json)); if (res !== undefined) { json = res; @@ -122,11 +119,11 @@ Transformer.prototype.process = function(bemjson) { } if (res === undefined) { - var content = json.content; + let content = json.content; if (content) { if (Array.isArray(content)) { // content: [[[{}, {}, [{}]]]] - var flatten; + let flatten; do { flatten = false; for (i = 0; i < content.length; i++) { @@ -177,10 +174,13 @@ function render(tree) { Transformer.prototype.Transformer = Transformer; -module.exports = function(opts) { +const bemjsonToJsx = function(opts) { return new Transformer(opts || {}); }; -module.exports.tagToClass = tagToClass; -module.exports.plugins = plugins; -module.exports.styleToObj = styleToObj; +bemjsonToJsx.tagToClass = tagToClass; +bemjsonToJsx.plugins = plugins; +bemjsonToJsx.styleToObj = styleToObj; + +export default bemjsonToJsx; +export { tagToClass, plugins, styleToObj }; diff --git a/packages/bemjson-to-jsx/lib/plugins.js b/packages/bemjson-to-jsx/lib/plugins.js index 4464de22..eb2cd441 100644 --- a/packages/bemjson-to-jsx/lib/plugins.js +++ b/packages/bemjson-to-jsx/lib/plugins.js @@ -1,25 +1,21 @@ -'use strict'; +import { camelCase } from 'change-case'; +import { styleToObj, valToStr } from './helpers.js'; -var camelCase = require('camel-case'); -var helpers = require('./helpers'); -var styleToObj = helpers.styleToObj; -var valToStr = helpers.valToStr; - -module.exports.copyMods = () => function copyMods(jsx, bemjson) { +export const copyMods = () => function copyMods(jsx, bemjson) { bemjson.elem ? bemjson.elemMods && Object.assign(jsx.props, bemjson.elemMods) : bemjson.mods && Object.assign(jsx.props, bemjson.mods); }; -module.exports.camelCaseProps = () => function camelCaseProps(jsx) { +export const camelCaseProps = () => function camelCaseProps(jsx) { jsx.props = Object.keys(jsx.props).reduce((acc, propKey) => { acc[camelCase(propKey)] = jsx.props[propKey]; return acc; }, {}); }; -module.exports.copyCustomFields = () => function copyCustomFields(jsx, bemjson) { - var blackList = ['content', 'block', 'elem', 'mods', 'elemMods', 'tag', 'js']; +export const copyCustomFields = () => function copyCustomFields(jsx, bemjson) { + const blackList = ['content', 'block', 'elem', 'mods', 'elemMods', 'tag', 'js']; Object.keys(bemjson).forEach(k => { if(~blackList.indexOf(k)) { return; } @@ -31,7 +27,7 @@ module.exports.copyCustomFields = () => function copyCustomFields(jsx, bemjson) }); }; -module.exports.stylePropToObj = () => function stylePropToObj(jsx) { +export const stylePropToObj = () => function stylePropToObj(jsx) { if (jsx.props['style']) { jsx.props['style'] = styleToObj(jsx.props['style']) jsx.props['attrs'] && @@ -39,7 +35,7 @@ module.exports.stylePropToObj = () => function stylePropToObj(jsx) { } }; -module.exports.keepWhiteSpaces = () => function keepWhiteSpaces(jsx) { +export const keepWhiteSpaces = () => function keepWhiteSpaces(jsx) { if (jsx.isText) { if (jsx.simpleText[0] === ' ' || jsx.simpleText[jsx.simpleText.length - 1] === ' ') { // wrap to {} to keep spaces @@ -48,15 +44,15 @@ module.exports.keepWhiteSpaces = () => function keepWhiteSpaces(jsx) { } }; -module.exports.defaultPlugins = [ - module.exports.keepWhiteSpaces, - module.exports.copyMods, - module.exports.camelCaseProps, - module.exports.copyCustomFields, - module.exports.stylePropToObj +export const defaultPlugins = [ + keepWhiteSpaces, + copyMods, + camelCaseProps, + copyCustomFields, + stylePropToObj ]; -module.exports.whiteList = function(options) { +export const whiteList = function(options) { options = options || {}; return function(jsx) { if (options.entities && jsx.bemEntity) { @@ -66,4 +62,3 @@ module.exports.whiteList = function(options) { } } }; - diff --git a/packages/bemjson-to-jsx/lib/reactMappings.js b/packages/bemjson-to-jsx/lib/reactMappings.js index b8cb2684..ca54b93e 100644 --- a/packages/bemjson-to-jsx/lib/reactMappings.js +++ b/packages/bemjson-to-jsx/lib/reactMappings.js @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +export default { a: 'a', abbr: 'abbr', address: 'address', diff --git a/packages/bemjson-to-jsx/package.json b/packages/bemjson-to-jsx/package.json index 15689a14..c0025197 100644 --- a/packages/bemjson-to-jsx/package.json +++ b/packages/bemjson-to-jsx/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.bemjson-to-jsx", "version": "0.2.9", "description": "Transform BEMJSON to JSX", + "type": "module", "publishConfig": { "access": "public" }, @@ -13,7 +14,6 @@ ], "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" }, "keywords": [ @@ -25,11 +25,13 @@ "url": "https://github.com/bem/bem-sdk/issues?q=label%3Apkg%3Abemjson-to-jsx" }, "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/bemjson-to-jsx#readme", + "engines": { + "node": ">= 24.0" + }, "dependencies": { "@bem/sdk.entity-name": "^0.2.11", "@bem/sdk.naming.entity.stringify": "^1.1.2", - "@bem/sdk.naming.presets": "^0.0.9", - "camel-case": "^3.0.0", - "pascal-case": "^2.0.1" + "@bem/sdk.naming.presets": "^0.2.3", + "change-case": "^5.0.0" } } diff --git a/packages/bemjson-to-jsx/test/helpers.test.js b/packages/bemjson-to-jsx/test/helpers.test.js index 7ad477b4..35b62407 100644 --- a/packages/bemjson-to-jsx/test/helpers.test.js +++ b/packages/bemjson-to-jsx/test/helpers.test.js @@ -1,10 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const expect = require('chai').expect; - -const helpers = require('../lib/helpers'); -const objToStr = helpers.objToStr; -const styleToObj = helpers.styleToObj; +import { objToStr, styleToObj } from '../lib/helpers.js'; describe('helpers: objToStr', () => { @@ -24,7 +20,7 @@ describe('helpers: objToStr', () => { expect(objToStr({ 'hello world': 42 })).to.equal('{ \'hello world\': 42 }'); }); - xit('should process computed property names', () => { + it.skip('should process computed property names', () => { expect(objToStr({ ['hello' + 'world']: 42 })).to.equal('{ [\'hello\' + \'world\']: 42 }'); }); @@ -65,12 +61,12 @@ describe('helpers: objToStr', () => { describe('helpers: styleToObj', () => { it('should transform style string to style obj', () => { - var obj = styleToObj('width:200px;height:100px;'); + const obj = styleToObj('width:200px;height:100px;'); expect(obj).to.eql({ width: '200px', height: '100px' }); }); it('should not transform style obj to smth else', () => { - var obj = styleToObj({ width: '200px', height: '100px' }); + const obj = styleToObj({ width: '200px', height: '100px' }); expect(obj).to.eql({ width: '200px', height: '100px' }); }); }); diff --git a/packages/bemjson-to-jsx/test/index.test.js b/packages/bemjson-to-jsx/test/index.test.js index d2d353bf..338ac8fa 100644 --- a/packages/bemjson-to-jsx/test/index.test.js +++ b/packages/bemjson-to-jsx/test/index.test.js @@ -1,9 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const expect = require('chai').expect; +import T from '../lib/index.js'; -var transformer = require('../lib')(); -var transform = transformer.process.bind(transformer); +const transformer = T(); +const transform = transformer.process.bind(transformer); describe('transform', () => { diff --git a/packages/bemjson-to-jsx/test/plugins.test.js b/packages/bemjson-to-jsx/test/plugins.test.js index ba737af7..8046f631 100644 --- a/packages/bemjson-to-jsx/test/plugins.test.js +++ b/packages/bemjson-to-jsx/test/plugins.test.js @@ -1,16 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const expect = require('chai').expect; +import T from '../lib/index.js'; -var T = require('../lib'); - -var BemEntity = require('@bem/sdk.entity-name'); +import BemEntity from '@bem/sdk.entity-name'; describe('pluginis', () => { describe('copyMods', () => { it('without elem', () => { - var res = T().process({ + const res = T().process({ block: 'button2', mods: {size: 'm', theme: 'normal'}, elemMods: {size: 'l', theme: 'dark'} @@ -22,7 +20,7 @@ describe('pluginis', () => { }); it('with elem', () => { - var res = T() + const res = T() .process({ block: 'button2', elem: 'text', @@ -38,7 +36,7 @@ describe('pluginis', () => { describe('whiteList', () => { it('without opts', () => { - var res = T() + const res = T() .use(T.plugins.whiteList()) .process({ block: 'button2' }); @@ -48,7 +46,7 @@ describe('pluginis', () => { }); it('whiteList', () => { - var res = T() + const res = T() .use(T.plugins.whiteList({ entities: [{ block: 'button2' }].map(BemEntity.create) })) .process({ block: 'button2', content: [{ block: 'menu' }, { block: 'selec' }] }); @@ -60,7 +58,7 @@ describe('pluginis', () => { describe('camelCaseProps', () => { it('should transform mod-name to modName', () => { - var res = T().process({ block: 'button2', mods: { 'has-clear': 'yes' } }); + const res = T().process({ block: 'button2', mods: { 'has-clear': 'yes' } }); expect(res.JSX).to.equal( `` @@ -68,7 +66,7 @@ describe('pluginis', () => { }); it('should transform several mod-names to modName', () => { - var res = T().process({ block: 'button2', mods: { 'has-clear': 'yes', 'has-tick': 'too' } }); + const res = T().process({ block: 'button2', mods: { 'has-clear': 'yes', 'has-tick': 'too' } }); expect(res.JSX).to.equal( `` @@ -76,7 +74,7 @@ describe('pluginis', () => { }); it('should distinguish mod-name and modname', () => { - var res = T().process({ block: 'button2', mods: { 'has-clear': 'yes', 'hasclear': 'yes' } }); + const res = T().process({ block: 'button2', mods: { 'has-clear': 'yes', 'hasclear': 'yes' } }); expect(res.JSX).to.equal( `` @@ -86,7 +84,7 @@ describe('pluginis', () => { describe('stylePropToObj', () => { it('styleProp to obj', () => { - var res = T().process({ block: 'button2', style: 'width:200px' }); + const res = T().process({ block: 'button2', style: 'width:200px' }); expect(res.JSX).to.equal( `` @@ -94,7 +92,7 @@ describe('pluginis', () => { }); it('attrs style to obj', () => { - var res = T().process({ block: 'button2', attrs: { style: 'width:200px' } }); + const res = T().process({ block: 'button2', attrs: { style: 'width:200px' } }); expect(res.JSX).to.equal( `` @@ -104,7 +102,7 @@ describe('pluginis', () => { describe('keepWhiteSpaces', () => { it('should keep spaces before simple text', () => { - var res = T().process({ block: 'button2', content: ' space before' }); + const res = T().process({ block: 'button2', content: ' space before' }); expect(res.JSX).to.equal( `\n{' space before'}\n` @@ -112,7 +110,7 @@ describe('pluginis', () => { }); it('should keep spaces after simple text', () => { - var res = T().process({ block: 'button2', content: 'space after ' }); + const res = T().process({ block: 'button2', content: 'space after ' }); expect(res.JSX).to.equal( `\n{'space after '}\n` @@ -120,7 +118,7 @@ describe('pluginis', () => { }); it('should keep spaces before & after simple text', () => { - var res = T().process({ block: 'button2', content: ' space before & after ' }); + const res = T().process({ block: 'button2', content: ' space before & after ' }); expect(res.JSX).to.equal( `\n{' space before & after '}\n` @@ -128,7 +126,7 @@ describe('pluginis', () => { }); it('should keep spaces in only spaces simple text', () => { - var res = T().process({ block: 'button2', content: [' ', ' ', ' ']}); + const res = T().process({ block: 'button2', content: [' ', ' ', ' ']}); expect(res.JSX).to.equal( `\n{' '}\n{' '}\n{' '}\n` diff --git a/packages/bundle/lib/index.js b/packages/bundle/lib/index.js index 2e7981af..f4bf0328 100644 --- a/packages/bundle/lib/index.js +++ b/packages/bundle/lib/index.js @@ -1,11 +1,9 @@ -'use strict'; +import assert from 'node:assert'; +import path from 'node:path'; -const assert = require('assert'); -const path = require('path'); +import bemjsonToDecl from '@bem/sdk.bemjson-to-decl'; -const bemjsonToDecl = require('@bem/sdk.bemjson-to-decl'); - -module.exports = class BemBundle { +export default class BemBundle { /** * @constructor * @param {Object} opts - Params diff --git a/packages/bundle/package.json b/packages/bundle/package.json index 39bab53c..fc13b18d 100644 --- a/packages/bundle/package.json +++ b/packages/bundle/package.json @@ -2,19 +2,19 @@ "name": "@bem/sdk.bundle", "version": "0.2.15", "description": "bem-bundle", + "type": "module", "publishConfig": { "access": "public" }, "main": "lib/index.js", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "files": [ "lib/**" ], "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" }, "repository": "bem/bem-sdk", diff --git a/packages/bundle/test/calculated-fields.test.js b/packages/bundle/test/calculated-fields.test.js index c57bcc28..ee349bcc 100644 --- a/packages/bundle/test/calculated-fields.test.js +++ b/packages/bundle/test/calculated-fields.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const BemBundle = require('..'); -const bemjsonToDecl = require('@bem/sdk.bemjson-to-decl'); +import { assert } from 'chai'; +import BemBundle from '../lib/index.js'; +import bemjsonToDecl from '@bem/sdk.bemjson-to-decl'; describe('bemjson given:', function () { it('should generate bemdecl by given bemjson', function () { diff --git a/packages/bundle/test/exceptions.test.js b/packages/bundle/test/exceptions.test.js index cebc5675..f4f61587 100644 --- a/packages/bundle/test/exceptions.test.js +++ b/packages/bundle/test/exceptions.test.js @@ -1,18 +1,16 @@ -'use strict'; - -const assert = require('chai').assert; -const BemBundle = require('..'); +import { assert } from 'chai'; +import BemBundle from '../lib/index.js'; describe('throw exception', function () { it('should throw if no bemjson and bemdecl given', function () { assert.throws(function () { - new BemBundle({}); // eslint-disable-line no-new + new BemBundle({}); }, Error, 'BEMJSON or BEMDECL must be present'); }); it('should throw if bemjson not an object', function () { assert.throws(function () { - new BemBundle({ // eslint-disable-line no-new + new BemBundle({ bemjson: 'bemjson' }); }, Error, 'BEMJSON should be an object'); @@ -20,7 +18,7 @@ describe('throw exception', function () { it('should throw if levels given but not an array', function () { assert.throws(function () { - new BemBundle({ // eslint-disable-line no-new + new BemBundle({ bemjson: { block: 'block' }, @@ -31,7 +29,7 @@ describe('throw exception', function () { it('should throw if no path and name given', function () { assert.throws(function () { - new BemBundle({ // eslint-disable-line no-new + new BemBundle({ bemjson: { block: 'block' } diff --git a/packages/bundle/test/field-types.test.js b/packages/bundle/test/field-types.test.js index 4b68cdf1..72bc4190 100644 --- a/packages/bundle/test/field-types.test.js +++ b/packages/bundle/test/field-types.test.js @@ -1,7 +1,5 @@ -'use strict'; - -const assert = require('chai').assert; -const BemBundle = require('..'); +import { assert } from 'chai'; +import BemBundle from '../lib/index.js'; describe('Result object fields', function () { var bundle; diff --git a/packages/bundle/test/is-bundle.test.js b/packages/bundle/test/is-bundle.test.js index 88a66066..0835e4d9 100644 --- a/packages/bundle/test/is-bundle.test.js +++ b/packages/bundle/test/is-bundle.test.js @@ -1,7 +1,5 @@ -'use strict'; - -const assert = require('chai').assert; -const BemBundle = require('..'); +import { assert } from 'chai'; +import BemBundle from '../lib/index.js'; describe('isBundle', function () { diff --git a/packages/cell/index.js b/packages/cell/index.js index 7ba372cb..ee8f42ef 100644 --- a/packages/cell/index.js +++ b/packages/cell/index.js @@ -1,11 +1,12 @@ -'use strict'; +import assert from 'node:assert'; +import util from 'node:util'; -const assert = require('assert'); -const util = require('util'); +import BemEntityName from '@bem/sdk.entity-name'; -const deprecate = require('depd')(require('./package.json').name); - -const BemEntityName = require('@bem/sdk.entity-name'); +const _warned = new Set(); +function deprecate(msg) { + if (!_warned.has(msg)) { _warned.add(msg); process.emitWarning(msg, 'DeprecationWarning'); } +} /** * Bem mod representation @@ -20,7 +21,7 @@ const BemEntityName = require('@bem/sdk.entity-name'); * * @type {module.BemCell} */ -module.exports = class BemCell { +export default class BemCell { /** * @param {Object} obj — representation of cell. * @param {BemEntityName} obj.entity — representation of entity name. @@ -174,7 +175,7 @@ module.exports = class BemCell { * * @example * const BemCell = require('@bem/sdk.cell'); - * const BemEntityName§ = require('@bem/sdk.entity-name'); + * const BemEntityName = require('@bem/sdk.entity-name'); * const cell = new BemCell({ entity: new BemEntityName({ block: 'button', mod: 'focused' }), * tech: 'css', layer: 'desktop' }); * @@ -241,6 +242,10 @@ module.exports = class BemCell { return `BemCell ${stringRepresentation}`; } + [Symbol.for('nodejs.util.inspect.custom')](depth, options) { + return this.inspect(depth, options); + } + /** * Return raw data for `JSON.stringify()`. * @@ -331,4 +336,4 @@ module.exports = class BemCell { return new BemCell(data); } -}; +} diff --git a/packages/cell/package.json b/packages/cell/package.json index d8bb2169..7a99a8b5 100644 --- a/packages/cell/package.json +++ b/packages/cell/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.cell", "version": "0.2.9", "description": "Representation of identifier of a part of BEM entity.", + "type": "module", "publishConfig": { "access": "public" }, @@ -28,15 +29,13 @@ "index.js" ], "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "dependencies": { - "@bem/sdk.entity-name": "^0.2.11", - "depd": "1.1.0" + "@bem/sdk.entity-name": "^0.2.11" }, "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" } } diff --git a/packages/cell/test/create.test.js b/packages/cell/test/create.test.js index 682ecd2b..f2c08776 100644 --- a/packages/cell/test/create.test.js +++ b/packages/cell/test/create.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('create', () => { it('should return instance as is if it`s a BemCell', () => { diff --git a/packages/cell/test/fields.test.js b/packages/cell/test/fields.test.js index 60137d3e..90dcdc27 100644 --- a/packages/cell/test/fields.test.js +++ b/packages/cell/test/fields.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('fields', () => { it('should provide `entity` field', () => { diff --git a/packages/cell/test/id.test.js b/packages/cell/test/id.test.js index 815df535..f932b46a 100644 --- a/packages/cell/test/id.test.js +++ b/packages/cell/test/id.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('id', () => { it('should provide `id` field', () => { diff --git a/packages/cell/test/inspect.test.js b/packages/cell/test/inspect.test.js index 128cf80b..32accc15 100644 --- a/packages/cell/test/inspect.test.js +++ b/packages/cell/test/inspect.test.js @@ -1,13 +1,9 @@ -'use strict'; +import util from 'node:util'; -const util = require('util'); +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('../index'); +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '../index.js'; describe('inspect', () => { it('should return entity object', () => { diff --git a/packages/cell/test/is-bem-cell.test.js b/packages/cell/test/is-bem-cell.test.js index 67d3da95..ae1d7868 100644 --- a/packages/cell/test/is-bem-cell.test.js +++ b/packages/cell/test/is-bem-cell.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('is-bem-cell', () => { it('should check valid entities', () => { diff --git a/packages/cell/test/is-equal.test.js b/packages/cell/test/is-equal.test.js index a3ba52ee..1bddbd7b 100644 --- a/packages/cell/test/is-equal.test.js +++ b/packages/cell/test/is-equal.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('is-equal', () => { it('should detect equal cell', () => { diff --git a/packages/cell/test/legacy.test.js b/packages/cell/test/legacy.test.js index 1fe335ba..f8f4434e 100644 --- a/packages/cell/test/legacy.test.js +++ b/packages/cell/test/legacy.test.js @@ -1,15 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const beforeEach = require('mocha').beforeEach; -const afterEach = require('mocha').afterEach; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; const cell = new BemCell({ entity: new BemEntityName({ block: 'b', elem: 'e', mod: { name: 'm', val: 'v' } }) }); const modLessCell = new BemCell({ entity: new BemEntityName({ block: 'b' }) }); diff --git a/packages/cell/test/to-json.test.js b/packages/cell/test/to-json.test.js index 31143a91..7ded7d23 100644 --- a/packages/cell/test/to-json.test.js +++ b/packages/cell/test/to-json.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('to-json', () => { it('should return stringified cell', () => { diff --git a/packages/cell/test/to-string.test.js b/packages/cell/test/to-string.test.js index 30dcafe8..c467e5d2 100644 --- a/packages/cell/test/to-string.test.js +++ b/packages/cell/test/to-string.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('to-string', () => { it('should return string', () => { diff --git a/packages/cell/test/valid.test.js b/packages/cell/test/valid.test.js index 55a9ce4a..193a2bfb 100644 --- a/packages/cell/test/valid.test.js +++ b/packages/cell/test/valid.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('valid', () => { it('should throw error if not provide arguments', () => { diff --git a/packages/cell/test/value-of.test.js b/packages/cell/test/value-of.test.js index 03592560..75ba99a0 100644 --- a/packages/cell/test/value-of.test.js +++ b/packages/cell/test/value-of.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; - -const BemEntityName = require('@bem/sdk.entity-name'); - -const BemCell = require('../index'); +import BemCell from '../index.js'; describe('value-of', () => { it('should return cell with entity', () => { diff --git a/packages/config/index.js b/packages/config/index.js index ab1781ba..3180a9c9 100644 --- a/packages/config/index.js +++ b/packages/config/index.js @@ -1,17 +1,66 @@ -'use strict'; +import fs from 'node:fs'; +import assert from 'node:assert'; +import path from 'node:path'; +import { cosmiconfigSync } from 'cosmiconfig'; +import merge from './lib/merge.js'; +import resolveSets from './lib/resolve-sets.js'; +import resolveLevel from './plugins/resolve-level.js'; -var fs = require('fs'), - assert = require('assert'), - path = require('path'), - rc = require('betterc'), - Promise = require('pinkie-promise'), - flatten = require('lodash.flatten'), - merge = require('./lib/merge'), - resolveSets = require('./lib/resolve-sets'), +const basePlugins = [resolveLevel]; - basePlugins = [require('./plugins/resolve-level')], +const specialKeys = new Set(['sets', 'levels', 'libs', 'modules', '__source']); - specialKeys = new Set(['sets', 'levels', 'libs', 'modules', '__source']); +/** + * Loads configs as an array, mimicking betterc behavior: + * - defaults come first + * - found RC config(s) in the middle + * - extendBy at the end + * + * @param {Object} rcOpts + * @returns {Array} + */ +function loadConfigs(rcOpts) { + const configs = []; + + if (rcOpts.defaults) { + configs.push(JSON.parse(JSON.stringify(rcOpts.defaults))); + } + + if (rcOpts.argv && rcOpts.argv.config) { + // Load specific config file + const configPath = path.resolve(rcOpts.argv.config); + const content = JSON.parse(fs.readFileSync(configPath, 'utf8')); + content.__source = configPath; + configs.push(content); + } else { + const explorer = cosmiconfigSync(rcOpts.name || 'bem', { + searchPlaces: [ + `.${rcOpts.name || 'bem'}rc`, + `.${rcOpts.name || 'bem'}rc.json`, + `.${rcOpts.name || 'bem'}rc.js`, + ], + stopDir: rcOpts.fsRoot + }); + const result = explorer.search(rcOpts.cwd); + if (result && result.config) { + const config = result.config; + config.__source = result.filepath; + configs.push(config); + } + } + + if (rcOpts.extendBy) { + configs.push(typeof rcOpts.extendBy === 'string' + ? JSON.parse(rcOpts.extendBy) + : JSON.parse(JSON.stringify(rcOpts.extendBy))); + } + + if (configs.length === 0) { + configs.push({}); + } + + return configs; +} /** * Constructor @@ -37,25 +86,25 @@ function BemConfig(options) { * @returns {Promise|Array} */ BemConfig.prototype.configs = function(isSync) { - var options = this._options, - cwd = options.cwd, - rcOpts = { - defaults: options.defaults && JSON.parse(JSON.stringify(options.defaults)), - cwd: cwd, - fsRoot: options.fsRoot, - fsHome: options.fsHome, - name: options.name || 'bem', - extendBy: options.extendBy - }; + const options = this._options; + const cwd = options.cwd; + const rcOpts = { + defaults: options.defaults, + cwd: cwd, + fsRoot: options.fsRoot, + fsHome: options.fsHome, + name: options.name || 'bem', + extendBy: options.extendBy + }; if (options.pathToConfig) { rcOpts.argv = { config: options.pathToConfig }; } - var plugins = [].concat(basePlugins, options.plugins || []); + const plugins = [].concat(basePlugins, options.plugins || []); if (isSync) { - var configs = doSomeMagicProcedure(this._configs || (this._configs = rc.sync(rcOpts)), cwd); + const configs = doSomeMagicProcedure(this._configs || (this._configs = loadConfigs(rcOpts)), cwd); this._root = getConfigsRootDir(configs); @@ -66,8 +115,9 @@ BemConfig.prototype.configs = function(isSync) { }, configs); } - var _this = this, - _thisConfigs = this._configs || rc(rcOpts).then(function(cfgs) { _this._configs = cfgs; return cfgs; }); + // Async path: loadConfigs is actually sync (cosmiconfig), but we wrap in Promise for API compat + const _this = this; + const _thisConfigs = this._configs || (this._configs = loadConfigs(rcOpts)); return Promise.resolve(_thisConfigs).then(function(cfgs) { doSomeMagicProcedure(cfgs, cwd); @@ -114,7 +164,7 @@ BemConfig.prototype.get = async function() { * @returns {Promise} */ BemConfig.prototype.level = function(pathToLevel) { - var _this = this; + const _this = this; return this.configs() .then(function(configs) { @@ -134,24 +184,18 @@ BemConfig.prototype.level = function(pathToLevel) { BemConfig.prototype.library = function(libName) { return this.get() .then(function(config) { - var libs = config.libs, - lib = libs && libs[libName]; + const libs = config.libs; + const lib = libs && libs[libName]; if (lib !== undefined && typeof lib !== 'object') { return Promise.reject('Invalid `libs` format'); } - var cwd = lib && lib.path || path.resolve('node_modules', libName); + const cwd = lib && lib.path || path.resolve('node_modules', libName); - return new Promise(function(resolve, reject) { - fs.exists(cwd, function(doesExist) { - if (!doesExist) { - return reject('Library ' + libName + ' was not found at ' + cwd); - } - - resolve(cwd); - }) - }); + return fs.promises.access(cwd, fs.constants.F_OK) + .then(() => cwd) + .catch(() => { throw 'Library ' + libName + ' was not found at ' + cwd; }); }) .then(cwd => new BemConfig({ cwd: path.resolve(cwd) })); }; @@ -161,18 +205,18 @@ BemConfig.prototype.library = function(libName) { * @returns {Promise} */ BemConfig.prototype.levelMap = function() { - var _this = this; + const _this = this; return this.get().then(function(config) { - var projectLevels = config.levels || [], - libNames = config.libs ? Object.keys(config.libs) : [], - commonOpts = Object.keys(config) - .filter(key => !specialKeys.has(key)) - .reduce((acc, key) => { - acc[key] = config[key]; - - return acc; - }, {}); + const projectLevels = config.levels || []; + const libNames = config.libs ? Object.keys(config.libs) : []; + const commonOpts = Object.keys(config) + .filter(key => !specialKeys.has(key)) + .reduce((acc, key) => { + acc[key] = config[key]; + + return acc; + }, {}); return Promise.all(libNames.map(function(libName) { return _this.library(libName).then(function(bemLibConf) { @@ -181,7 +225,7 @@ BemConfig.prototype.levelMap = function() { }); }); })).then(function(libLevels) { - var allLevels = [].concat.apply([], libLevels.filter(Boolean)).concat(projectLevels); + const allLevels = [].concat.apply([], libLevels.filter(Boolean)).concat(projectLevels); return allLevels.reduce((res, lvl) => { res[lvl.path] = merge({}, commonOpts, res[lvl.path] || {}, lvl); @@ -192,16 +236,16 @@ BemConfig.prototype.levelMap = function() { }; BemConfig.prototype.levels = function(setName) { - var _this = this; + const _this = this; return this.get().then(function(config) { - var levels = config.levels || [], - sets = config.sets || {}; + const levels = config.levels || []; + const sets = config.sets || {}; if (!sets[setName]) { return []; } - var resolvedSets = resolveSets(sets), - set = resolvedSets[setName]; + const resolvedSets = resolveSets(sets); + const set = resolvedSets[setName]; if (!set || !set.length) { return []; } @@ -230,14 +274,14 @@ BemConfig.prototype.levels = function(setName) { return levels.reduce((acc, lvl) => { if (lvl.layer !== chunk.layer) { return acc; } - var levelPath = lvl.path || calculateDefaultLevelPath(lvl); + const levelPath = lvl.path || calculateDefaultLevelPath(lvl); levelsMap[levelPath] && acc.push(levelsMap[levelPath]); return acc; }, []); })); - }).then(flatten); + }).then(arr => arr.flat()); }); }; @@ -248,7 +292,7 @@ BemConfig.prototype.levels = function(setName) { */ BemConfig.prototype.module = function(moduleName) { return this.get().then(function(config) { - var modules = config.modules; + const modules = config.modules; return modules && modules[moduleName]; }); @@ -273,7 +317,7 @@ BemConfig.prototype.rootSync = function() { */ BemConfig.prototype.getSync = function() { return merge(this.configs(true)); -} +}; /** * Resolves config for given level synchronously @@ -295,13 +339,13 @@ BemConfig.prototype.levelSync = function(pathToLevel) { * @returns {Object} */ BemConfig.prototype.librarySync = function(libName) { - var config = this.getSync(), - libs = config.libs, - lib = libs && libs[libName]; + const config = this.getSync(); + const libs = config.libs; + const lib = libs && libs[libName]; assert(lib === undefined || typeof lib === 'object', 'Invalid `libs` format'); - var cwd = lib && lib.path || path.resolve('node_modules', libName); + const cwd = lib && lib.path || path.resolve('node_modules', libName); assert(fs.existsSync(cwd), 'Library ' + libName + ' was not found at ' + cwd); @@ -313,13 +357,13 @@ BemConfig.prototype.librarySync = function(libName) { * @returns {Object} */ BemConfig.prototype.levelMapSync = function() { - var config = this.getSync(), - projectLevels = config.levels || [], - libNames = config.libs ? Object.keys(config.libs) : []; + const config = this.getSync(); + const projectLevels = config.levels || []; + const libNames = config.libs ? Object.keys(config.libs) : []; - var libLevels = [].concat.apply([], libNames.map(function(libName) { - var bemLibConf = this.librarySync(libName), - libConfig = bemLibConf.getSync(); + const libLevels = [].concat.apply([], libNames.map(function(libName) { + const bemLibConf = this.librarySync(libName); + const libConfig = bemLibConf.getSync(); return libConfig.levels; }, this)).filter(Boolean); @@ -332,7 +376,7 @@ BemConfig.prototype.levelMapSync = function() { return acc; }, {}); - var allLevels = [].concat(libLevels, projectLevels); // hm. + const allLevels = [].concat(libLevels, projectLevels); // hm. return allLevels.reduce(function(acc, level) { acc[level.path] = Object.assign({}, commonOpts, level); return acc; @@ -340,21 +384,21 @@ BemConfig.prototype.levelMapSync = function() { }; BemConfig.prototype.levelsSync = function(setName) { - var _this = this, - config = this.getSync(), - levels = config.levels || [], - levelsMap = this.levelMapSync(), - sets = config.sets || {}; + const _this = this; + const config = this.getSync(); + const levels = config.levels || []; + const levelsMap = this.levelMapSync(); + const sets = config.sets || {}; if (!sets[setName]) { return []; } - var resolvedSets = resolveSets(sets), - set = resolvedSets[setName]; + const resolvedSets = resolveSets(sets); + const set = resolvedSets[setName]; // TODO: uniq return set.reduce((acc, chunk) => { if (chunk.library) { - var libConfig = _this.librarySync(chunk.library); + const libConfig = _this.librarySync(chunk.library); assert(libConfig, 'Library `' + chunk.library + '` was not found'); @@ -373,7 +417,7 @@ BemConfig.prototype.levelsSync = function(setName) { levels.forEach(lvl => { if (lvl.layer !== chunk.layer) { return; } - var levelPath = lvl.path || calculateDefaultLevelPath(lvl); + const levelPath = lvl.path || calculateDefaultLevelPath(lvl); levelsMap[levelPath] && acc.push(levelsMap[levelPath]); }); @@ -388,29 +432,29 @@ BemConfig.prototype.levelsSync = function(setName) { * @returns {Object} */ BemConfig.prototype.moduleSync = function(moduleName) { - var modules = this.getSync().modules; + const modules = this.getSync().modules; return modules && modules[moduleName]; }; function getConfigsRootDir(configs) { - var rootCfg = [].concat(configs).reverse().find(function(cfg) { return cfg.root && cfg.__source; }); + const rootCfg = [].concat(configs).reverse().find(function(cfg) { return cfg.root && cfg.__source; }); if (rootCfg) { return path.dirname(rootCfg.__source); } } function getLevelByConfigs(pathToLevel, options, allConfigs, root) { - var absLevelPath = path.resolve(root || options.cwd, pathToLevel), - levelOpts = {}, - commonOpts = {}; + const absLevelPath = path.resolve(root || options.cwd, pathToLevel); + let levelOpts = {}; + let commonOpts = {}; - for (var i = allConfigs.length - 1; i >= 0; i--) { - var conf = allConfigs[i], - levels = conf.levels || []; + for (let i = allConfigs.length - 1; i >= 0; i--) { + const conf = allConfigs[i]; + const levels = conf.levels || []; commonOpts = merge({}, conf, commonOpts); - for (var j = 0; j < levels.length; j++) { - var level = levels[j]; + for (let j = 0; j < levels.length; j++) { + const level = levels[j]; if (level === undefined || level.path !== absLevelPath) { continue; } @@ -450,7 +494,7 @@ function doSomeMagicProcedure(configs, cwd) { config.levels = Object.keys(levels).map(levelPath => Object.assign({ path: levelPath }, levels[levelPath])); } else { - var levelPrefix = ''; + let levelPrefix = ''; if (config.__source && path.dirname(config.__source) !== cwd) { levelPrefix = path.relative(path.dirname(config.__source), cwd); } @@ -468,6 +512,6 @@ function calculateDefaultLevelPath(lvl) { return `${lvl.layer}.blocks`; } -module.exports = function(opts) { +export default function(opts) { return new BemConfig(opts); -}; +} diff --git a/packages/config/lib/merge.js b/packages/config/lib/merge.js index 6fed789f..2dbe5308 100644 --- a/packages/config/lib/merge.js +++ b/packages/config/lib/merge.js @@ -1,17 +1,38 @@ -'use strict'; - -var mergeWith = require('lodash.mergewith'); - /** - * Merge all arguments to firt one. - * Consider arrays as simple value and not deep merge them. + * Deep merge helper. + * Merges objects recursively but treats arrays as atomic values (replaces, not concatenates). + * Mutates and returns the first object (like lodash.mergeWith). + * * @param {Array|Object} configs - array of configs or positional arguments * @return {Object} */ -module.exports = function merge(configs) { - var args = Array.isArray(configs) ? configs : Array.from(arguments); - args.push(function(objValue, srcValue) { - if (Array.isArray(objValue)) { return srcValue; } + +function isPlainObject(val) { + return val !== null && typeof val === 'object' && !Array.isArray(val); +} + +function deepMergeTwo(target, source) { + for (const key of Object.keys(source)) { + const srcVal = source[key]; + if (srcVal === undefined) { continue; } + const tgtVal = target[key]; + if (Array.isArray(tgtVal)) { + // customizer: arrays are replaced, not deep-merged + target[key] = srcVal; + } else if (isPlainObject(tgtVal) && isPlainObject(srcVal)) { + deepMergeTwo(tgtVal, srcVal); + } else { + target[key] = srcVal; + } + } + return target; +} + +export default function merge(configs) { + const args = Array.isArray(configs) ? configs : Array.from(arguments); + if (args.length === 0) { return {}; } + return args.reduce((acc, obj) => { + if (obj == null) { return acc; } + return deepMergeTwo(acc, obj); }); - return mergeWith.apply(null, args); -}; +} diff --git a/packages/config/lib/resolve-sets.js b/packages/config/lib/resolve-sets.js index b1dfc823..146a796c 100644 --- a/packages/config/lib/resolve-sets.js +++ b/packages/config/lib/resolve-sets.js @@ -1,16 +1,11 @@ -'use strict'; - -const assert = require('assert'); - -const _ = { - uniqWith: require('lodash.uniqwith'), - isEqual: require('lodash.isequal') -}; +import assert from 'node:assert'; +import { isDeepStrictEqual } from 'node:util'; // TODO: cache -module.exports = function resolveSets(sets) { +export default function resolveSets(sets) { return Object.keys(sets).reduce((acc, setName) => { - acc[setName] = _.uniqWith(resolveSet(sets[setName], setName, sets), _.isEqual); + const arr = resolveSet(sets[setName], setName, sets); + acc[setName] = arr.filter((item, i) => arr.findIndex(o => isDeepStrictEqual(item, o)) === i); return acc; }, {}); } diff --git a/packages/config/package.json b/packages/config/package.json index f5542be7..63d78144 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -2,13 +2,13 @@ "name": "@bem/sdk.config", "version": "0.1.0", "description": "Config module for bem-tools", + "type": "module", "publishConfig": { "access": "public" }, "main": "index.js", "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" }, "keywords": [ @@ -24,21 +24,9 @@ }, "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/config#readme", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "dependencies": { - "betterc": "^1.3.0", - "glob": "^7.0.5", - "is-glob": "^3.1.0", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isequal": "^4.5.0", - "lodash.mergewith": "^4.6.0", - "lodash.uniqwith": "^4.5.0", - "pinkie-promise": "^2.0.1" - }, - "devDependencies": { - "@types/chai-as-promised": "0.0.31", - "chai-as-promised": "^7.0.0" + "cosmiconfig": "^9.0.0" } } diff --git a/packages/config/plugins/resolve-level.js b/packages/config/plugins/resolve-level.js index 97bbe410..873f0e4d 100644 --- a/packages/config/plugins/resolve-level.js +++ b/packages/config/plugins/resolve-level.js @@ -1,22 +1,20 @@ -'use strict'; - -var path = require('path'), - isGlob = require('is-glob'), - glob = require('glob'), - cloneDeep = require('lodash.clonedeep'), - merge = require('../lib/merge'); - -module.exports = function(config, configs, options, cb) { - var cwd = options.cwd || process.cwd(), - source = config.__source, - res = cloneDeep(config), - levels = res.levels || [], - levelsIndex = {}, - cyclesToResolve = levels.length; +import path from 'node:path'; +import { globSync } from 'node:fs'; +import merge from '../lib/merge.js'; + +const isGlob = s => /[*?{[\]]/.test(s.replace(/\\./g, '')); + +export default function resolveLevel(config, configs, options, cb) { + const cwd = options.cwd || process.cwd(); + const source = config.__source; + const res = structuredClone(config); + const levels = res.levels || []; + const levelsIndex = {}; + let cyclesToResolve = levels.length; if (!cyclesToResolve) { return cb ? cb(res) : res; } - var pathsToRemove = []; + const pathsToRemove = []; levels.forEach(function(level, i) { cyclesToResolve--; @@ -35,7 +33,7 @@ module.exports = function(config, configs, options, cb) { } if (!cb) { // sync - var globbedLevels = glob.sync(level.path, { cwd: cwd }); + const globbedLevels = globSync(level.path, { cwd: cwd }); globbedLevels.forEach(function(levelPath, idx) { onLevel(levelPath, level.path); globbedLevels.length - 1 === idx && pathsToRemove.push(level.path); @@ -44,20 +42,18 @@ module.exports = function(config, configs, options, cb) { return; } - // async - glob(level.path, { cwd: cwd }, function(err, asyncGlobbedLevels) { - // TODO: if (err) { throw err; } - asyncGlobbedLevels.forEach(function(levelPath, idx) { - onLevel(levelPath, level.path); - asyncGlobbedLevels.length - 1 === idx && pathsToRemove.push(level.path); - }); - - if (!cyclesToResolve) { - removeRelPaths(); - - cb(res); - } + // async — node:fs globSync is always sync, so use it here too + // (the original used async glob; we simplify to sync and call cb) + const asyncGlobbedLevels = globSync(level.path, { cwd: cwd }); + asyncGlobbedLevels.forEach(function(levelPath, idx) { + onLevel(levelPath, level.path); + asyncGlobbedLevels.length - 1 === idx && pathsToRemove.push(level.path); }); + + if (!cyclesToResolve) { + removeRelPaths(); + cb(res); + } }); cb || removeRelPaths(); @@ -67,7 +63,7 @@ module.exports = function(config, configs, options, cb) { function onLevel(levelPath, globLevelPath) { globLevelPath || (globLevelPath = levelPath); - var resolvedLevel = path.resolve(source ? path.dirname(source) : cwd, levelPath); + const resolvedLevel = path.resolve(source ? path.dirname(source) : cwd, levelPath); if (resolvedLevel === levelPath && levelPath === globLevelPath) { return; } @@ -85,4 +81,4 @@ module.exports = function(config, configs, options, cb) { levelsIndex[pathToRemove] = undefined; }); } -}; +} diff --git a/packages/config/test/async.test.js b/packages/config/test/async.test.js index c286ede0..6bd0923a 100644 --- a/packages/config/test/async.test.js +++ b/packages/config/test/async.test.js @@ -1,25 +1,27 @@ -'use strict'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; -const path = require('path'); +import { expect, use } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; -const describe = require('mocha').describe; -const it = require('mocha').it; +use(chaiAsPromised); -const chai = require('chai'); +import notStubbedBemConfig from '../index.js'; -chai.use(require('chai-as-promised')); - -const expect = chai.expect; - -const proxyquire = require('proxyquire'); -const notStubbedBemConfig = require('..'); +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +/** + * Creates a bemConfig factory with pre-set configs (bypassing cosmiconfig). + * @param {Array} conf - Array of config objects to inject + * @returns {Function} bemConfig factory + */ function config(conf) { - return proxyquire('..', { - 'betterc'() { - return Promise.resolve(conf || [{}]); - } - }); + return function(opts) { + const instance = notStubbedBemConfig(opts); + instance._configs = conf || [{}]; + return instance; + }; } describe('async', () => { @@ -276,7 +278,7 @@ describe('async', () => { const expected = {}; expected[path.resolve('l1')] = { path: path.resolve('l1'), some: 'conf1' }; - // because of mocked rc, all instances of bemConfig has always the same data + // because of injected configs, all instances of bemConfig has always the same data return expect(bemConfig().levelMap()).to.eventually.deep.equal( expected ); @@ -294,9 +296,7 @@ describe('async', () => { }); it('should throw if lib was not found', () => { - const bemConfig = config(); - - return bemConfig().library('lib1').catch(err => expect(err.includes('Library lib1 was not found at')).to.equal(true)); + return notStubbedBemConfig().library('lib1').catch(err => expect(err.includes('Library lib1 was not found at')).to.equal(true)); }); it('should throw if lib was not found', () => { @@ -330,8 +330,8 @@ describe('async', () => { return bemConfig().library('lib1') .then(lib => { return lib.get().then(libConf => { - // because of mocked rc, all instances of bemConfig has always the same data - return expect(libConf).to.deep.equal(conf[0]); + // library config is loaded from the library's own .bemrc.json + return expect(libConf).to.have.property('lib1Config', true); }); }); }); @@ -423,12 +423,6 @@ describe('async', () => { ); }); -// TODO: add test for -// resolving, e.g. projectRoot -// 'should override default config with .bemrc' -// 'should not override default levels if none in .bemrc provided' -// 'should not mutate defaults' - it('should return common config if no levels provided', () => { const bemConfig = config([ { common: 'value' } diff --git a/packages/config/test/mocks/node_modules/lib1/.bemrc.json b/packages/config/test/mocks/node_modules/lib1/.bemrc.json new file mode 100644 index 00000000..22b3c6aa --- /dev/null +++ b/packages/config/test/mocks/node_modules/lib1/.bemrc.json @@ -0,0 +1,3 @@ +{ + "lib1Config": true +} diff --git a/packages/config/test/resolve-sets.test.js b/packages/config/test/resolve-sets.test.js index 7f741d56..4ec07409 100644 --- a/packages/config/test/resolve-sets.test.js +++ b/packages/config/test/resolve-sets.test.js @@ -1,5 +1,5 @@ -const assert = require('assert'); -const resolveSets = require('../lib/resolve-sets'); +import assert from 'node:assert'; +import resolveSets from '../lib/resolve-sets.js'; describe('resolve-sets', function() { it('should support objects', function() { diff --git a/packages/config/test/sync.test.js b/packages/config/test/sync.test.js index 784c08df..cdbdbc3a 100644 --- a/packages/config/test/sync.test.js +++ b/packages/config/test/sync.test.js @@ -1,42 +1,40 @@ -'use strict'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; -const path = require('path'); +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import notStubbedBemConfig from '../index.js'; -const expect = require('chai').expect; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -const proxyquire = require('proxyquire'); -const notStubbedBemConfig = require('..'); - -// stub for bem-config +/** + * Creates a bemConfig factory with pre-set configs (bypassing cosmiconfig). + */ function config(conf) { - return proxyquire('..', { - 'betterc': { - sync: function() { - return conf || [{}]; - } - } - }); + return function(opts) { + const instance = notStubbedBemConfig(opts); + instance._configs = conf || [{}]; + return instance; + }; } describe('sync', () => { // configs() - it('should return empty config', () => { - const bemConfig = config(); + it('should return empty config', async () => { + const bemConfig = await config(); expect(bemConfig().configs(true)).to.deep.equal([{}]); }); - it('should return empty config if empty map passed', () => { - const bemConfig = config([{}]); + it('should return empty config if empty map passed', async () => { + const bemConfig = await config([{}]); expect(bemConfig().configs(true)).to.deep.equal([{}]); }); - it('should return configs', () => { - const bemConfig = config([ + it('should return configs', async () => { + const bemConfig = await config([ { test: 1 }, { test: 2 } ]); @@ -45,8 +43,8 @@ describe('sync', () => { }); // root() - it('should return project root', () => { - const bemConfig = config([ + it('should return project root', async () => { + const bemConfig = await config([ { test: 1, __source: 'some/path' }, { test: 2, root: true, __source: __filename }, { other: 'field', __source: 'some/other/path' } @@ -55,8 +53,8 @@ describe('sync', () => { expect(bemConfig().rootSync()).to.deep.equal(path.dirname(__filename)); }); - it('should respect proper project root', () => { - const bemConfig = config([ + it('should respect proper project root', async () => { + const bemConfig = await config([ { test: 1, root: true, __source: 'some/path' }, { test: 2, root: true, __source: __filename }, { other: 'field', __source: 'some/other/path' } @@ -66,8 +64,8 @@ describe('sync', () => { }); // get() - it('should return merged config', () => { - const bemConfig = config([ + it('should return merged config', async () => { + const bemConfig = await config([ { test: 1 }, { test: 2 }, { other: 'field' } @@ -77,14 +75,14 @@ describe('sync', () => { }); // level() - it('should return undefined if no levels in config', () => { - const bemConfig = config(); + it('should return undefined if no levels in config', async () => { + const bemConfig = await config(); expect(bemConfig().levelSync('l1')).to.equal(undefined); }); - it('should return undefined if no level found', () => { - const bemConfig = config([{ + it('should return undefined if no level found', async () => { + const bemConfig = await config([{ levels: [ { path: 'l1', some: 'conf' } ] @@ -93,8 +91,8 @@ describe('sync', () => { expect(bemConfig().levelSync('l2')).to.equal(undefined); }); - it('should return level', () => { - const bemConfig = config([{ + it('should return level', async () => { + const bemConfig = await config([{ levels: [ { path: 'path/to/level', test: 1 } ], @@ -104,8 +102,8 @@ describe('sync', () => { expect(bemConfig().levelSync('path/to/level')).to.deep.equal({ test: 1, something: 'else' }); }); - it('should resolve wildcard levels', () => { - const bemConfig = config([{ + it('should resolve wildcard levels', async () => { + const bemConfig = await config([{ levels: [ { path: 'l*', test: 1 } ], @@ -117,21 +115,21 @@ describe('sync', () => { ); }); - it('should resolve wildcard levels with absolute path', () => { + it('should resolve wildcard levels with absolute path', async () => { const conf = { levels: [], something: 'else' }; conf.levels.push({ path: path.join(__dirname, 'mocks', 'l*'), test: 1 }); - const bemConfig = config([conf]); + const bemConfig = await config([conf]); expect(bemConfig({ cwd: path.resolve(__dirname, 'mocks') }).levelSync('level1')).to.deep.equal( { test: 1, something: 'else' } ); }); - it('should merge levels from different configs', () => { - const bemConfig = config([{ + it('should merge levels from different configs', async () => { + const bemConfig = await config([{ levels: [ { path: 'level1', 'l1o1': 'l1v1' } ], @@ -153,8 +151,8 @@ describe('sync', () => { ); }); - it('should override arrays in merged levels from different configs', () => { - const bemConfig = config([{ + it('should override arrays in merged levels from different configs', async () => { + const bemConfig = await config([{ levels: [ { path: 'level1', @@ -206,16 +204,16 @@ describe('sync', () => { }); // levelMap() - it('should return empty map on levelMap if no levels found', () => { - const bemConfig = config(); + it('should return empty map on levelMap if no levels found', async () => { + const bemConfig = await config(); expect(bemConfig().levelMapSync()).to.deep.equal( {} ); }); - it('should return levels map for project without libs', () => { - const bemConfig = config([{ + it('should return levels map for project without libs', async () => { + const bemConfig = await config([{ levels: [ { path: 'l1', some: 'conf1' } ], @@ -230,8 +228,8 @@ describe('sync', () => { expect(actual).to.deep.equal(expected); }); - it('should return proper levels map for layer without path and custom cwd', () => { - const bemConfig = config([{ + it('should return proper levels map for layer without path and custom cwd', async () => { + const bemConfig = await config([{ levels: [ { layer: 'common', some: 'conf1' } ], @@ -250,8 +248,8 @@ describe('sync', () => { expect(actual).to.deep.equal(expected); }); - it('should return proper levels map for layer without path and custom cwd', () => { - const bemConfig = config([{ + it('should return proper levels map for layer without path and custom cwd', async () => { + const bemConfig = await config([{ levels: [ { layer: 'common', some: 'conf1' } ], @@ -270,9 +268,9 @@ describe('sync', () => { expect(actual).to.deep.equal(expected); }); - it('should return levels map for project and included libs', () => { + it('should return levels map for project and included libs', async () => { const pathToLib1 = path.resolve(__dirname, 'mocks', 'node_modules', 'lib1'); - const bemConfig = config([{ + const bemConfig = await config([{ levels: [ { path: 'l1', some: 'conf1' } ], @@ -294,11 +292,11 @@ describe('sync', () => { expect(actual).to.deep.equal(expected); }); - it('should return globbed levels map', () => { + it('should return globbed levels map', async () => { const mockDir = path.resolve(__dirname, 'mocks'); const levelPath = path.join(mockDir, 'l*'); const levels = [{path: levelPath, some: 'conf1'}]; - const bemConfig = config([{ + const bemConfig = await config([{ levels, __source: mockDir }]); @@ -313,8 +311,8 @@ describe('sync', () => { }); // library() - it('should throw if lib format is incorrect', () => { - const bemConfig = config([{ + it('should throw if lib format is incorrect', async () => { + const bemConfig = await config([{ libs: { lib1: '' } @@ -323,14 +321,14 @@ describe('sync', () => { expect(() => bemConfig().librarySync('lib1')).to.throw(/Invalid `libs` format/); }); - it('should throw if lib was not found', () => { - const bemConfig = config(); + it('should throw if lib was not found', async () => { + const bemConfig = await config(); expect(() => bemConfig().librarySync('lib1')).to.throw(/Library lib1 was not found at /); }); - it('should throw if lib was not found', () => { - const bemConfig = config([{ + it('should throw if lib was not found', async () => { + const bemConfig = await config([{ libs: { lib1: { conf: 'of lib1', @@ -343,7 +341,7 @@ describe('sync', () => { expect(() => bemConfig().librarySync('lib2')).to.throw(/Library lib2 was not found at /); }); - it('should return library config', () => { + it('should return library config', async () => { const conf = [{ libs: { lib1: { @@ -353,23 +351,23 @@ describe('sync', () => { } }]; - const bemConfig = config(conf); + const bemConfig = await config(conf); const libConf = bemConfig().librarySync('lib1').getSync(); - // because of mocked rc, all instances of bemConfig has always the same data - expect(libConf).to.deep.equal(conf[0]); + // library config is loaded from the library's own .bemrc.json + expect(libConf).to.have.property('lib1Config', true); }); // module() - it('should return undefined if no modules in config', () => { - const bemConfig = config(); + it('should return undefined if no modules in config', async () => { + const bemConfig = await config(); expect(bemConfig().moduleSync('m1')).to.equal(undefined); }); - it('should return undefined if no module found', () => { - const bemConfig = config([{ + it('should return undefined if no module found', async () => { + const bemConfig = await config([{ modules: { m1: { conf: 'of m1' @@ -380,8 +378,8 @@ describe('sync', () => { expect(bemConfig().moduleSync('m2')).to.equal(undefined); }); - it('should return module', () => { - const bemConfig = config([{ + it('should return module', async () => { + const bemConfig = await config([{ modules: { m1: { conf: 'of m1' @@ -395,8 +393,8 @@ describe('sync', () => { expect(bemConfig().moduleSync('m1')).to.deep.equal({ conf: 'of m1' }); }); - it('should not extend with configs higher then root', () => { - const bemConfig = config([{ + it('should not extend with configs higher then root', async () => { + const bemConfig = await config([{ levels: [ { path: 'level1', l1o1: 'should not be used', l1o2: 'should not be used either' } ] @@ -495,8 +493,8 @@ describe('sync', () => { }); // levels - it('should return levels set', () => { - const bemConfig = config([{ + it('should return levels set', async () => { + const bemConfig = await config([{ levels: [ { layer: 'common', data: '1' }, { layer: 'desktop', data: '2' }, @@ -540,8 +538,8 @@ describe('sync', () => { expect(actual).to.deep.equal(expected); }); - it('should return levels set with custom paths', () => { - const bemConfig = config([{ + it('should return levels set with custom paths', async () => { + const bemConfig = await config([{ levels: [ { layer: 'common', path: 'node_modules/lib/common.blocks' }, { layer: 'common', path: 'common.blocks' }, diff --git a/packages/decl/benchmark/intersect.bench.js b/packages/decl/benchmark/intersect.bench.js index 6af29c99..06f22043 100644 --- a/packages/decl/benchmark/intersect.bench.js +++ b/packages/decl/benchmark/intersect.bench.js @@ -1,14 +1,21 @@ -'use strict'; +import { performance } from 'node:perf_hooks'; -const intersect = require('../lib/index').intersect; +import { intersect } from '../lib/index.js'; -suite('subtract', () => { - set('intersect', 200000); +function bench(name, fn, iterations = 200000) { + const start = performance.now(); + for (let i = 0; i < iterations; i++) { + fn(); + } + const elapsed = performance.now() - start; + console.log(` ${name}: ${iterations} iterations in ${elapsed.toFixed(2)}ms (${(iterations / elapsed * 1000).toFixed(0)} ops/sec)`); +} - bench('blocks', () => { - const decl1 = [{ block: 'block-1' }, { block: 'block-2' }, { block: 'block-3' }]; - const decl2 = [{ block: 'block-2' }]; +console.log('subtract (intersect):'); - intersect(decl1, decl2); - }); +bench('blocks', () => { + const decl1 = [{ block: 'block-1' }, { block: 'block-2' }, { block: 'block-3' }]; + const decl2 = [{ block: 'block-2' }]; + + intersect(decl1, decl2); }); diff --git a/packages/decl/benchmark/merge.bench.js b/packages/decl/benchmark/merge.bench.js index 27f6efbc..604c326c 100644 --- a/packages/decl/benchmark/merge.bench.js +++ b/packages/decl/benchmark/merge.bench.js @@ -1,6 +1,7 @@ -'use strict'; +import { performance } from 'node:perf_hooks'; + +import { merge } from '../lib/index.js'; -const merge = require('../lib/index').merge; const decls = { blocks: [ [{ block: 'block-1' }], @@ -24,26 +25,33 @@ const decls = { decls.full = [].concat(decls.blocks, decls.blockMods, decls.elems, decls.elemMods); -suite('merge', () => { - set('interations', 200000); +function bench(name, fn, iterations = 200000) { + const start = performance.now(); + for (let i = 0; i < iterations; i++) { + fn(); + } + const elapsed = performance.now() - start; + console.log(` ${name}: ${iterations} iterations in ${elapsed.toFixed(2)}ms (${(iterations / elapsed * 1000).toFixed(0)} ops/sec)`); +} + +console.log('merge:'); - bench('blocks', () => { - merge.apply(null, decls.blocks); - }); +bench('blocks', () => { + merge.apply(null, decls.blocks); +}); - bench('block mods', () => { - merge.apply(null, decls.blockMods); - }); +bench('block mods', () => { + merge.apply(null, decls.blockMods); +}); - bench('elems', () => { - merge.apply(null, decls.elems); - }); +bench('elems', () => { + merge.apply(null, decls.elems); +}); - bench('elem mods', () => { - merge.apply(null, decls.elemMods); - }); +bench('elem mods', () => { + merge.apply(null, decls.elemMods); +}); - bench('full', () => { - merge.apply(null, decls.full); - }); +bench('full', () => { + merge.apply(null, decls.full); }); diff --git a/packages/decl/benchmark/normalize-harmony.bench.js b/packages/decl/benchmark/normalize-harmony.bench.js index 7fa96c33..0851eabb 100644 --- a/packages/decl/benchmark/normalize-harmony.bench.js +++ b/packages/decl/benchmark/normalize-harmony.bench.js @@ -1,9 +1,10 @@ -'use strict'; +import { performance } from 'node:perf_hooks'; + +import { normalize } from '../lib/index.js'; -const bemdecl = require('../lib/index'); const opts = { harmony: true }; -const normalize = function (entities) { - return bemdecl.normalize(entities, opts); +const normalizeHarmony = function (entities) { + return normalize(entities, opts); }; const decls = { blocks: [ @@ -35,26 +36,33 @@ const decls = { decls.full = [].concat(decls.blocks, decls.blockMods, decls.elems, decls.elemMods); -suite('normalize --harmony', () => { - set('interations', 200000); +function bench(name, fn, iterations = 200000) { + const start = performance.now(); + for (let i = 0; i < iterations; i++) { + fn(); + } + const elapsed = performance.now() - start; + console.log(` ${name}: ${iterations} iterations in ${elapsed.toFixed(2)}ms (${(iterations / elapsed * 1000).toFixed(0)} ops/sec)`); +} + +console.log('normalize --harmony:'); - bench('blocks', () => { - normalize(decls.blocks); - }); +bench('blocks', () => { + normalizeHarmony(decls.blocks); +}); - bench('block mods', () => { - normalize(decls.blockMods); - }); +bench('block mods', () => { + normalizeHarmony(decls.blockMods); +}); - bench('elems', () => { - normalize(decls.elems); - }); +bench('elems', () => { + normalizeHarmony(decls.elems); +}); - bench('elem mods', () => { - normalize(decls.elemMods); - }); +bench('elem mods', () => { + normalizeHarmony(decls.elemMods); +}); - bench('full', () => { - normalize(decls.full); - }); +bench('full', () => { + normalizeHarmony(decls.full); }); diff --git a/packages/decl/benchmark/normalize.bench.js b/packages/decl/benchmark/normalize.bench.js index 9c7a73b2..fbe22f07 100644 --- a/packages/decl/benchmark/normalize.bench.js +++ b/packages/decl/benchmark/normalize.bench.js @@ -1,6 +1,7 @@ -'use strict'; +import { performance } from 'node:perf_hooks'; + +import { normalize } from '../lib/index.js'; -const normalize = require('../lib/index').normalize; const decls = { blocks: [ { name: 'block-1' }, @@ -29,26 +30,33 @@ const decls = { decls.full = [].concat(decls.blocks, decls.blockMods, decls.elems, decls.elemMods); -suite('normalize', () => { - set('interations', 200000); +function bench(name, fn, iterations = 200000) { + const start = performance.now(); + for (let i = 0; i < iterations; i++) { + fn(); + } + const elapsed = performance.now() - start; + console.log(` ${name}: ${iterations} iterations in ${elapsed.toFixed(2)}ms (${(iterations / elapsed * 1000).toFixed(0)} ops/sec)`); +} + +console.log('normalize:'); - bench('blocks', () => { - normalize(decls.blocks); - }); +bench('blocks', () => { + normalize(decls.blocks); +}); - bench('block mods', () => { - normalize(decls.blockMods); - }); +bench('block mods', () => { + normalize(decls.blockMods); +}); - bench('elems', () => { - normalize(decls.elems); - }); +bench('elems', () => { + normalize(decls.elems); +}); - bench('elem mods', () => { - normalize(decls.elemMods); - }); +bench('elem mods', () => { + normalize(decls.elemMods); +}); - bench('full', () => { - normalize(decls.full); - }); +bench('full', () => { + normalize(decls.full); }); diff --git a/packages/decl/benchmark/subtract.bench.js b/packages/decl/benchmark/subtract.bench.js index 385f61b7..5446d229 100644 --- a/packages/decl/benchmark/subtract.bench.js +++ b/packages/decl/benchmark/subtract.bench.js @@ -1,14 +1,21 @@ -'use strict'; +import { performance } from 'node:perf_hooks'; -const subtract = require('../lib/index').subtract; +import { subtract } from '../lib/index.js'; -suite('subtract', () => { - set('interations', 200000); +function bench(name, fn, iterations = 200000) { + const start = performance.now(); + for (let i = 0; i < iterations; i++) { + fn(); + } + const elapsed = performance.now() - start; + console.log(` ${name}: ${iterations} iterations in ${elapsed.toFixed(2)}ms (${(iterations / elapsed * 1000).toFixed(0)} ops/sec)`); +} - bench('blocks', () => { - var decl1 = [{ block: 'block-1' }, { block: 'block-2' }, { block: 'block-3' }], - decl2 = [{ block: 'block-2' }]; +console.log('subtract:'); - subtract(decl1, decl2); - }); +bench('blocks', () => { + const decl1 = [{ block: 'block-1' }, { block: 'block-2' }, { block: 'block-3' }]; + const decl2 = [{ block: 'block-2' }]; + + subtract(decl1, decl2); }); diff --git a/packages/decl/lib/assign.js b/packages/decl/lib/assign.js index 343e9213..a4e2bf8d 100644 --- a/packages/decl/lib/assign.js +++ b/packages/decl/lib/assign.js @@ -1,8 +1,6 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const BemCell = require('@bem/sdk.cell'); +import BemCell from '@bem/sdk.cell'; const isValidVal = v => Boolean(v || v === 0); @@ -14,7 +12,7 @@ const isValidVal = v => Boolean(v || v === 0); * @param {BemCell} scope - Context, the processing entity usually * @returns {BemCell} - Filled entity and tech */ -module.exports = function (cell, scope) { +export default function (cell, scope) { assert(scope, 'Scope parameter is a required one.'); assert(scope.constructor.name === 'BemCell' || scope.entity && scope.entity.block, 'Scope parameter should be a BemCell-like object.'); @@ -57,4 +55,4 @@ module.exports = function (cell, scope) { } return BemCell.create(result); -}; +} diff --git a/packages/decl/lib/cellify.js b/packages/decl/lib/cellify.js index f2691bca..7838e952 100644 --- a/packages/decl/lib/cellify.js +++ b/packages/decl/lib/cellify.js @@ -1,8 +1,6 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; -const BemCell = require('@bem/sdk.cell'); - -module.exports = (data) => { +export default (data) => { const arr = Array.isArray(data) ? data : [data]; return arr.map(BemCell.create); diff --git a/packages/decl/lib/detect.js b/packages/decl/lib/detect.js index 35416315..e471bb99 100644 --- a/packages/decl/lib/detect.js +++ b/packages/decl/lib/detect.js @@ -1,6 +1,4 @@ -'use strict'; - -const assert = require('assert'); +import assert from 'node:assert'; /** * Detects decl format @@ -8,7 +6,7 @@ const assert = require('assert'); * @param {Object} obj Declaration object * @return {String} */ -module.exports = function (obj) { +export default function (obj) { assert(typeof obj === 'object', 'Argument must be an object'); if (typeof obj.blocks === 'object') { @@ -18,4 +16,4 @@ module.exports = function (obj) { } else if (typeof obj.decl === 'object' || Array.isArray(obj)) { return 'v2'; } -}; +} diff --git a/packages/decl/lib/format.js b/packages/decl/lib/format.js index cdb0d7be..de89f086 100644 --- a/packages/decl/lib/format.js +++ b/packages/decl/lib/format.js @@ -1,8 +1,6 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const formats = require('./formats'); +import formats from './formats/index.js'; /** * Formats a normalized declaration to the target format @@ -12,7 +10,7 @@ const formats = require('./formats'); * @param {string} opts.format target format * @return {Array} Array with converted declaration */ -module.exports = function (decl, opts) { +export default function (decl, opts) { opts || (opts = {}); const formatName = opts.format; @@ -26,4 +24,4 @@ module.exports = function (decl, opts) { } return format.format(decl); -}; +} diff --git a/packages/decl/lib/formats/enb/format.js b/packages/decl/lib/formats/enb/format.js index 11859bc9..29df880d 100644 --- a/packages/decl/lib/formats/enb/format.js +++ b/packages/decl/lib/formats/enb/format.js @@ -1,12 +1,10 @@ -'use strict'; - /** * Format normalized declaration to enb format. * * @param {BemCell[]} cells - Source declaration * @returns {Array<{block: string, elem: ?string, mod: ?{name: string, val: (string|true)}, tech: ?string}>} */ -module.exports = function (cells) { +export default function (cells) { Array.isArray(cells) || (cells = [cells]); const decl = cells.map(cell => { @@ -26,4 +24,4 @@ module.exports = function (cells) { }); return decl; -}; +} diff --git a/packages/decl/lib/formats/enb/index.js b/packages/decl/lib/formats/enb/index.js index 92b63293..5c9ea270 100644 --- a/packages/decl/lib/formats/enb/index.js +++ b/packages/decl/lib/formats/enb/index.js @@ -1,6 +1,5 @@ -'use strict'; +import format from './format.js'; +import parse from './parse.js'; -module.exports = { - format: require('./format'), - parse: require('./parse') -}; +export { format, parse }; +export default { format, parse }; diff --git a/packages/decl/lib/formats/enb/normalize.js b/packages/decl/lib/formats/enb/normalize.js index 69564efd..f398dc1d 100644 --- a/packages/decl/lib/formats/enb/normalize.js +++ b/packages/decl/lib/formats/enb/normalize.js @@ -1,7 +1,5 @@ -'use strict'; - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; /** * Normalizes enb declaration. @@ -9,14 +7,14 @@ const BemCell = require('@bem/sdk.cell'); * @param {Array<{block: string, elem: ?string, mod: ?{name: string, val: (string|true)}, tech: ?string}>} items - declaration * @returns {BemCell[]} */ -module.exports = function (items) { +export default function (items) { return items.map(item => { const entityObj = { block: item.block }; item.elem && (entityObj.elem = item.elem); if (item.mod) { - entityObj.mod = { name: item.mod } + entityObj.mod = { name: item.mod }; item.val && (entityObj.mod.val = item.val); } @@ -25,4 +23,4 @@ module.exports = function (items) { tech: item.tech }); }); -}; +} diff --git a/packages/decl/lib/formats/enb/parse.js b/packages/decl/lib/formats/enb/parse.js index 3ededbbf..c5a56baa 100644 --- a/packages/decl/lib/formats/enb/parse.js +++ b/packages/decl/lib/formats/enb/parse.js @@ -1,8 +1,6 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const normalize = require('./normalize'); +import normalize from './normalize.js'; /** * Parses enb declaration. @@ -10,8 +8,8 @@ const normalize = require('./normalize'); * @param {Object} data - Object with declaration * @returns {BemCell[]} */ -module.exports = (data) => { - assert(data.hasOwnProperty('deps') || data.hasOwnProperty('decl'), 'Invalid format of enb declaration.'); +export default (data) => { + assert(Object.hasOwn(data, 'deps') || Object.hasOwn(data, 'decl'), 'Invalid format of enb declaration.'); return normalize(data.deps || data.decl); }; diff --git a/packages/decl/lib/formats/harmony/index.js b/packages/decl/lib/formats/harmony/index.js index 419197db..9283853a 100644 --- a/packages/decl/lib/formats/harmony/index.js +++ b/packages/decl/lib/formats/harmony/index.js @@ -1,5 +1,4 @@ -'use strict'; +import parse from './parse.js'; -module.exports = { - parse: require('./parse') -}; +export { parse }; +export default { parse }; diff --git a/packages/decl/lib/formats/harmony/normalize.js b/packages/decl/lib/formats/harmony/normalize.js index 94a6128a..e9435c6f 100644 --- a/packages/decl/lib/formats/harmony/normalize.js +++ b/packages/decl/lib/formats/harmony/normalize.js @@ -1,7 +1,5 @@ -'use strict'; - -const BemCell = require('@bem/sdk.cell'); -const BemEntityName = require('@bem/sdk.entity-name'); +import BemCell from '@bem/sdk.cell'; +import BemEntityName from '@bem/sdk.entity-name'; function getMods(entity) { let mods = entity.mods; @@ -32,7 +30,7 @@ function getMods(entity) { return res; } -module.exports = function (decl) { +export default function (decl) { const res = []; const hash = {}; @@ -125,4 +123,4 @@ module.exports = function (decl) { } return res; -}; +} diff --git a/packages/decl/lib/formats/harmony/parse.js b/packages/decl/lib/formats/harmony/parse.js index 82065444..7deabc2e 100644 --- a/packages/decl/lib/formats/harmony/parse.js +++ b/packages/decl/lib/formats/harmony/parse.js @@ -1,17 +1,15 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const normalize = require('./normalize'); +import normalize from './normalize.js'; /** - * Parses enb declaration. + * Parses harmony declaration. * * @param {Object} data - Object with declaration * @returns {BemCell[]} */ -module.exports = (data) => { - assert(data.hasOwnProperty('decl'), 'Invalid format of harmony declaration.'); +export default (data) => { + assert(Object.hasOwn(data, 'decl'), 'Invalid format of harmony declaration.'); return normalize(data.decl); }; diff --git a/packages/decl/lib/formats/index.js b/packages/decl/lib/formats/index.js index 15623fd2..f06dfdae 100644 --- a/packages/decl/lib/formats/index.js +++ b/packages/decl/lib/formats/index.js @@ -1,4 +1,7 @@ -'use strict'; +import v1 from './v1/index.js'; +import v2 from './v2/index.js'; +import enb from './enb/index.js'; +import harmony from './harmony/index.js'; const isNotSupported = () => { throw new Error( @@ -11,14 +14,9 @@ const baseFormat = { parse: isNotSupported }; -const formats = { - v1: require('./v1'), - v2: require('./v2'), - enb: require('./enb'), - harmony: require('./harmony') -}; +const formats = { v1, v2, enb, harmony }; -module.exports = Object.keys(formats).reduce((obj, formatName) => { +export default Object.keys(formats).reduce((obj, formatName) => { obj[formatName] = Object.assign({}, baseFormat, formats[formatName]); return obj; diff --git a/packages/decl/lib/formats/v1/format.js b/packages/decl/lib/formats/v1/format.js index 617a868a..09022cd2 100644 --- a/packages/decl/lib/formats/v1/format.js +++ b/packages/decl/lib/formats/v1/format.js @@ -1,8 +1,4 @@ -'use strict'; - -module.exports = formatv1; - -function formatv1(decl) { +export default function formatv1(decl) { Array.isArray(decl) || decl && (decl = [decl]); if (!decl || !decl.length) { diff --git a/packages/decl/lib/formats/v1/index.js b/packages/decl/lib/formats/v1/index.js index 92b63293..5c9ea270 100644 --- a/packages/decl/lib/formats/v1/index.js +++ b/packages/decl/lib/formats/v1/index.js @@ -1,6 +1,5 @@ -'use strict'; +import format from './format.js'; +import parse from './parse.js'; -module.exports = { - format: require('./format'), - parse: require('./parse') -}; +export { format, parse }; +export default { format, parse }; diff --git a/packages/decl/lib/formats/v1/normalize.js b/packages/decl/lib/formats/v1/normalize.js index 90d254d7..ebf50497 100644 --- a/packages/decl/lib/formats/v1/normalize.js +++ b/packages/decl/lib/formats/v1/normalize.js @@ -1,9 +1,7 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; +import BemEntityName from '@bem/sdk.entity-name'; -const BemCell = require('@bem/sdk.cell'); -const BemEntityName = require('@bem/sdk.entity-name'); - -module.exports = function (decl) { +export default function (decl) { const res = []; const hash = {}; @@ -70,4 +68,4 @@ module.exports = function (decl) { } return res; -}; +} diff --git a/packages/decl/lib/formats/v1/parse.js b/packages/decl/lib/formats/v1/parse.js index f98378fb..fb4f69c8 100644 --- a/packages/decl/lib/formats/v1/parse.js +++ b/packages/decl/lib/formats/v1/parse.js @@ -1,17 +1,15 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const normalize = require('./normalize'); +import normalize from './normalize.js'; /** - * Parses enb declaration. + * Parses v1 declaration. * * @param {Object} data - Object with declaration * @returns {BemCell[]} */ -module.exports = (data) => { - assert(data.hasOwnProperty('blocks'), 'Invalid format of v1 declaration.'); +export default (data) => { + assert(Object.hasOwn(data, 'blocks'), 'Invalid format of v1 declaration.'); return normalize(data.blocks); }; diff --git a/packages/decl/lib/formats/v2/format.js b/packages/decl/lib/formats/v2/format.js index ed1316ea..d8c89cad 100644 --- a/packages/decl/lib/formats/v2/format.js +++ b/packages/decl/lib/formats/v2/format.js @@ -1,3 +1 @@ -'use strict'; - -module.exports = require('../enb/format'); +export { default } from '../enb/format.js'; diff --git a/packages/decl/lib/formats/v2/index.js b/packages/decl/lib/formats/v2/index.js index 92b63293..5c9ea270 100644 --- a/packages/decl/lib/formats/v2/index.js +++ b/packages/decl/lib/formats/v2/index.js @@ -1,6 +1,5 @@ -'use strict'; +import format from './format.js'; +import parse from './parse.js'; -module.exports = { - format: require('./format'), - parse: require('./parse') -}; +export { format, parse }; +export default { format, parse }; diff --git a/packages/decl/lib/formats/v2/normalize.js b/packages/decl/lib/formats/v2/normalize.js index feadcd46..cbfb2739 100644 --- a/packages/decl/lib/formats/v2/normalize.js +++ b/packages/decl/lib/formats/v2/normalize.js @@ -1,11 +1,9 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; +import BemEntityName from '@bem/sdk.entity-name'; -const BemCell = require('@bem/sdk.cell'); -const BemEntityName = require('@bem/sdk.entity-name'); +import declAssign from '../../assign.js'; -const declAssign = require('../../assign'); - -module.exports = function (decl, scope) { +export default function (decl, scope) { const res = []; const hash = {}; @@ -172,7 +170,7 @@ module.exports = function (decl, scope) { if (!entity.mod) { return mod; } - const val = entity.hasOwnProperty('val') ? + const val = Object.hasOwn(entity, 'val') ? entity.val : true; @@ -243,4 +241,4 @@ module.exports = function (decl, scope) { function isNotActual(obj) { return !obj || (typeof obj === 'object' && Object.keys(obj).length === 0); } -}; +} diff --git a/packages/decl/lib/formats/v2/parse.js b/packages/decl/lib/formats/v2/parse.js index 20c1d57e..8a4784e6 100644 --- a/packages/decl/lib/formats/v2/parse.js +++ b/packages/decl/lib/formats/v2/parse.js @@ -1,17 +1,15 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const normalize = require('./normalize'); +import normalize from './normalize.js'; /** - * Parses enb declaration. + * Parses v2 declaration. * * @param {Object} data - Object with declaration * @returns {BemCell[]} */ -module.exports = (data) => { - assert(data.hasOwnProperty('decl'), 'Invalid format of v2 declaration.'); +export default (data) => { + assert(Object.hasOwn(data, 'decl'), 'Invalid format of v2 declaration.'); return normalize(data.decl); }; diff --git a/packages/decl/lib/index.js b/packages/decl/lib/index.js index 7dcf196e..2d2b8ab5 100644 --- a/packages/decl/lib/index.js +++ b/packages/decl/lib/index.js @@ -1,14 +1,36 @@ -'use strict'; +import format from './format.js'; +import normalize from './normalize.js'; +import merge from './merge.js'; +import subtract from './subtract.js'; +import intersect from './intersect.js'; +import parse from './parse.js'; +import assign from './assign.js'; +import load from './load.js'; +import stringify from './stringify.js'; +import save from './save.js'; -module.exports = { - format: require('./format'), - normalize: require('./normalize'), - merge: require('./merge'), - subtract: require('./subtract'), - intersect: require('./intersect'), - parse: require('./parse'), - assign: require('./assign'), - load: require('./load'), - stringify: require('./stringify'), - save: require('./save') +export { + format, + normalize, + merge, + subtract, + intersect, + parse, + assign, + load, + stringify, + save +}; + +export default { + format, + normalize, + merge, + subtract, + intersect, + parse, + assign, + load, + stringify, + save }; diff --git a/packages/decl/lib/intersect.js b/packages/decl/lib/intersect.js index 9bcdd821..0dae85c2 100644 --- a/packages/decl/lib/intersect.js +++ b/packages/decl/lib/intersect.js @@ -1,5 +1,3 @@ -'use strict'; - /** * Intersecting sets of cells. * @@ -7,7 +5,7 @@ * @param {...(BemCell[])} otherSet - Set (or sets) of that should be merged into the original one. * @returns {BemCell[]} - Resulting set of cells. */ -module.exports = function () { +export default function () { const hash = {}; const res = []; const setsQty = arguments.length; @@ -31,4 +29,4 @@ module.exports = function () { } return res; -}; +} diff --git a/packages/decl/lib/load.js b/packages/decl/lib/load.js index 69dc24c3..e61f7054 100644 --- a/packages/decl/lib/load.js +++ b/packages/decl/lib/load.js @@ -1,11 +1,6 @@ -'use strict'; +import { readFile } from 'node:fs/promises'; -const fs = require('graceful-fs'); -const promisify = require('es6-promisify'); - -const parse = require('./parse'); - -const readFile = promisify(fs.readFile); +import parse from './parse.js'; /** * Read file and call parse on its content @@ -14,4 +9,4 @@ const readFile = promisify(fs.readFile); * @param {Object} opts additional options * @return {Promise} */ -module.exports = (filePath, opts) => readFile(filePath, opts || 'utf-8').then(parse); +export default (filePath, opts) => readFile(filePath, opts || 'utf-8').then(parse); diff --git a/packages/decl/lib/merge.js b/packages/decl/lib/merge.js index 537857de..97707f33 100644 --- a/packages/decl/lib/merge.js +++ b/packages/decl/lib/merge.js @@ -1,5 +1,3 @@ -'use strict'; - /** * Merging sets of cells. * @@ -7,7 +5,7 @@ * @param {...(BemCell[])} otherCollection - Set (or sets) of that should be merged into the original one. * @returns {BemCell[]} - Resulting set of cells. */ -module.exports = function (collection) { +export default function (collection) { const hash = {}; const res = [].concat(collection); @@ -33,4 +31,4 @@ module.exports = function (collection) { } return res; -}; +} diff --git a/packages/decl/lib/normalize.js b/packages/decl/lib/normalize.js index 8c9b279f..8644e856 100644 --- a/packages/decl/lib/normalize.js +++ b/packages/decl/lib/normalize.js @@ -1,13 +1,16 @@ -'use strict'; +import v1Normalize from './formats/v1/normalize.js'; +import v2Normalize from './formats/v2/normalize.js'; +import harmonyNormalize from './formats/harmony/normalize.js'; +import enbNormalize from './formats/enb/normalize.js'; const normalizer = { - v1: require('./formats/v1/normalize'), - v2: require('./formats/v2/normalize'), - harmony: require('./formats/harmony/normalize'), - enb: require('./formats/enb/normalize') + v1: v1Normalize, + v2: v2Normalize, + harmony: harmonyNormalize, + enb: enbNormalize }; -module.exports = (decl, opts) => { +export default (decl, opts) => { opts || (opts = {}); const format = opts.format || 'v2'; diff --git a/packages/decl/lib/parse.js b/packages/decl/lib/parse.js index f27a2037..29cf25f2 100644 --- a/packages/decl/lib/parse.js +++ b/packages/decl/lib/parse.js @@ -1,11 +1,24 @@ -'use strict'; +import assert from 'node:assert'; +import vm from 'node:vm'; -const assert = require('assert'); +import formats from './formats/index.js'; +import detect from './detect.js'; -const nodeEval = require('node-eval'); - -const formats = require('./formats'); -const detect = require('./detect'); +/** + * Evaluate code string similar to node-eval. + * Supports both module.exports style and expression style (e.g. `({ blocks: [...] })`). + * + * @param {String} code - code to evaluate + * @returns {*} - evaluated result + */ +function nodeEval(code) { + const m = { exports: {} }; + const wrapped = `(function(module, exports) { return ${code}\n})(m, m.exports)`; + const result = vm.runInNewContext(wrapped, { m }); + // If the code is an expression (like `({ blocks: [...] })`), return the expression result. + // If it uses module.exports, return m.exports. + return result !== undefined ? result : m.exports; +} /** * Parses BEMDECL file data @@ -13,7 +26,7 @@ const detect = require('./detect'); * @param {String|Object} bemdecl - string of bemdecl or object * @returns {Array} Array of normalized entities */ -module.exports = function parse(bemdecl) { +export default function parse(bemdecl) { assert(typeof bemdecl === 'object' || typeof bemdecl === 'string', 'Bemdecl must be String or Object'); const data = (typeof bemdecl === 'string') ? nodeEval(bemdecl) : bemdecl; @@ -25,4 +38,4 @@ module.exports = function parse(bemdecl) { } return format.parse(data); -}; +} diff --git a/packages/decl/lib/save.js b/packages/decl/lib/save.js index 4613efc5..b5d3285b 100644 --- a/packages/decl/lib/save.js +++ b/packages/decl/lib/save.js @@ -1,10 +1,6 @@ -'use strict'; +import { writeFile } from 'node:fs/promises'; -const fs = require('fs'); -const promisify = require('es6-promisify'); -const stringify = require('./stringify'); - -const writeFile = promisify(fs.writeFile); +import stringify from './stringify.js'; /** * Save normalized declaration to target format @@ -17,7 +13,7 @@ const writeFile = promisify(fs.writeFile); * @param {Number} [opts.mode=0o666] File mode * @returns {Promise.} */ -module.exports = (filename, cells, opts) => { +export default (filename, cells, opts) => { const options = opts || {}; const defaults = { format: 'v2', @@ -27,4 +23,4 @@ module.exports = (filename, cells, opts) => { const str = stringify(cells, Object.assign({}, defaults, opts)); return writeFile(filename, str, { mode: options.mode }); -} +}; diff --git a/packages/decl/lib/stringify.js b/packages/decl/lib/stringify.js index 88b871c8..24688720 100644 --- a/packages/decl/lib/stringify.js +++ b/packages/decl/lib/stringify.js @@ -1,9 +1,6 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); -const JSON5 = require('json5'); - -const format = require('./format'); +import format from './format.js'; const DEFAULTS = { exportType: 'json', space: 4 }; @@ -17,11 +14,23 @@ const fieldByFormat = { v2: 'deps' }; +/** + * Simple JSON5-like output: unquoted keys where possible. + * + * @param {*} obj - object to stringify + * @param {null} _replacer - unused, kept for signature compat + * @param {String|Number} space - indentation + * @returns {String} + */ +function json5Stringify(obj, _replacer, space) { + return JSON.stringify(obj, null, space).replace(/"(\w+)":/g, '$1:'); +} + const generators = { - json5: (obj, space) => JSON5.stringify(obj, null, space), + json5: (obj, space) => json5Stringify(obj, null, space), json: (obj, space) => JSON.stringify(obj, null, space), - commonjs: (obj, space) => `module.exports = ${JSON5.stringify(obj, null, space)};\n`, - es2015: (obj, space) => `export default ${JSON5.stringify(obj, null, space)};\n` + commonjs: (obj, space) => `module.exports = ${json5Stringify(obj, null, space)};\n`, + es2015: (obj, space) => `export default ${json5Stringify(obj, null, space)};\n` }; // Aliases generators.es6 = generators.es2015; @@ -37,12 +46,12 @@ generators.cjs = generators.commonjs; * @param {String|Number} [opts.space] - number of space characters or string to use as a white space * @returns {String} */ -module.exports = function (decl, opts) { +export default function (decl, opts) { const options = Object.assign({}, DEFAULTS, opts); assert(options.format, 'You must declare target format'); - assert(fieldByFormat.hasOwnProperty(options.format), 'Specified format isn\'t supported'); - assert(generators.hasOwnProperty(options.exportType), 'Specified export type isn\'t supported'); + assert(Object.hasOwn(fieldByFormat, options.format), 'Specified format isn\'t supported'); + assert(Object.hasOwn(generators, options.exportType), 'Specified export type isn\'t supported'); Array.isArray(decl) || (decl = [decl]); @@ -57,4 +66,4 @@ module.exports = function (decl, opts) { } return generators[options.exportType](stringifiedObj, options.space); -}; +} diff --git a/packages/decl/lib/subtract.js b/packages/decl/lib/subtract.js index b8244837..328e37d9 100644 --- a/packages/decl/lib/subtract.js +++ b/packages/decl/lib/subtract.js @@ -1,6 +1,4 @@ -'use strict'; - -const merge = require('./merge'); +import merge from './merge.js'; /** * Subtracting sets of cells. @@ -9,7 +7,7 @@ const merge = require('./merge'); * @param {...(BemCell[])} removingSet - Set (or sets) with cells that should be removed * @returns {BemCell[]} - Resulting set of cells */ -module.exports = function (collection, removingSet) { +export default function (collection, removingSet) { const hash = {}; (arguments.length > 2) && (removingSet = merge.apply(null, [].slice.call(arguments, 1))); @@ -21,4 +19,4 @@ module.exports = function (collection, removingSet) { return collection.filter(function (item) { return !hash[item.id]; }); -}; +} diff --git a/packages/decl/package.json b/packages/decl/package.json index 76e01573..34c3165c 100644 --- a/packages/decl/package.json +++ b/packages/decl/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.decl", "version": "0.3.10", "description": "Manage declaration of BEM entities", + "type": "module", "publishConfig": { "access": "public" }, @@ -22,7 +23,7 @@ }, "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/decl#readme", "engines": { - "node": ">= 8" + "node": ">= 24.0" }, "main": "lib/index.js", "files": [ @@ -30,19 +31,10 @@ ], "dependencies": { "@bem/sdk.cell": "^0.2.9", - "@bem/sdk.entity-name": "^0.2.11", - "es6-promisify": "5.0.0", - "graceful-fs": "4.1.11", - "json5": "0.5.1", - "node-eval": "1.1.0" + "@bem/sdk.entity-name": "^0.2.11" }, "scripts": { - "bench": "matcha benchmark/*.bench.js", "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" - }, - "devDependencies": { - "matcha": "^0.7.0" } } diff --git a/packages/decl/test/assign.test.js b/packages/decl/test/assign.test.js index 434b3575..bcf6d54b 100644 --- a/packages/decl/test/assign.test.js +++ b/packages/decl/test/assign.test.js @@ -1,15 +1,11 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; +import { assign } from '../lib/index.js'; const simplifyCell = c => Object.assign({tech: null}, c.valueOf()); -const assign = require('..').assign; describe('assign', () => { - it('entity block should dominate scope’s one', () => { + it('entity block should dominate scope\u2019s one', () => { expect(simplifyCell(assign( { entity: { block: 'b' } }, { entity: { block: 'sb' } }))).to.deep.equal( @@ -30,21 +26,21 @@ describe('assign', () => { { entity: { block: 'b' }, tech: null }); }); - it('entity elem should dominate scope’s one', () => { + it('entity elem should dominate scope\u2019s one', () => { expect(simplifyCell(assign( { entity: { block: 'b', elem: 'e' } }, { entity: { block: 'sb', elem: 'sb' } }))).to.deep.equal( { entity: { block: 'b', elem: 'e' }, tech: null }); }); - it('entity modName should dominate scope’s one for block', () => { + it('entity modName should dominate scope\u2019s one for block', () => { expect(simplifyCell(assign( { entity: { block: 'b', mod: { name: 'm' } } }, { entity: { block: 'sb', mod: { name: 'sm' } } }))).to.deep.equal( { entity: { block: 'b', mod: { name: 'm', val: true }}, tech: null }); }); - it('entity modVal should dominate scope’s one for block', () => { + it('entity modVal should dominate scope\u2019s one for block', () => { expect(simplifyCell(assign( { entity: { block: 'b', mod: { name: 'm', val: 'v' } } }, { entity: { block: 'sb', mod: { name: 'sm', val: 'sv' } } }))).to.deep.equal( @@ -58,14 +54,14 @@ describe('assign', () => { { entity: { block: 'b', mod: { name: 'm', val: 'v' } }, tech: null }); }); - it('entity modName should dominate scope’s one for block and elem', () => { + it('entity modName should dominate scope\u2019s one for block and elem', () => { expect(simplifyCell(assign( { entity: { block: 'b', elem: 'e', mod: { name: 'm' } } }, { entity: { block: 'sb', elem: 'se', mod: { name: 'sm' } } }))).to.deep.equal( { entity: { block: 'b', elem: 'e', mod: { name: 'm', val: true }}, tech: null }); }); - it('entity modVal should dominate scope’s one for block and elem', () => { + it('entity modVal should dominate scope\u2019s one for block and elem', () => { expect(simplifyCell(assign( { entity: { block: 'b', elem: 'e', mod: { name: 'm', val: 'v' } } }, { entity: { block: 'sb', elem: 'se', mod: { name: 'sm', val: 'sv' } } }))).to.deep.equal( @@ -93,35 +89,35 @@ describe('assign', () => { { entity: { block: 'sb', elem: 'e' }, tech: null }); }); - it('entity elem should use scope’s block', () => { + it('entity elem should use scope\u2019s block', () => { expect(simplifyCell(assign( { entity: { elem: 'e' } }, { entity: { block: 'sb', elem: 'se' } }))).to.deep.equal( { entity: { block: 'sb', elem: 'e' }, tech: null }); }); - it('entity modName should use scope’s block', () => { + it('entity modName should use scope\u2019s block', () => { expect(simplifyCell(assign( { entity: { mod: { name: 'm' } } }, { entity: { block: 'sb', mod: { name: 'sm' } } }))).to.deep.equal( { entity: { block: 'sb', mod: { name: 'm', val: true }}, tech: null }); }); - it('entity modName should use scope’s elem', () => { + it('entity modName should use scope\u2019s elem', () => { expect(simplifyCell(assign( { entity: { mod: { name: 'm' } } }, { entity: { block: 'sb', elem: 'se', mod: { name: 'sm' } } }))).to.deep.equal( { entity: { block: 'sb', elem: 'se', mod: { name: 'm', val: true }}, tech: null }); }); - it('entity modVal should use scope’s block and modName', () => { + it('entity modVal should use scope\u2019s block and modName', () => { expect(simplifyCell(assign( { entity: { mod: { val: 'v' } } }, { entity: { block: 'sb', mod: { name: 'sm', val: 'sv' } } }))).to.deep.equal( { entity: { block: 'sb', mod: { name: 'sm', val: 'v' } }, tech: null }); }); - it('entity modVal should use scope’s block, elem and modName', () => { + it('entity modVal should use scope\u2019s block, elem and modName', () => { expect(simplifyCell(assign( { entity: { mod: { val: 'v' } } }, { entity: { block: 'sb', elem: 'se', mod: { name: 'sm', val: 'sv' } } }))).to.deep.equal( @@ -261,7 +257,7 @@ describe('assign', () => { { entity: { block: 'b' }, tech: 'js' }); }); - it('entity tech should dominate the scope’s one', () => { + it('entity tech should dominate the scope\u2019s one', () => { expect(simplifyCell(assign( { entity: { block: 'b' }, tech: 'bemhtml' }, { entity: { block: 'sb' }, tech: 'js' }))).to.deep.equal( diff --git a/packages/decl/test/formats/enb/format.test.js b/packages/decl/test/formats/enb/format.test.js index 9c849d27..adef36a1 100644 --- a/packages/decl/test/formats/enb/format.test.js +++ b/packages/decl/test/formats/enb/format.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { assert } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const assert = require('chai').assert; - -const cellify = require('../../../lib/cellify'); -const format = require('../../../lib/formats/enb/format'); +import cellify from '../../../lib/cellify.js'; +import format from '../../../lib/formats/enb/format.js'; describe('decl.formats.enb.format', () => { it('should format block', () => { diff --git a/packages/decl/test/formats/enb/normalize.test.js b/packages/decl/test/formats/enb/normalize.test.js index 96ab1ea2..e90d32d7 100644 --- a/packages/decl/test/formats/enb/normalize.test.js +++ b/packages/decl/test/formats/enb/normalize.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { assert } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const assert = require('chai').assert; - -const cellify = require('../../../lib/cellify'); -const normalize = require('../../../lib/formats/enb/normalize'); +import cellify from '../../../lib/cellify.js'; +import normalize from '../../../lib/formats/enb/normalize.js'; describe('decl.formats.enb.normalize', () => { it('should normalize block', () => { diff --git a/packages/decl/test/formats/enb/parse.test.js b/packages/decl/test/formats/enb/parse.test.js index 259a5806..9ed49b34 100644 --- a/packages/decl/test/formats/enb/parse.test.js +++ b/packages/decl/test/formats/enb/parse.test.js @@ -1,12 +1,9 @@ -'use strict'; +import { assert } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { simplifyCell } from '../../util.js'; +import enbFormat from '../../../lib/formats/enb/index.js'; -const assert = require('chai').assert; - -const simplifyCell = require('../../util').simplifyCell; -const parse = require('../../../lib/formats/enb').parse; +const { parse } = enbFormat; describe('decl.formats.enb.parse', () => { it('should throw if invalid format', () => { diff --git a/packages/decl/test/formats/harmony/normalize/block.test.js b/packages/decl/test/formats/harmony/normalize/block.test.js index 2261faee..a6376ebb 100644 --- a/packages/decl/test/formats/harmony/normalize/block.test.js +++ b/packages/decl/test/formats/harmony/normalize/block.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony.block', () => { it('should support block', () => { diff --git a/packages/decl/test/formats/harmony/normalize/common.test.js b/packages/decl/test/formats/harmony/normalize/common.test.js index 589f7f17..bb996b70 100644 --- a/packages/decl/test/formats/harmony/normalize/common.test.js +++ b/packages/decl/test/formats/harmony/normalize/common.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony', () => { it('should support undefined', () => { diff --git a/packages/decl/test/formats/harmony/normalize/elem.test.js b/packages/decl/test/formats/harmony/normalize/elem.test.js index 76d42a00..16206de5 100644 --- a/packages/decl/test/formats/harmony/normalize/elem.test.js +++ b/packages/decl/test/formats/harmony/normalize/elem.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony.elem', () => { it('should support elem', () => { diff --git a/packages/decl/test/formats/harmony/normalize/elems.test.js b/packages/decl/test/formats/harmony/normalize/elems.test.js index 9c6dc68c..c99a5d4f 100644 --- a/packages/decl/test/formats/harmony/normalize/elems.test.js +++ b/packages/decl/test/formats/harmony/normalize/elems.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony.elems', () => { it('should support strings', () => { diff --git a/packages/decl/test/formats/harmony/normalize/mix.test.js b/packages/decl/test/formats/harmony/normalize/mix.test.js index 8f26b863..5a3d5531 100644 --- a/packages/decl/test/formats/harmony/normalize/mix.test.js +++ b/packages/decl/test/formats/harmony/normalize/mix.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony.mix', () => { it('should support mix', () => { diff --git a/packages/decl/test/formats/harmony/normalize/mods.test.js b/packages/decl/test/formats/harmony/normalize/mods.test.js index 85c822f8..9191d0cb 100644 --- a/packages/decl/test/formats/harmony/normalize/mods.test.js +++ b/packages/decl/test/formats/harmony/normalize/mods.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony.mods', () => { it('should support shortcut for bool mod', () => { diff --git a/packages/decl/test/formats/harmony/normalize/scope.test.js b/packages/decl/test/formats/harmony/normalize/scope.test.js index d786bb62..b1bb101c 100644 --- a/packages/decl/test/formats/harmony/normalize/scope.test.js +++ b/packages/decl/test/formats/harmony/normalize/scope.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/harmony/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/harmony/normalize.js'; describe('normalize-harmony.scope', () => { it('should support mod in block scope', () => { diff --git a/packages/decl/test/formats/harmony/parse.test.js b/packages/decl/test/formats/harmony/parse.test.js index a7063045..efb09c18 100644 --- a/packages/decl/test/formats/harmony/parse.test.js +++ b/packages/decl/test/formats/harmony/parse.test.js @@ -1,12 +1,9 @@ -'use strict'; +import { assert } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { simplifyCell } from '../../util.js'; +import harmonyFormat from '../../../lib/formats/harmony/index.js'; -const assert = require('chai').assert; - -const simplifyCell = require('../../util').simplifyCell; -const parse = require('../../../lib/formats/harmony').parse; +const { parse } = harmonyFormat; describe('decl.formats.harmony.parse', () => { it('should throw if invalid format', () => { diff --git a/packages/decl/test/formats/v1/format.test.js b/packages/decl/test/formats/v1/format.test.js index 612805fe..23e3072c 100644 --- a/packages/decl/test/formats/v1/format.test.js +++ b/packages/decl/test/formats/v1/format.test.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); - -const format = require('../../../lib/formats/v1/format'); +import BemCell from '@bem/sdk.cell'; +import format from '../../../lib/formats/v1/format.js'; function cellify(entities) { return entities.map(BemCell.create); diff --git a/packages/decl/test/formats/v1/normalize/common.test.js b/packages/decl/test/formats/v1/normalize/common.test.js index c7aa49b0..d79aef18 100644 --- a/packages/decl/test/formats/v1/normalize/common.test.js +++ b/packages/decl/test/formats/v1/normalize/common.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v1/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v1/normalize.js'; describe('intersect.common', () => { it('should support undefined', () => { diff --git a/packages/decl/test/formats/v1/normalize/elems.test.js b/packages/decl/test/formats/v1/normalize/elems.test.js index ec0123cc..1adc1740 100644 --- a/packages/decl/test/formats/v1/normalize/elems.test.js +++ b/packages/decl/test/formats/v1/normalize/elems.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v1/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v1/normalize.js'; describe('intersect.elems', () => { it('should support arrays', () => { diff --git a/packages/decl/test/formats/v1/normalize/mods.test.js b/packages/decl/test/formats/v1/normalize/mods.test.js index 43daf597..f83f8a07 100644 --- a/packages/decl/test/formats/v1/normalize/mods.test.js +++ b/packages/decl/test/formats/v1/normalize/mods.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v1/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v1/normalize.js'; describe('intersect.mods', () => { it('should support objects', () => { diff --git a/packages/decl/test/formats/v1/parse.test.js b/packages/decl/test/formats/v1/parse.test.js index 6fbc82a8..ec25f06f 100644 --- a/packages/decl/test/formats/v1/parse.test.js +++ b/packages/decl/test/formats/v1/parse.test.js @@ -1,12 +1,9 @@ -'use strict'; +import { assert } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { simplifyCell } from '../../util.js'; +import v1Format from '../../../lib/formats/v1/index.js'; -const assert = require('chai').assert; - -const simplifyCell = require('../../util').simplifyCell; -const parse = require('../../../lib/formats/v1').parse; +const { parse } = v1Format; describe('decl.formats.v1.parse', () => { it('should throw if invalid format', () => { diff --git a/packages/decl/test/formats/v2/normalize/block-mod.test.js b/packages/decl/test/formats/v2/normalize/block-mod.test.js index 34e370e9..10f7a41d 100644 --- a/packages/decl/test/formats/v2/normalize/block-mod.test.js +++ b/packages/decl/test/formats/v2/normalize/block-mod.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.block-mods', () => { it('should support mod', () => { diff --git a/packages/decl/test/formats/v2/normalize/block-mods.test.js b/packages/decl/test/formats/v2/normalize/block-mods.test.js index 0626368f..44dafc02 100644 --- a/packages/decl/test/formats/v2/normalize/block-mods.test.js +++ b/packages/decl/test/formats/v2/normalize/block-mods.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.block-mods', () => { it('should support mods', () => { diff --git a/packages/decl/test/formats/v2/normalize/block.test.js b/packages/decl/test/formats/v2/normalize/block.test.js index a932a6e3..f92f9c28 100644 --- a/packages/decl/test/formats/v2/normalize/block.test.js +++ b/packages/decl/test/formats/v2/normalize/block.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.block', () => { it('should support block', () => { diff --git a/packages/decl/test/formats/v2/normalize/common.test.js b/packages/decl/test/formats/v2/normalize/common.test.js index a934af1d..1839154c 100644 --- a/packages/decl/test/formats/v2/normalize/common.test.js +++ b/packages/decl/test/formats/v2/normalize/common.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.common', () => { it('should support undefined', () => { diff --git a/packages/decl/test/formats/v2/normalize/elem-mod.test.js b/packages/decl/test/formats/v2/normalize/elem-mod.test.js index c3d80318..21ddc643 100644 --- a/packages/decl/test/formats/v2/normalize/elem-mod.test.js +++ b/packages/decl/test/formats/v2/normalize/elem-mod.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.elem-mod', () => { it('should support shortcut for bool mod of elem', () => { diff --git a/packages/decl/test/formats/v2/normalize/elem-mods.test.js b/packages/decl/test/formats/v2/normalize/elem-mods.test.js index 4cc8bf4f..6978c09e 100644 --- a/packages/decl/test/formats/v2/normalize/elem-mods.test.js +++ b/packages/decl/test/formats/v2/normalize/elem-mods.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.elem-mods', () => { it('should support elem as object with mods', () => { diff --git a/packages/decl/test/formats/v2/normalize/elem.test.js b/packages/decl/test/formats/v2/normalize/elem.test.js index f3e8bda0..5bda7306 100644 --- a/packages/decl/test/formats/v2/normalize/elem.test.js +++ b/packages/decl/test/formats/v2/normalize/elem.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.elem', () => { it('should support elem', () => { diff --git a/packages/decl/test/formats/v2/normalize/elems-mod.test.js b/packages/decl/test/formats/v2/normalize/elems-mod.test.js index 6b4c18d2..3d100a1a 100644 --- a/packages/decl/test/formats/v2/normalize/elems-mod.test.js +++ b/packages/decl/test/formats/v2/normalize/elems-mod.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.elems-mod', () => { it('should support shortcut for bool mod of elem', () => { diff --git a/packages/decl/test/formats/v2/normalize/elems-mods.test.js b/packages/decl/test/formats/v2/normalize/elems-mods.test.js index c66baf88..e95f9df2 100644 --- a/packages/decl/test/formats/v2/normalize/elems-mods.test.js +++ b/packages/decl/test/formats/v2/normalize/elems-mods.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.elems-mods', () => { it('should support elem as object and mod', () => { diff --git a/packages/decl/test/formats/v2/normalize/elems.test.js b/packages/decl/test/formats/v2/normalize/elems.test.js index 838305bc..e70a876d 100644 --- a/packages/decl/test/formats/v2/normalize/elems.test.js +++ b/packages/decl/test/formats/v2/normalize/elems.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.elems', () => { it('should support elems', () => { diff --git a/packages/decl/test/formats/v2/normalize/iterable.test.js b/packages/decl/test/formats/v2/normalize/iterable.test.js index a6ff388e..d23d4cb5 100644 --- a/packages/decl/test/formats/v2/normalize/iterable.test.js +++ b/packages/decl/test/formats/v2/normalize/iterable.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.iterable', () => { it('should support iterable set', () => { diff --git a/packages/decl/test/formats/v2/normalize/mod-mods-vals.test.js b/packages/decl/test/formats/v2/normalize/mod-mods-vals.test.js index 54ffc071..5be23cbe 100644 --- a/packages/decl/test/formats/v2/normalize/mod-mods-vals.test.js +++ b/packages/decl/test/formats/v2/normalize/mod-mods-vals.test.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const createCell = require('../../../util').createCell; -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { createCell, simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.mod-mods-vals', () => { it('should support mod and mods with scope block, elem', () => { diff --git a/packages/decl/test/formats/v2/normalize/scope.test.js b/packages/decl/test/formats/v2/normalize/scope.test.js index 6417d42e..78775a6d 100644 --- a/packages/decl/test/formats/v2/normalize/scope.test.js +++ b/packages/decl/test/formats/v2/normalize/scope.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.scope', () => { it('should consider block scope', () => { diff --git a/packages/decl/test/formats/v2/normalize/unusual.test.js b/packages/decl/test/formats/v2/normalize/unusual.test.js index 08f1d3b6..b6b3de29 100644 --- a/packages/decl/test/formats/v2/normalize/unusual.test.js +++ b/packages/decl/test/formats/v2/normalize/unusual.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../../../util').simplifyCell; -const normalize = require('../../../../lib/formats/v2/normalize'); +import { simplifyCell } from '../../../util.js'; +import normalize from '../../../../lib/formats/v2/normalize.js'; describe('normalize2.unusual', () => { it('should support both mod and mods', () => { diff --git a/packages/decl/test/formats/v2/parse.test.js b/packages/decl/test/formats/v2/parse.test.js index a1b149a6..a7c05ca8 100644 --- a/packages/decl/test/formats/v2/parse.test.js +++ b/packages/decl/test/formats/v2/parse.test.js @@ -1,12 +1,9 @@ -'use strict'; +import { assert } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { simplifyCell } from '../../util.js'; +import v2Format from '../../../lib/formats/v2/index.js'; -const assert = require('chai').assert; - -const simplifyCell = require('../../util').simplifyCell; -const parse = require('../../../lib/formats/v2').parse; +const { parse } = v2Format; describe('decl.formats.v2.parse', () => { it('should throw if invalid format', () => { diff --git a/packages/decl/test/index.test.js b/packages/decl/test/index.test.js index 9014775e..bc93bb79 100644 --- a/packages/decl/test/index.test.js +++ b/packages/decl/test/index.test.js @@ -1,12 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { simplifyCell } from './util.js'; +import bemDecl from '../lib/index.js'; -const expect = require('chai').expect; - -const simplifyCell = require('./util').simplifyCell; -const bemDecl = require('../lib/index'); const decls = { v1: [{ name: 'block' }], v2: [{ block: 'block' }], diff --git a/packages/decl/test/intersect/disjoint-entities.test.js b/packages/decl/test/intersect/disjoint-entities.test.js index 3b3317c4..5d5dff91 100644 --- a/packages/decl/test/intersect/disjoint-entities.test.js +++ b/packages/decl/test/intersect/disjoint-entities.test.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const createCell = require('../util').createCell; - -const intersect = require('../../lib/intersect'); +import { createCell } from '../util.js'; +import intersect from '../../lib/intersect.js'; describe('intersect.disjoint-entities', () => { it('should not intersect other entities from block', () => { diff --git a/packages/decl/test/intersect/intersecting-entities.test.js b/packages/decl/test/intersect/intersecting-entities.test.js index ef2ddda0..9edf9dc1 100644 --- a/packages/decl/test/intersect/intersecting-entities.test.js +++ b/packages/decl/test/intersect/intersecting-entities.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const createCell = require('../util').createCell; -const intersect = require('../../lib/intersect'); +import { createCell } from '../util.js'; +import intersect from '../../lib/intersect.js'; describe('intersect.intersecting-entities', () => { it('should intersect block with block', () => { diff --git a/packages/decl/test/intersect/sets.test.js b/packages/decl/test/intersect/sets.test.js index 04d2d4ec..2d4082b2 100644 --- a/packages/decl/test/intersect/sets.test.js +++ b/packages/decl/test/intersect/sets.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const createCell = require('../util').createCell; -const intersect = require('../../lib/intersect'); +import { createCell } from '../util.js'; +import intersect from '../../lib/intersect.js'; describe('intersect.sets', () => { it('should support only one decl', () => { diff --git a/packages/decl/test/merge/bem.test.js b/packages/decl/test/merge/bem.test.js index 56dde0e1..2c69791f 100644 --- a/packages/decl/test/merge/bem.test.js +++ b/packages/decl/test/merge/bem.test.js @@ -1,14 +1,10 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); const createCell = BemCell.create; -const merge = require('../../lib/merge'); +import merge from '../../lib/merge.js'; describe('intersect.bem', () => { it('should merge block with its elem', () => { diff --git a/packages/decl/test/merge/sets.test.js b/packages/decl/test/merge/sets.test.js index 3ef8592f..c785b756 100644 --- a/packages/decl/test/merge/sets.test.js +++ b/packages/decl/test/merge/sets.test.js @@ -1,14 +1,10 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); const createCell = BemCell.create; -const merge = require('../../lib/merge'); +import merge from '../../lib/merge.js'; describe('intersect.sets', () => { it('should support only one decl', () => { diff --git a/packages/decl/test/mocha.opts b/packages/decl/test/mocha.opts deleted file mode 100644 index 4a523201..00000000 --- a/packages/decl/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---recursive diff --git a/packages/decl/test/parse/legacy.test.js b/packages/decl/test/parse/legacy.test.js index 0f58072f..b97e3652 100644 --- a/packages/decl/test/parse/legacy.test.js +++ b/packages/decl/test/parse/legacy.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../util').simplifyCell; -const parse = require('../../lib/parse'); +import { simplifyCell } from '../util.js'; +import parse from '../../lib/parse.js'; describe('parse.legacy', () => { it('should parse empty legacy blocks property', () => { @@ -29,4 +24,3 @@ describe('parse.legacy', () => { ); }); }); - diff --git a/packages/decl/test/parse/parse.test.js b/packages/decl/test/parse/parse.test.js index edf32fb4..d25ba820 100644 --- a/packages/decl/test/parse/parse.test.js +++ b/packages/decl/test/parse/parse.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyCell = require('../util').simplifyCell; -const parse = require('../../lib/parse'); +import { simplifyCell } from '../util.js'; +import parse from '../../lib/parse.js'; describe('decl.parse', () => { it('should throw if undefined', () => { diff --git a/packages/decl/test/save.test.js b/packages/decl/test/save.test.js index 9cb8deb5..625716c9 100644 --- a/packages/decl/test/save.test.js +++ b/packages/decl/test/save.test.js @@ -1,26 +1,21 @@ -'use strict'; - -const describe = require('mocha').describe; -const it = require('mocha').it; -const beforeEach = require('mocha').beforeEach; - -const expect = require('chai').expect; - -const sinon = require('sinon'); -const proxyquire = require('proxyquire'); +import { expect } from 'chai'; +import sinon from 'sinon'; +import esmock from 'esmock'; describe('save', () => { let context; - beforeEach(() => { + beforeEach(async () => { const stringifyStub = sinon.stub(); + const save = await esmock('../lib/save.js', { + '../lib/stringify.js': { default: stringifyStub }, + 'node:fs/promises': { writeFile: sinon.stub().resolves() } + }); + context = { stringifyStub: stringifyStub, - save: proxyquire('../lib/save', { - './stringify': stringifyStub, - fs: { writeFile: sinon.stub() } - }) + save: save.default || save }; }); diff --git a/packages/decl/test/stringify/enb.test.js b/packages/decl/test/stringify/enb.test.js index ec774a92..9c66ddc8 100644 --- a/packages/decl/test/stringify/enb.test.js +++ b/packages/decl/test/stringify/enb.test.js @@ -1,14 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemCell from '@bem/sdk.cell'; +import stringify from '../../lib/stringify.js'; -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); -const JSON5 = require('json5'); - -const stringify = require('../../lib/stringify'); +/** + * Simple JSON5-like output: unquoted keys where possible. + */ +function json5Stringify(obj, _replacer, space) { + return JSON.stringify(obj, null, space).replace(/"(\w+)":/g, '$1:'); +} const obj = { format: 'enb', @@ -24,19 +24,19 @@ describe('stringify.enb', () => { it('should stringify enb declaration with commonJS', () => { expect( stringify(cell, { format: 'enb', exportType: 'commonjs' }) - ).to.equal(`module.exports = ${JSON5.stringify(obj, null, 4)};\n`); + ).to.equal(`module.exports = ${json5Stringify(obj, null, 4)};\n`); }); it('should stringify enb declaration with es6', () => { expect( stringify(cell, { format: 'enb', exportType: 'es6' }) - ).to.equal(`export default ${JSON5.stringify(obj, null, 4)};\n`); + ).to.equal(`export default ${json5Stringify(obj, null, 4)};\n`); }); it('should stringify enb declaration with es2105', () => { expect( stringify(cell, { format: 'enb', exportType: 'es2015' }) - ).to.equal(`export default ${JSON5.stringify(obj, null, 4)};\n`); + ).to.equal(`export default ${json5Stringify(obj, null, 4)};\n`); }); it('should stringify enb declaration with JSON', () => { @@ -48,7 +48,7 @@ describe('stringify.enb', () => { it('should stringify enb declaration with JSON5', () => { expect( stringify(cell, { format: 'enb', exportType: 'json5' }) - ).to.equal(JSON5.stringify(obj, null, 4)); + ).to.equal(json5Stringify(obj, null, 4)); }); it('should stringify enb declaration with JSON if no exportType given', () => { diff --git a/packages/decl/test/stringify/errors.test.js b/packages/decl/test/stringify/errors.test.js index 32aed28b..0337fb69 100644 --- a/packages/decl/test/stringify/errors.test.js +++ b/packages/decl/test/stringify/errors.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); -const stringify = require('../../lib/stringify'); +import BemCell from '@bem/sdk.cell'; +import stringify from '../../lib/stringify.js'; const cell = BemCell.create({ block: 'block' }); diff --git a/packages/decl/test/subtract/disjoint.test.js b/packages/decl/test/subtract/disjoint.test.js index 3349e93b..3e05e927 100644 --- a/packages/decl/test/subtract/disjoint.test.js +++ b/packages/decl/test/subtract/disjoint.test.js @@ -1,14 +1,10 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); const createCell = BemCell.create; -const subtract = require('../../lib/subtract'); +import subtract from '../../lib/subtract.js'; describe('subtract.disjoint', () => { it('should not subtract other entities from block', () => { diff --git a/packages/decl/test/subtract/intersecting.test.js b/packages/decl/test/subtract/intersecting.test.js index e3a9c3e6..c1e99d67 100644 --- a/packages/decl/test/subtract/intersecting.test.js +++ b/packages/decl/test/subtract/intersecting.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const subtract = require('../../lib/subtract'); +import subtract from '../../lib/subtract.js'; describe('subtract.intersecting', () => { it('should subtract block from block', () => { diff --git a/packages/decl/test/subtract/sets.test.js b/packages/decl/test/subtract/sets.test.js index 1a04d08f..da34ce53 100644 --- a/packages/decl/test/subtract/sets.test.js +++ b/packages/decl/test/subtract/sets.test.js @@ -1,14 +1,10 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); const createCell = BemCell.create; -const subtract = require('../../lib/subtract'); +import subtract from '../../lib/subtract.js'; describe('subtract.sets', () => { it('should subtract set from empty set', () => { diff --git a/packages/decl/test/util.js b/packages/decl/test/util.js index d48c9300..c720dd40 100644 --- a/packages/decl/test/util.js +++ b/packages/decl/test/util.js @@ -1,10 +1,8 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; -const BemCell = require('@bem/sdk.cell'); +export const createCell = BemCell.create; -exports.createCell = BemCell.create; - -exports.simplifyCell = function (cell) { +export const simplifyCell = function (cell) { const entity = { block: cell.entity.block }; cell.entity.elem && (entity.elem = cell.entity.elem); if (cell.entity.mod) { diff --git a/packages/deps/lib/buildGraph.js b/packages/deps/lib/buildGraph.js index 7678e22f..9eda9b62 100644 --- a/packages/deps/lib/buildGraph.js +++ b/packages/deps/lib/buildGraph.js @@ -1,6 +1,4 @@ -'use strict'; - -const BemGraph = require('@bem/sdk.graph').BemGraph; +import { BemGraph } from '@bem/sdk.graph'; /** * A BEM-entity with or without a tech @@ -12,7 +10,7 @@ const BemGraph = require('@bem/sdk.graph').BemGraph; * @param {?{denaturalized: Boolean}} options * @returns {BemGraph} */ -module.exports = function buildGraph(deps, options) { +export default function buildGraph(deps, options) { options || (options = {}); const graph = new BemGraph(); @@ -30,4 +28,4 @@ module.exports = function buildGraph(deps, options) { options.denaturalized || graph.naturalize(); return graph; -}; +} diff --git a/packages/deps/lib/formats/deps.js/index.js b/packages/deps/lib/formats/deps.js/index.js index 129e1327..ac4ba2ea 100644 --- a/packages/deps/lib/formats/deps.js/index.js +++ b/packages/deps/lib/formats/deps.js/index.js @@ -1,6 +1,4 @@ -'use strict'; +import reader from './reader.js'; +import parser from './parser.js'; -const reader = require('./reader'); -const parser = require('./parser'); - -module.exports = { parser, reader }; +export default { parser, reader }; diff --git a/packages/deps/lib/formats/deps.js/parser.js b/packages/deps/lib/formats/deps.js/parser.js index afc79b29..463b8f07 100644 --- a/packages/deps/lib/formats/deps.js/parser.js +++ b/packages/deps/lib/formats/deps.js/parser.js @@ -1,7 +1,7 @@ -'use strict'; +import { debuglog } from 'node:util'; +import decl from '@bem/sdk.decl'; -const debug = require('debug')('@bem/sdk.deps'); -const decl = require('@bem/sdk.decl'); +const debug = debuglog('bem_sdk_deps'); /** * @typedef {Object} DepsData @@ -35,7 +35,7 @@ const decl = require('@bem/sdk.decl'); * @param {(Array|DepsData)} depsData - List of deps * @returns {Array} */ -module.exports = function parse(depsData) { +export default function parse(depsData) { const mustDeps = []; const shouldDeps = []; const mustDepsIndex = {}; @@ -60,7 +60,7 @@ module.exports = function parse(depsData) { decl.normalize(dep.mustDeps, {format: 'v2', scope: subscope}).forEach(function (nd) { nd = decl.assign(nd, subscope); const key = nd.id; - const indexKey = subscopeKey + '→' + key; + const indexKey = subscopeKey + '\u2192' + key; if (!mustDepsIndex[indexKey]) { subscopeKey === key || mustDeps.push({ vertex: subscope, dependOn: nd, ordered: true, path: record.path }); @@ -71,7 +71,7 @@ module.exports = function parse(depsData) { if (dep.shouldDeps) { decl.normalize(dep.shouldDeps, {format: 'v2', scope: subscope}).forEach(function (nd) { const key = nd.id; - const indexKey = subscopeKey + '→' + key; + const indexKey = subscopeKey + '\u2192' + key; if (!shouldDepsIndex[indexKey]) { subscopeKey === key || shouldDeps.push({ vertex: subscope, dependOn: nd, path: record.path }); @@ -82,7 +82,7 @@ module.exports = function parse(depsData) { if (dep.noDeps) { decl.normalize(dep.noDeps, {format: 'v2', scope: subscope}).forEach(function (nd) { const key = nd.id; - const indexKey = subscopeKey + '→' + key; + const indexKey = subscopeKey + '\u2192' + key; removeFromDeps(key, indexKey, mustDepsIndex, mustDeps); removeFromDeps(key, indexKey, shouldDepsIndex, shouldDeps); }); @@ -107,8 +107,8 @@ module.exports = function parse(depsData) { return null; } - debug.enabled && debug('parsed-deps: ', mustDeps.concat(shouldDeps) + debug('parsed-deps: ', mustDeps.concat(shouldDeps) .map(v => `${v.vertex.id} ${v.ordered ? '=>' : '->'} ${v.dependOn.id} : ${v.path}`)); return mustDeps.concat(shouldDeps); -}; +} diff --git a/packages/deps/lib/formats/deps.js/reader.js b/packages/deps/lib/formats/deps.js/reader.js index 4d47330e..8a56e705 100644 --- a/packages/deps/lib/formats/deps.js/reader.js +++ b/packages/deps/lib/formats/deps.js/reader.js @@ -1,7 +1,20 @@ -'use strict'; +import { readFile } from 'node:fs/promises'; +import vm from 'node:vm'; -const fsp = require('mz/fs'); -const _eval = require('node-eval'); +/** + * Evaluates BEM deps file content. + * BEM deps files use `module.exports` to export deps data. + * + * @param {string} code - File content to evaluate + * @param {string} filename - Original file path (for error messages) + * @returns {*} Evaluated module exports + */ +function nodeEval(code, filename) { + const m = { exports: {} }; + const wrapped = `(function(module, exports, require) { ${code}\n})(m, m.exports, () => {})`; + vm.runInNewContext(wrapped, { m }, { filename }); + return m.exports; +} /** * Reads and evaluates BemFiles. @@ -9,9 +22,9 @@ const _eval = require('node-eval'); * @param {BemFile} f - file data to read * @returns {Promise<{file: BemFile, data: *, scope: BemEntityName}>} */ -module.exports = function read(f) { - return fsp.readFile(f.path, 'utf8') +export default function read(f) { + return readFile(f.path, 'utf8') .then(content => Object.assign(f, { - data: _eval(content, f.path) + data: nodeEval(content, f.path) })); -}; +} diff --git a/packages/deps/lib/gather.js b/packages/deps/lib/gather.js index df4dde85..6b360563 100644 --- a/packages/deps/lib/gather.js +++ b/packages/deps/lib/gather.js @@ -1,17 +1,15 @@ -'use strict'; +import assert from 'node:assert'; +import fs from 'node:fs'; -const assert = require('assert'); -const fs = require('fs'); - -const Config = require('@bem/sdk.config'); -const walk = require('@bem/sdk.walk'); +import Config from '@bem/sdk.config'; +import walk from '@bem/sdk.walk'; /** * Gathering deps.js files with bem-walk * @param {BemConfig} config * @returns {Promise>} */ -module.exports = async function ({ platform = 'desktop', defaults = {}, config }) { +export default async function ({ platform = 'desktop', defaults = {}, config }) { config || (config = Config()); assert(!Array.isArray(config.levels), 'Missing description of levels in the configuration.'); @@ -21,7 +19,7 @@ module.exports = async function ({ platform = 'desktop', defaults = {}, config } config.levelMap(), ]); - return new Promise(async (resolve, reject) => { + return new Promise((resolve, reject) => { const walker = walk(levels.map(l => l.path || l), { levels: levelMap, defaults }); const res = []; let filesCount = 1; @@ -53,4 +51,4 @@ module.exports = async function ({ platform = 'desktop', defaults = {}, config } .on('error', reject) .on('end', resolveIfPossible); }); -}; +} diff --git a/packages/deps/lib/index.js b/packages/deps/lib/index.js index eaee69f4..d9236aab 100644 --- a/packages/deps/lib/index.js +++ b/packages/deps/lib/index.js @@ -1,10 +1,8 @@ -'use strict'; +import read from './read.js'; +import parse from './parse.js'; +import load from './load.js'; +import gather from './gather.js'; +import resolve from './resolve.js'; +import buildGraph from './buildGraph.js'; -const read = require('./read'); -const parse = require('./parse'); -const load = require('./load'); -const gather = require('./gather'); -const resolve = require('./resolve'); -const buildGraph = require('./buildGraph'); - -module.exports = { load, read, parse, gather, resolve, buildGraph }; +export { load, read, parse, gather, resolve, buildGraph }; diff --git a/packages/deps/lib/load.js b/packages/deps/lib/load.js index e6d3fe7a..5c782940 100644 --- a/packages/deps/lib/load.js +++ b/packages/deps/lib/load.js @@ -1,14 +1,12 @@ -'use strict'; +import read from './read.js'; +import parse from './parse.js'; +import gather from './gather.js'; +import defaultFormat from './formats/deps.js/index.js'; -const read = require('./read'); -const parse = require('./parse'); -const gather = require('./gather'); -const defaultFormat = require('./formats/deps.js'); - -module.exports = function (config, format) { +export default function (config, format) { format || (format = defaultFormat); return gather(config) .then(read(format.reader)) .then(parse(format.parser)); -}; +} diff --git a/packages/deps/lib/parse.js b/packages/deps/lib/parse.js index 14eb077e..59ae24fb 100644 --- a/packages/deps/lib/parse.js +++ b/packages/deps/lib/parse.js @@ -1,8 +1,6 @@ -'use strict'; +import defaultParser from './formats/deps.js/parser.js'; -const defaultParser = require('./formats/deps.js/parser'); - -module.exports = function parse(parser) { +export default function parse(parser) { parser || (parser = defaultParser); return function (deps) { @@ -12,4 +10,4 @@ module.exports = function parse(parser) { } ); }; -}; +} diff --git a/packages/deps/lib/read.js b/packages/deps/lib/read.js index 8bcf6fe4..88b6eead 100644 --- a/packages/deps/lib/read.js +++ b/packages/deps/lib/read.js @@ -1,6 +1,4 @@ -'use strict'; - -const defaultReader = require('./formats/deps.js/reader'); +import defaultReader from './formats/deps.js/reader.js'; /** * Generic serial reader generator @@ -8,7 +6,7 @@ const defaultReader = require('./formats/deps.js/reader'); * @param {function(f: BemFile): Promise<{file: BemFile, data: *, scope: BemEntityName}>} reader - Reads and evaluates BemFiles. * @returns {Function} */ -module.exports = function read(reader) { +export default function read(reader) { reader || (reader = defaultReader); /** @@ -36,4 +34,4 @@ module.exports = function read(reader) { .catch(reject); }); }; -}; +} diff --git a/packages/deps/lib/resolve.js b/packages/deps/lib/resolve.js index ab8bbc2d..7ba418a1 100644 --- a/packages/deps/lib/resolve.js +++ b/packages/deps/lib/resolve.js @@ -1,6 +1,4 @@ -'use strict'; - -const buildGraph = require('./buildGraph'); +import buildGraph from './buildGraph.js'; /** * @param {BemEntityName[]} declaration @@ -8,7 +6,7 @@ const buildGraph = require('./buildGraph'); * @param {{tech: ?String}} options * @returns {Array<{entity: BemEntityName, tech: String}>} */ -module.exports = function (declaration, relations, options) { +export default function (declaration, relations, options) { declaration || (declaration = []); relations || (relations = []); options || (options = {}); @@ -33,4 +31,4 @@ module.exports = function (declaration, relations, options) { return res; }, []) }; -}; +} diff --git a/packages/deps/package.json b/packages/deps/package.json index 6fe78e16..39ff5fa9 100644 --- a/packages/deps/package.json +++ b/packages/deps/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.deps", "version": "0.3.1", "description": "Manage BEM dependencies", + "type": "module", "publishConfig": { "access": "public" }, @@ -22,7 +23,7 @@ }, "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/deps#readme", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "lib/index.js", "files": [ @@ -33,18 +34,10 @@ "@bem/sdk.decl": "^0.3.10", "@bem/sdk.entity-name": "^0.2.11", "@bem/sdk.graph": "^0.3.3", - "@bem/sdk.walk": "^0.6.0", - "debug": "2.6.9", - "mz": "2.4.0", - "node-eval": "1.1.0" - }, - "devDependencies": { - "stream-to-array": "^2.3.0", - "through2": "^2.0.1" + "@bem/sdk.walk": "^0.6.0" }, "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" } } diff --git a/packages/deps/test/formats/deps.js/parser.test.js b/packages/deps/test/formats/deps.js/parser.test.js index 904c0b3c..322c748a 100644 --- a/packages/deps/test/formats/deps.js/parser.test.js +++ b/packages/deps/test/formats/deps.js/parser.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const parser = require('../../../lib/formats/deps.js/parser'); +import parser from '../../../lib/formats/deps.js/parser.js'; const key = (v) => `${v.entity.id}${v.tech ? '.' + v.tech : ''}`; const parse = (z) => { diff --git a/packages/deps/test/gather.test.js b/packages/deps/test/gather.test.js index e5a4d42d..21739985 100644 --- a/packages/deps/test/gather.test.js +++ b/packages/deps/test/gather.test.js @@ -1,14 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mock from 'mock-fs'; -const expect = require('chai').expect; - -const mock = require('mock-fs'); - -const gather = require('..').gather; +import { gather } from '../lib/index.js'; describe('gather', () => { afterEach(() => { diff --git a/packages/deps/test/mocha.opts b/packages/deps/test/mocha.opts deleted file mode 100644 index 4a523201..00000000 --- a/packages/deps/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---recursive diff --git a/packages/deps/test/resolve.test.js b/packages/deps/test/resolve.test.js index 6cf8b7a8..1d11db0f 100644 --- a/packages/deps/test/resolve.test.js +++ b/packages/deps/test/resolve.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const resolve = require('..').resolve; +import { resolve } from '../lib/index.js'; describe('resolve', () => { it('should return result containing entities and dependOn sections', () => { diff --git a/packages/entity-name/.mocharc.yml b/packages/entity-name/.mocharc.yml new file mode 100644 index 00000000..83e03282 --- /dev/null +++ b/packages/entity-name/.mocharc.yml @@ -0,0 +1,2 @@ +require: test/setup.js +recursive: true diff --git a/packages/entity-name/index.d.ts b/packages/entity-name/index.d.ts index 0de6794a..19c5207f 100644 --- a/packages/entity-name/index.d.ts +++ b/packages/entity-name/index.d.ts @@ -1,117 +1,113 @@ -declare module '@bem/sdk.entity-name' { - export default class BemEntityName { - constructor(obj: EntityName.IOptions); +/** + * Types of BEM entities. + */ +export type Type = 'block' | 'blockMod' | 'elem' | 'elemMod'; +export type BlockName = string; +export type ElementName = string; +export type ModifierName = string; +export type ModifierValue = string | boolean; +export type Id = string; - readonly block: EntityName.BlockName; - readonly elem: EntityName.ElementName | undefined; - readonly mod: EntityName.IModifier | undefined; - readonly modName: EntityName.ModifierName | undefined; - readonly modVal: EntityName.ModifierValue | undefined; - readonly type: EntityName.Type; - readonly scope: BemEntityName | null; - readonly id: EntityName.Id; +/** + * Abstract object to represent entity name + */ +interface IAbstractRepresentation { + /** + * The block name of entity. + */ + block: BlockName; + /** + * The element name of entity. + */ + elem?: ElementName; + mod?: any; +} - isSimpleMod(): boolean | null; - isEqual(entityName: BemEntityName): boolean; - belongsTo(entityName: BemEntityName): boolean; - valueOf(): EntityName.IRepresentation; - toJSON(): EntityName.IRepresentation; - toString(): string; - inspect(depth: number, options: object): string; +/** + * Object to represent modifier of entity name. + */ +export interface IModifier { + /** + * The modifier name of entity. + */ + name: ModifierName; + /** + * The modifier value of entity. + */ + val: ModifierValue; +} - static create(obj: EntityName.ICreateOptions | string): BemEntityName; - static isBemEntityName(entityName: any): boolean; - } +/** + * Strict object to represent entity name. + */ +export interface IRepresentation extends IAbstractRepresentation { + /** + * The modifier of entity. + */ + mod?: IModifier; +} - export namespace EntityName { +/** + * Object to create representation of entity name. + */ +export interface IOptions extends IAbstractRepresentation { + /** + * The modifier of entity. + */ + mod?: ModifierName | { /** - * Types of BEM entities. + * The modifier name of entity. */ - export type Type = 'block' | 'blockMod' | 'elem' | 'elemMod'; - export type BlockName = string; - export type ElementName = string; - export type ModifierName = string; - export type ModifierValue = string | boolean; - export type Id = string; - + name: ModifierName; /** - * Abstract object to represent entity name + * The modifier value of entity. */ - interface IAbstractRepresentation { - /** - * The block name of entity. - */ - block: BlockName; - /** - * The element name of entity. - */ - elem?: ElementName; - mod?: any; - } + val?: ModifierValue; + }; + /** + * The modifier name of entity. Used if `mod.name` wasn't specified. + * @deprecated use `mod.name` instead. + */ + modName?: ModifierName; + /** + * The modifier value of entity. Used if neither `mod.val` nor `val` were not specified. + * @deprecated use `mod.name` instead. + */ + modVal?: ModifierValue; +} - /** - * Object to represent modifier of entity name. - */ - export interface IModifier { - /** - * The modifier name of entity. - */ - name: ModifierName; - /** - * The modifier value of entity. - */ - val: ModifierValue; - } +/** + * Object to create representation of entity name with `create` method. + * + * Contains old field: `val`, `modName` and `modVal. + */ +export interface ICreateOptions extends IOptions { + /** + * The modifier value of entity. Used if neither `mod.val` were not specified. + */ + val?: ModifierValue; +} - /** - * Strict object to represent entity name. - */ - export interface IRepresentation extends IAbstractRepresentation { - /** - * The modifier of entity. - */ - mod?: IModifier; - } +export default class BemEntityName { + constructor(obj: IOptions); - /** - * Object to create representation of entity name. - */ - export interface IOptions extends IAbstractRepresentation { - /** - * The modifier of entity. - */ - mod?: ModifierName | { - /** - * The modifier name of entity. - */ - name: ModifierName; - /** - * The modifier value of entity. - */ - val?: ModifierValue; - }; - /** - * The modifier name of entity. Used if `mod.name` wasn't specified. - * @deprecated use `mod.name` instead. - */ - modName?: ModifierName; - /** - * The modifier value of entity. Used if neither `mod.val` nor `val` were not specified. - * @deprecated use `mod.name` instead. - */ - modVal?: ModifierValue; - } + readonly block: BlockName; + readonly elem: ElementName | undefined; + readonly mod: IModifier | undefined; + readonly modName: ModifierName | undefined; + readonly modVal: ModifierValue | undefined; + readonly type: Type; + readonly scope: BemEntityName | null; + readonly id: Id; - /** - * Object to create representation of entity name with `create` method. - * - * Contains old field: `val`, `modName` and `modVal. - */ - export interface ICreateOptions extends IOptions { - /** - * The modifier value of entity. Used if neither `mod.val` were not specified. - */ - val?: ModifierValue; - } - } + isSimpleMod(): boolean | null; + isEqual(entityName: BemEntityName): boolean; + belongsTo(entityName: BemEntityName): boolean; + valueOf(): IRepresentation; + toJSON(): IRepresentation; + toString(): string; + inspect(depth: number, options: object): string; + + static create(obj: ICreateOptions | string): BemEntityName; + static isBemEntityName(entityName: any): boolean; } diff --git a/packages/entity-name/index.js b/packages/entity-name/index.js index f3d1a284..e9495c85 100644 --- a/packages/entity-name/index.js +++ b/packages/entity-name/index.js @@ -1,3 +1 @@ -'use strict'; - -module.exports = require('./lib/entity-name'); +export { default } from './lib/entity-name.js'; diff --git a/packages/entity-name/lib/deprecate.js b/packages/entity-name/lib/deprecate.js index 811de91e..662e4661 100644 --- a/packages/entity-name/lib/deprecate.js +++ b/packages/entity-name/lib/deprecate.js @@ -1,8 +1,6 @@ -'use strict'; +import { inspect } from 'node:util'; -const util = require('util'); - -const deprecate = require('depd')('@bem/sdk.entity-name'); +const warned = new Set(); /** * Logs deprecation messages. @@ -11,12 +9,17 @@ const deprecate = require('depd')('@bem/sdk.entity-name'); * @param {string} deprecateName * @param {string} newName */ -module.exports = (obj, deprecateName, newName) => { - const objStr = util.inspect(obj, { depth: 1 }); +const deprecate = (obj, deprecateName, newName) => { + const objStr = inspect(obj, { depth: 1 }); const message = [ `\`${deprecateName}\` is kept just for compatibility and can be dropped in the future.`, `Use \`${newName}\` instead in \`${objStr}\` at` ].join(' '); - deprecate(message); + if (!warned.has(message)) { + warned.add(message); + process.emitWarning(message, 'DeprecationWarning'); + } }; + +export default deprecate; diff --git a/packages/entity-name/lib/entity-name.js b/packages/entity-name/lib/entity-name.js index 0e5a43b3..e21a2f82 100644 --- a/packages/entity-name/lib/entity-name.js +++ b/packages/entity-name/lib/entity-name.js @@ -1,12 +1,12 @@ -'use strict'; +import { inspect } from 'node:util'; -const util = require('util'); +import originNaming from '@bem/sdk.naming.presets/origin.js'; +import createStringify from '@bem/sdk.naming.entity.stringify'; -const originNaming = require('@bem/sdk.naming.presets/origin'); -const stringifyEntity = require('@bem/sdk.naming.entity.stringify')(originNaming); +import deprecate from './deprecate.js'; +import EntityTypeError from './entity-type-error.js'; -const deprecate = require('./deprecate'); -const EntityTypeError = require('./entity-type-error'); +const stringifyEntity = createStringify(originNaming); /** * Enum for types of BEM entities. @@ -48,7 +48,7 @@ class BemEntityName { const modObj = obj.mod; const modName = (typeof modObj === 'string' ? modObj : modObj && modObj.name) || !isBemEntityName && obj.modName; - const hasModVal = modObj && modObj.hasOwnProperty('val') || obj.hasOwnProperty('modVal'); + const hasModVal = modObj && Object.hasOwn(modObj, 'val') || Object.hasOwn(obj, 'modVal'); if (modName) { const normalizeValue = v => v === 0 ? '0' : v; @@ -68,7 +68,7 @@ class BemEntityName { * Returns the name of block to which this entity belongs. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button' }); * * name.block; // button @@ -83,7 +83,7 @@ class BemEntityName { * If entity is not element or modifier of element then returns empty string. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', elem: 'text' }); * * name.elem; // text @@ -98,7 +98,7 @@ class BemEntityName { * Important: If entity is not a modifier then returns `undefined`. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * const blockName = new BemEntityName({ block: 'button' }); * const modName = new BemEntityName({ block: 'button', mod: 'disabled' }); @@ -142,13 +142,13 @@ class BemEntityName { * Returns type for this entity. * * @example type of element - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', elem: 'text' }); * * name.type; // elem * * @example type of element modifier - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'menu', elem: 'item', mod: 'current' }); * * name.type; // elemMod @@ -174,7 +174,7 @@ class BemEntityName { * Important: block-typed entities has no scope. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * const buttonName = new BemEntityName({ block: 'button' }); * const buttonTextName = new BemEntityName({ block: 'button', elem: 'text' }); @@ -207,7 +207,7 @@ class BemEntityName { * you should use `@bem/naming` package. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', mod: 'disabled' }); * * name.id; // button_disabled @@ -226,19 +226,19 @@ class BemEntityName { * Determines whether modifier simple or not * * @example simple mod - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', mod: { name: 'theme' } }); * * name.isSimpleMod(); // true * * @example mod with value - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', mod: { name: 'theme', val: 'normal' } }); * * name.isSimpleMod(); // false * * @example block - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button' }); * * name.isSimpleMod(); // null @@ -253,7 +253,7 @@ class BemEntityName { * Determines whether specified entity is the deepEqual entity. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * const inputName = new BemEntityName({ block: 'input' }); * const buttonName = new BemEntityName({ block: 'button' }); @@ -272,7 +272,7 @@ class BemEntityName { * Determines whether specified entity belongs to this. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * const buttonName = new BemEntityName({ block: 'button' }); * const buttonTextName = new BemEntityName({ block: 'button', elem: 'text' }); @@ -305,12 +305,12 @@ class BemEntityName { * without private and deprecated fields (`modName` and `modVal`). * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', mod: 'focused' }); * * name.valueOf(); * - * // ➜ { block: 'button', mod: { name: 'focused', value: true } } + * // -> { block: 'button', mod: { name: 'focused', value: true } } * * @returns {BEMSDK.EntityName.Representation} */ @@ -320,7 +320,7 @@ class BemEntityName { * Returns raw data for `JSON.stringify()` purposes. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * const name = new BemEntityName({ block: 'input', mod: 'available' }); * @@ -339,7 +339,7 @@ class BemEntityName { * you should use `@bem/naming` package. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button', mod: 'focused' }); * * name.toString(); // button_focused @@ -358,7 +358,7 @@ class BemEntityName { * without private and deprecated fields (`modName` and `modVal`). * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * const name = new BemEntityName({ block: 'button' }); * * console.log(name); // BemEntityName { block: 'button' } @@ -369,8 +369,8 @@ class BemEntityName { * * @returns {string} */ - inspect(depth, options) { - const stringRepresentation = util.inspect(this._data, options); + [Symbol.for('nodejs.util.inspect.custom')](depth, options) { + const stringRepresentation = inspect(this._data, options); return `BemEntityName ${stringRepresentation}`; } @@ -379,11 +379,11 @@ class BemEntityName { * Creates BemEntityName instance by any object representation. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * BemEntityName.create({ block: 'my-button', mod: 'theme', val: 'red' }); * BemEntityName.create({ block: 'my-button', modName: 'theme', modVal: 'red' }); - * // → BemEntityName { block: 'my-button', mod: { name: 'theme', val: 'red' } } + * // -> BemEntityName { block: 'my-button', mod: { name: 'theme', val: 'red' } } * * @param {(BEMSDK.EntityName.CreateOptions|string)} obj — representation of entity name. * @returns {BemEntityName} An object representing entity name. @@ -422,7 +422,7 @@ class BemEntityName { * Determines whether specified entity is instance of BemEntityName. * * @example - * const BemEntityName = require('@bem/sdk.entity-name'); + * import BemEntityName from '@bem/sdk.entity-name'; * * const entityName = new BemEntityName({ block: 'input' }); * @@ -438,9 +438,4 @@ class BemEntityName { } } -module.exports = BemEntityName; - -// TypeScript imports the `default` property for -// an ES2015 default import (`import BemEntityName from '@bem/sdk.entity-name'`) -// See: https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-83694181 -module.exports.default = BemEntityName; +export default BemEntityName; diff --git a/packages/entity-name/lib/entity-type-error.js b/packages/entity-name/lib/entity-type-error.js index a50755d0..091204c5 100644 --- a/packages/entity-name/lib/entity-type-error.js +++ b/packages/entity-name/lib/entity-type-error.js @@ -1,22 +1,21 @@ -'use strict'; - -const util = require('util'); - -const ExtendableError = require('es6-error'); +import { inspect } from 'node:util'; /** * The EntityTypeError object represents an error when a value is not valid BEM entity. */ -module.exports = class EntityTypeError extends ExtendableError { +class EntityTypeError extends Error { /** * @param {*} obj — not valid object * @param {string} [reason] — human-readable reason why object is not valid */ constructor(obj, reason) { - const str = util.inspect(obj, { depth: 1 }); + const str = inspect(obj, { depth: 1 }); const type = obj ? typeof obj : ''; const message = `the ${type} \`${str}\` is not valid BEM entity`; super(reason ? `${message}, ${reason}` : message); + this.name = this.constructor.name; } -}; +} + +export default EntityTypeError; diff --git a/packages/entity-name/package.json b/packages/entity-name/package.json index a6b1b2a4..5d657de5 100644 --- a/packages/entity-name/package.json +++ b/packages/entity-name/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.entity-name", "version": "0.2.11", "description": "BEM entity name representation", + "type": "module", "publishConfig": { "access": "public" }, @@ -36,25 +37,14 @@ "index.d.ts" ], "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "dependencies": { "@bem/sdk.naming.entity.stringify": "^1.1.2", - "@bem/sdk.naming.presets": "^0.0.9", - "depd": "1.1.0", - "es6-error": "4.0.2" + "@bem/sdk.naming.presets": "^0.2.3" }, - "devDependencies": { - "@types/node": "^8.0" - }, - "scripts": { +"scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" - }, - "greenkeeper": { - "ignore": [ - "@types/node" - ] } } diff --git a/packages/entity-name/test/belongs-to.test.js b/packages/entity-name/test/belongs-to.test.js index 2c0a679c..b296df00 100644 --- a/packages/entity-name/test/belongs-to.test.js +++ b/packages/entity-name/test/belongs-to.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('belongs-to', () => { it('should not detect belonging between block and itself', () => { diff --git a/packages/entity-name/test/bem-fields.test.js b/packages/entity-name/test/bem-fields.test.js index 99dcb396..4b5e42b7 100644 --- a/packages/entity-name/test/bem-fields.test.js +++ b/packages/entity-name/test/bem-fields.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('bem-fields', () => { it('should provide `block` field', () => { diff --git a/packages/entity-name/test/constructor/constructor.test.js b/packages/entity-name/test/constructor/constructor.test.js index 0aa4dcc0..33b58dfc 100644 --- a/packages/entity-name/test/constructor/constructor.test.js +++ b/packages/entity-name/test/constructor/constructor.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('../..'); +import BemEntityName from '../../index.js'; describe('constructor/constructor', () => { it('should create block', () => { diff --git a/packages/entity-name/test/constructor/errors.test.js b/packages/entity-name/test/constructor/errors.test.js index 04950223..e7a56187 100644 --- a/packages/entity-name/test/constructor/errors.test.js +++ b/packages/entity-name/test/constructor/errors.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('../..'); +import BemEntityName from '../../index.js'; describe('constructor/errors', () => { it('should throw error if not `block` field', () => { diff --git a/packages/entity-name/test/constructor/normalize.test.js b/packages/entity-name/test/constructor/normalize.test.js index 1c5968b6..43a6bd53 100644 --- a/packages/entity-name/test/constructor/normalize.test.js +++ b/packages/entity-name/test/constructor/normalize.test.js @@ -1,20 +1,16 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '../../index.js'; -const expect = require('chai').expect; - -const BemEntityName = require('../..'); const noop = () => {}; describe('constructor/normalize.test.js', () => { beforeEach(() => { - process.on('deprecation', noop); + process.on('warning', noop); }); afterEach(() => { - process.removeListener('deprecation', noop); + process.removeListener('warning', noop); }); it('should normalize simple modifier', () => { diff --git a/packages/entity-name/test/create.test.js b/packages/entity-name/test/create.test.js index bc62f82c..097559f9 100644 --- a/packages/entity-name/test/create.test.js +++ b/packages/entity-name/test/create.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('create', () => { it('should return object as is if it`s a BemEntityName', () => { diff --git a/packages/entity-name/test/deprecate.test.js b/packages/entity-name/test/deprecate.test.js index 5dc7aaa0..3fe2a793 100644 --- a/packages/entity-name/test/deprecate.test.js +++ b/packages/entity-name/test/deprecate.test.js @@ -1,21 +1,24 @@ -'use strict'; +import { expect } from 'chai'; +import sinon from 'sinon'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '../index.js'; -const expect = require('chai').expect; -const sinon = require('sinon'); -const proxyquire = require('proxyquire'); +describe('deprecate', () => { + let emitWarningSpy; -const BemEntityName = require('..'); + beforeEach(async () => { + emitWarningSpy = sinon.spy(process, 'emitWarning'); + }); -const deprecateSpy = sinon.spy(); -const deprecate = proxyquire('../lib/deprecate', { - 'depd':() => deprecateSpy -}); + afterEach(() => { + emitWarningSpy.restore(); + }); + + it('should deprecate object', async () => { + // Import a fresh deprecate module via esmock to reset its internal Set + const esmock = (await import('esmock')).default; + const { default: deprecate } = await esmock('../lib/deprecate.js', {}); -describe('deprecate', () => { - it('should deprecate object', () => { deprecate({ block: 'block' }, 'oldField', 'newField'); const message = [ @@ -23,10 +26,13 @@ describe('deprecate', () => { "Use `newField` instead in `{ block: 'block' }` at" ].join(' '); - expect(deprecateSpy.calledWith(message)).to.be.true; + expect(emitWarningSpy.calledWith(message, 'DeprecationWarning')).to.be.true; }); - it('should deprecate BemEntityName instance', () => { + it('should deprecate BemEntityName instance', async () => { + const esmock = (await import('esmock')).default; + const { default: deprecate } = await esmock('../lib/deprecate.js', {}); + deprecate(new BemEntityName({ block: 'block' }), 'oldField', 'newField'); const message = [ @@ -34,6 +40,6 @@ describe('deprecate', () => { "Use `newField` instead in `BemEntityName { block: 'block' }` at" ].join(' '); - expect(deprecateSpy.calledWith(message)).to.be.true; + expect(emitWarningSpy.calledWith(message, 'DeprecationWarning')).to.be.true; }); }); diff --git a/packages/entity-name/test/entity-type-error.test.js b/packages/entity-name/test/entity-type-error.test.js index 5cefbec8..5fbb83cb 100644 --- a/packages/entity-name/test/entity-type-error.test.js +++ b/packages/entity-name/test/entity-type-error.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const EntityTypeError = require('../lib/entity-type-error'); +import EntityTypeError from '../lib/entity-type-error.js'; describe('entity-type-error', () => { it('should create type error', () => { diff --git a/packages/entity-name/test/id.test.js b/packages/entity-name/test/id.test.js index 439e0a88..4a798374 100644 --- a/packages/entity-name/test/id.test.js +++ b/packages/entity-name/test/id.test.js @@ -1,13 +1,8 @@ -'use strict'; +import { expect } from 'chai'; +import sinon from 'sinon'; +import esmock from 'esmock'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; -const sinon = require('sinon'); -const proxyquire = require('proxyquire'); - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('id', () => { it('should build equal id for equal blocks', () => { @@ -24,11 +19,11 @@ describe('id', () => { expect(entityName1.id).is.not.equal(entityName2.id); }); - it('should cache id value', () => { + it('should cache id value', async () => { const stub = sinon.stub().returns('id'); - const StubBemEntityName = proxyquire('../lib/entity-name', { - '@bem/sdk.naming.entity.stringify': () => stub - }); + const StubBemEntityName = (await esmock('../lib/entity-name.js', { + '@bem/sdk.naming.entity.stringify': { default: () => stub } + })).default; const entityName = new StubBemEntityName({ block: 'block' }); diff --git a/packages/entity-name/test/inspect.test.js b/packages/entity-name/test/inspect.test.js index c8786de2..ed16aa5a 100644 --- a/packages/entity-name/test/inspect.test.js +++ b/packages/entity-name/test/inspect.test.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; +import { inspect } from 'node:util'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const inspect = require('util').inspect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('inspect.test.js', () => { it('should return entity object', () => { diff --git a/packages/entity-name/test/is-bem-entity-name.test.js b/packages/entity-name/test/is-bem-entity-name.test.js index 31f7a1b1..ad8ea2d9 100644 --- a/packages/entity-name/test/is-bem-entity-name.test.js +++ b/packages/entity-name/test/is-bem-entity-name.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('is-bem-entity-name', () => { it('should check valid entities', () => { diff --git a/packages/entity-name/test/is-equal.test.js b/packages/entity-name/test/is-equal.test.js index cf2a4644..717e4826 100644 --- a/packages/entity-name/test/is-equal.test.js +++ b/packages/entity-name/test/is-equal.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('is-equal', () => { it('should detect equal block', () => { diff --git a/packages/entity-name/test/is-simple-mod.test.js b/packages/entity-name/test/is-simple-mod.test.js index c37dccd8..cdf8cd76 100644 --- a/packages/entity-name/test/is-simple-mod.test.js +++ b/packages/entity-name/test/is-simple-mod.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('is-simple-mod', () => { it('should be true for simple modifiers', () => { diff --git a/packages/entity-name/test/mocha.opts b/packages/entity-name/test/mocha.opts deleted file mode 100644 index 0d6c0257..00000000 --- a/packages/entity-name/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---require test/setup --recursive diff --git a/packages/entity-name/test/modules.test.js b/packages/entity-name/test/modules.test.js index 11a29f60..a79e68d3 100644 --- a/packages/entity-name/test/modules.test.js +++ b/packages/entity-name/test/modules.test.js @@ -1,14 +1,10 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('modules', () => { - it('should export to default', () => { - expect(BemEntityName).to.equal(BemEntityName.default); + it('should export default', () => { + expect(BemEntityName).to.be.a('function'); + expect(BemEntityName.name).to.equal('BemEntityName'); }); }); diff --git a/packages/entity-name/test/scope.test.js b/packages/entity-name/test/scope.test.js index 1e71d65c..9a5aa0a8 100644 --- a/packages/entity-name/test/scope.test.js +++ b/packages/entity-name/test/scope.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('scope', () => { it('should return scope of block', () => { @@ -42,7 +37,7 @@ describe('scope', () => { it('should cache scope value', () => { const entity = new BemEntityName({ block: 'block', elem: 'elem' }); - entity.scope; // eslint-disable-line no-unused-expressions + entity.scope; expect(entity._scope.valueOf()).to.deep.equal({ block: 'block' }); }); diff --git a/packages/entity-name/test/setup.js b/packages/entity-name/test/setup.js index 2aa82fe3..0e81ad52 100644 --- a/packages/entity-name/test/setup.js +++ b/packages/entity-name/test/setup.js @@ -1,4 +1,4 @@ -'use strict'; - -// To silence deprecation warnings from being output -process.env.NO_DEPRECATION = '@bem/sdk.entity-name'; +// Silence DeprecationWarning during tests +process.on('warning', (warning) => { + if (warning.name === 'DeprecationWarning') return; +}); diff --git a/packages/entity-name/test/to-json.test.js b/packages/entity-name/test/to-json.test.js index 3181427c..31a7303a 100644 --- a/packages/entity-name/test/to-json.test.js +++ b/packages/entity-name/test/to-json.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('to-json', () => { it('should create stringified object', () => { diff --git a/packages/entity-name/test/to-string.test.js b/packages/entity-name/test/to-string.test.js index 84d213a4..899bc3a7 100644 --- a/packages/entity-name/test/to-string.test.js +++ b/packages/entity-name/test/to-string.test.js @@ -1,18 +1,18 @@ -'use strict'; - -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; -const sinon = require('sinon'); -const proxyquire = require('proxyquire'); - -const spy = sinon.spy(); -const BemEntityName = proxyquire('../lib/entity-name', { - '@bem/sdk.naming.entity.stringify': () => spy -}); +import { expect } from 'chai'; +import sinon from 'sinon'; +import esmock from 'esmock'; describe('to-string', () => { + let spy; + let BemEntityName; + + before(async () => { + spy = sinon.spy(); + BemEntityName = (await esmock('../lib/entity-name.js', { + '@bem/sdk.naming.entity.stringify': { default: () => spy } + })).default; + }); + it('should use `naming.stringify()` for block', () => { const entityName = new BemEntityName({ block: 'block' }); diff --git a/packages/entity-name/test/type.test.js b/packages/entity-name/test/type.test.js index 1756168d..cd4d0917 100644 --- a/packages/entity-name/test/type.test.js +++ b/packages/entity-name/test/type.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('type', () => { it('should determine block', () => { @@ -35,7 +30,7 @@ describe('type', () => { it('should cache type value', () => { const entity = new BemEntityName({ block: 'block' }); - entity.type; // eslint-disable-line no-unused-expressions + entity.type; expect(entity._type).to.equal('block'); }); diff --git a/packages/entity-name/test/value-of.test.js b/packages/entity-name/test/value-of.test.js index da264cc6..515849b9 100644 --- a/packages/entity-name/test/value-of.test.js +++ b/packages/entity-name/test/value-of.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemEntityName = require('..'); +import BemEntityName from '../index.js'; describe('value-of.test.js', () => { it('should return normalized object', () => { diff --git a/packages/file/file.js b/packages/file/file.js index fdb8f52b..0a3e5e13 100644 --- a/packages/file/file.js +++ b/packages/file/file.js @@ -1,9 +1,7 @@ -'use strict'; +import assert from 'node:assert'; +import util from 'node:util'; -const assert = require('assert'); -const util = require('util'); - -const BemCell = require('@bem/sdk.cell'); +import BemCell from '@bem/sdk.cell'; class BemFile { /** @@ -32,8 +30,8 @@ class BemFile { * Returns the cell of the file. * * @example - * const BemFile = require('@bem/sdk.file'); - * const BemCell = require('@bem/sdk.cell'); + * import BemFile from '@bem/sdk.file'; + * import BemCell from '@bem/sdk.cell'; * * const file = new BemFile({ * cell: BemCell.create({ block: 'button', elem: 'text', tech: 'css' }) @@ -80,6 +78,10 @@ class BemFile { return `BemFile ${stringRepresentation}`; } + [Symbol.for('nodejs.util.inspect.custom')](depth, options) { + return this.inspect(depth, options); + } + toJSON() { return this.valueOf(); } @@ -92,7 +94,7 @@ class BemFile { * Determines whether specified file is deep equal to another file or not * * @example - * const BemFile = require('@bem/sdk.file'); + * import BemFile from '@bem/sdk.file'; * const buttonFile1 = BemFile.create({ block: 'button', tech: 'css', layer: 'desktop', level: 'desktop.blocks' }); * const buttonFile2 = BemFile.create({ block: 'button', tech: 'css', layer: 'desktop', level: 'desktop.blocks' }); * const inputFile = BemFile.create({ block: 'input', tech: 'css', layer: 'common', level: 'common.blocks' }); @@ -111,8 +113,8 @@ class BemFile { * Determines whether specified file is instance of BemFile. * * @example - * const BemFile = require('@bem/sdk.file'); - * const BemCell = require('@bem/sdk.cell'); + * import BemFile from '@bem/sdk.file'; + * import BemCell from '@bem/sdk.cell'; * * const file = new BemFile({ * cell: new BemCell({ block: 'button', elem: 'text', tech: 'css' }), @@ -133,7 +135,7 @@ class BemFile { * Creates BemFile instance by any object representation. * * @example - * const BemFile = require('@bem/sdk.file'); + * import BemFile from '@bem/sdk.file'; * * BemFile.create({ block: 'my-button', mod: 'theme', val: 'red', tech: 'css' }); * BemFile.create({ block: 'my-button', modName: 'theme', modVal: 'red', tech: 'css' }); @@ -166,4 +168,4 @@ class BemFile { } } -module.exports = BemFile; +export default BemFile; diff --git a/packages/file/package.json b/packages/file/package.json index 219e2f90..e2fe2239 100644 --- a/packages/file/package.json +++ b/packages/file/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.file", "version": "0.3.5", "description": "Representation of identifier of a part of BEM entity.", + "type": "module", "publishConfig": { "access": "public" }, @@ -26,15 +27,13 @@ "file.js" ], "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "dependencies": { - "@bem/sdk.cell": "^0.2.9", - "depd": "1.1.0" + "@bem/sdk.cell": "^0.2.9" }, "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" } } diff --git a/packages/file/test/create.test.js b/packages/file/test/create.test.js index f562c535..4ad8ecf2 100644 --- a/packages/file/test/create.test.js +++ b/packages/file/test/create.test.js @@ -1,12 +1,9 @@ -'use strict'; +import { describe, it } from 'node:test'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { expect } from 'chai'; -const expect = require('chai').expect; - -const BemCell = require('@bem/sdk.cell'); -const BemFile = require('..'); +import BemCell from '@bem/sdk.cell'; +import BemFile from '../file.js'; describe('create', () => { it('should return instance as is if it`s a BemFile', () => { diff --git a/packages/file/test/fields.test.js b/packages/file/test/fields.test.js index c7f210bc..cb783d65 100644 --- a/packages/file/test/fields.test.js +++ b/packages/file/test/fields.test.js @@ -1,11 +1,8 @@ -'use strict'; +import { describe, it } from 'node:test'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { expect } from 'chai'; -const expect = require('chai').expect; - -const BemFile = require('..'); +import BemFile from '../file.js'; describe('fields', () => { it('should provide `cell` field', () => { diff --git a/packages/file/test/id.test.js b/packages/file/test/id.test.js index c5bdcf9d..38704192 100644 --- a/packages/file/test/id.test.js +++ b/packages/file/test/id.test.js @@ -1,11 +1,8 @@ -'use strict'; +import { describe, it } from 'node:test'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import { expect } from 'chai'; -const expect = require('chai').expect; - -const BemFile = require('..'); +import BemFile from '../file.js'; describe('id', () => { it('should provide `id` field', () => { diff --git a/packages/file/test/inspect.test.js b/packages/file/test/inspect.test.js index a47950fe..fec6d8d8 100644 --- a/packages/file/test/inspect.test.js +++ b/packages/file/test/inspect.test.js @@ -1,13 +1,9 @@ -'use strict'; +import util from 'node:util'; +import { describe, it } from 'node:test'; -const util = require('util'); +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemFile = require('..'); +import BemFile from '../file.js'; describe('inspect', () => { it('should return entity object', () => { diff --git a/packages/graph/lib/bem-graph.js b/packages/graph/lib/bem-graph.js index 5877f618..fbecd820 100644 --- a/packages/graph/lib/bem-graph.js +++ b/packages/graph/lib/bem-graph.js @@ -1,10 +1,11 @@ -'use strict'; +import { debuglog } from 'node:util'; -const debug = require('debug')('@bem/sdk.graph'); -const BemCell = require('@bem/sdk.cell'); +import BemCell from '@bem/sdk.cell'; -const MixedGraph = require('./mixed-graph'); -const resolve = require('./mixed-graph-resolve'); +import MixedGraph from './mixed-graph.js'; +import resolve from './mixed-graph-resolve.js'; + +const debug = debuglog('bem_sdk_graph'); class BemGraph { constructor() { @@ -188,4 +189,4 @@ BemGraph.Vertex = class { * * @type {BemGraph} */ -module.exports = BemGraph; +export default BemGraph; diff --git a/packages/graph/lib/circular-dependency-error.js b/packages/graph/lib/circular-dependency-error.js index 6b70da74..54475490 100644 --- a/packages/graph/lib/circular-dependency-error.js +++ b/packages/graph/lib/circular-dependency-error.js @@ -1,11 +1,7 @@ -'use strict'; - -const ExtendableError = require('es6-error'); - /** - * СircularDependencyError + * CircularDependencyError */ -module.exports = class СircularDependencyError extends ExtendableError { +export default class CircularDependencyError extends Error { constructor(loop) { loop = Array.from(loop || []); @@ -16,6 +12,7 @@ module.exports = class СircularDependencyError extends ExtendableError { super(message); + this.name = this.constructor.name; this._loop = loop; } get loop() { @@ -26,4 +23,4 @@ module.exports = class СircularDependencyError extends ExtendableError { return res; }); } -}; +} diff --git a/packages/graph/lib/directed-graph.js b/packages/graph/lib/directed-graph.js index 69c6c695..fcfa99ad 100644 --- a/packages/graph/lib/directed-graph.js +++ b/packages/graph/lib/directed-graph.js @@ -1,13 +1,9 @@ -'use strict'; - -const VertexSet = require('./vertex-set'); +import VertexSet from './vertex-set.js'; /** * Направленый граф - * - * @type {module.DirectedGraph} */ -module.exports = class DirectedGraph { +export default class DirectedGraph { constructor() { this._vertices = new VertexSet(); this._edgeMap = new Map(); diff --git a/packages/graph/lib/index.js b/packages/graph/lib/index.js index d3ac28f1..4294e781 100644 --- a/packages/graph/lib/index.js +++ b/packages/graph/lib/index.js @@ -1,10 +1,6 @@ -'use strict'; - -const BemGraph = require('./bem-graph'); +import BemGraph from './bem-graph.js'; /** * Графы */ -module.exports = { - BemGraph -}; +export { BemGraph }; diff --git a/packages/graph/lib/mixed-graph-resolve.js b/packages/graph/lib/mixed-graph-resolve.js index 4ccf4104..79521c3b 100644 --- a/packages/graph/lib/mixed-graph-resolve.js +++ b/packages/graph/lib/mixed-graph-resolve.js @@ -1,12 +1,11 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; -const series = require('ho-iter').series; +import VertexSet from './vertex-set.js'; +import CircularDependencyError from './circular-dependency-error.js'; -const BemCell = require('@bem/sdk.cell') -const VertexSet = require('./vertex-set'); -const CircularDependencyError = require('./circular-dependency-error'); - -module.exports = resolve; +function* series(...iters) { + for (const it of iters) if (it) yield* it; +} class TopoGroups { constructor() { @@ -43,7 +42,7 @@ function resolve(mixedGraph, startVertices, tech) { const _positions = startVertices.reduce((res, e, pos) => { res[e.id] = pos; return res; }, {}); const backsort = (a, b) => _positions[a.id] - _positions[b.id]; - const orderedSuccessors = []; // L ← Empty list that will contain the sorted nodes + const orderedSuccessors = []; // L <- Empty list that will contain the sorted nodes const _orderedVisits = {}; // Hash with visiting flags: temporary - false, permanently - true const unorderedSuccessors = new VertexSet(); // The rest nodes let crumbs = []; @@ -146,3 +145,5 @@ function resolve(mixedGraph, startVertices, tech) { crumbs.pop(); } } + +export default resolve; diff --git a/packages/graph/lib/mixed-graph.js b/packages/graph/lib/mixed-graph.js index 05af21ac..35d716ab 100644 --- a/packages/graph/lib/mixed-graph.js +++ b/packages/graph/lib/mixed-graph.js @@ -1,10 +1,11 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; -const series = require('ho-iter').series; -const BemCell = require('@bem/sdk.cell'); +import VertexSet from './vertex-set.js'; +import DirectedGraph from './directed-graph.js'; -const VertexSet = require('./vertex-set'); -const DirectedGraph = require('./directed-graph'); +function* series(...iters) { + for (const it of iters) if (it) yield* it; +} /** * Mixed graph. @@ -13,7 +14,7 @@ const DirectedGraph = require('./directed-graph'); * * @type {MixedGraph} */ -module.exports = class MixedGraph { +export default class MixedGraph { constructor() { this._vertices = new VertexSet(); this._orderedGraphMap = new Map(); @@ -58,7 +59,7 @@ module.exports = class MixedGraph { * * @param {Vertex} vertex - Vertex with succeeding vertices * @param {{ordered: ?Boolean, tech: ?String}} data - ? - * @returns {HOIterator} - Iterator with succeeding vertices + * @returns {Iterator} - Iterator with succeeding vertices */ directSuccessors(vertex, data) { data || (data = {}); diff --git a/packages/graph/lib/test-utils.js b/packages/graph/lib/test-utils.js index 560b9999..fb82b900 100644 --- a/packages/graph/lib/test-utils.js +++ b/packages/graph/lib/test-utils.js @@ -1,9 +1,7 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; +import bemNaming from '@bem/sdk.naming.entity'; -const BemCell = require('@bem/sdk.cell'); -const bemNaming = require('@bem/sdk.naming.entity'); - -const BemGraph = require('./bem-graph'); +import BemGraph from './bem-graph.js'; function depsMacro(obj) { const graphFunction = obj.graph; @@ -98,7 +96,7 @@ function createGraph(str) { /** * Utilities for tests */ -module.exports = { +export { findIndex, findLastIndex, depsMacro, diff --git a/packages/graph/lib/vertex-set.js b/packages/graph/lib/vertex-set.js index b2a6ac58..69122f55 100644 --- a/packages/graph/lib/vertex-set.js +++ b/packages/graph/lib/vertex-set.js @@ -1,5 +1,31 @@ -'use strict'; +class VertexSet { + constructor(iterable) { + this._map = new Map(); + if (iterable) { + for (const vertex of iterable) { + this.add(vertex); + } + } + } + add(vertex) { + this._map.set(vertex.id, vertex); + return this; + } + has(vertex) { + return this._map.has(vertex.id); + } + get size() { + return this._map.size; + } + values() { + return this._map.values(); + } + [Symbol.iterator]() { + return this._map.values(); + } + forEach(fn) { + this._map.forEach(fn); + } +} -const hashSet = require('hash-set'); - -module.exports = hashSet(vertex => vertex.id); +export default VertexSet; diff --git a/packages/graph/package.json b/packages/graph/package.json index 8adb8589..c38cd12c 100644 --- a/packages/graph/package.json +++ b/packages/graph/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.graph", "version": "0.3.3", "description": "Bem graph storage", + "type": "module", "publishConfig": { "access": "public" }, @@ -20,7 +21,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/graph#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "lib/index.js", "files": [ @@ -29,12 +30,7 @@ "dependencies": { "@bem/sdk.cell": "^0.2.9", "@bem/sdk.entity-name": "^0.2.11", - "@bem/sdk.naming.entity": "^0.2.11", - "debug": "2.6.9", - "es6-error": "4.0.2", - "hash-set": "1.0.1", - "ho-iter": "0.3.0", - "lodash": "4.17.15" + "@bem/sdk.naming.entity": "^0.2.11" }, "scripts": { "test": "mocha test/**/*.test.js spec/**/*.spec.js" diff --git a/packages/graph/spec/decl-order/ordered-deps.spec.js b/packages/graph/spec/decl-order/ordered-deps.spec.js index 318a0c9c..d649a51d 100644 --- a/packages/graph/spec/decl-order/ordered-deps.spec.js +++ b/packages/graph/spec/decl-order/ordered-deps.spec.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('decl-order/ordered-deps', () => { it('should place ordered entity from decl before several entities depending on it', () => { diff --git a/packages/graph/spec/decl-order/unordered-deps.spec.js b/packages/graph/spec/decl-order/unordered-deps.spec.js index 7289acb5..aef5893c 100644 --- a/packages/graph/spec/decl-order/unordered-deps.spec.js +++ b/packages/graph/spec/decl-order/unordered-deps.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('decl-order/unordered-deps', () => { it('should keep the ordering described in decl', () => { diff --git a/packages/graph/spec/deps-recommended-order/ordered-deps.spec.js b/packages/graph/spec/deps-recommended-order/ordered-deps.spec.js index 8ef9f88e..ab2ded86 100644 --- a/packages/graph/spec/deps-recommended-order/ordered-deps.spec.js +++ b/packages/graph/spec/deps-recommended-order/ordered-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('deps-recommended-order/ordered-deps', () => { it('should keep the ordering described in deps', () => { diff --git a/packages/graph/spec/deps-recommended-order/unordered-deps.spec.js b/packages/graph/spec/deps-recommended-order/unordered-deps.spec.js index b3aa907a..277d96b3 100644 --- a/packages/graph/spec/deps-recommended-order/unordered-deps.spec.js +++ b/packages/graph/spec/deps-recommended-order/unordered-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('deps-recommended-order/unordered-deps', () => { it('should keep the ordering described in deps', () => { diff --git a/packages/graph/spec/deps/direct-deps/common-deps/resolve-common-deps.spec.js b/packages/graph/spec/deps/direct-deps/common-deps/resolve-common-deps.spec.js index af5fac17..56387b21 100644 --- a/packages/graph/spec/deps/direct-deps/common-deps/resolve-common-deps.spec.js +++ b/packages/graph/spec/deps/direct-deps/common-deps/resolve-common-deps.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/direct-deps/common-deps/resolve-common-deps', () => { it('should resolve entity depending on another entity', () => { diff --git a/packages/graph/spec/deps/direct-deps/common-deps/resolve-tech-deps.spec.js b/packages/graph/spec/deps/direct-deps/common-deps/resolve-tech-deps.spec.js index cc1c2141..e058a7e1 100644 --- a/packages/graph/spec/deps/direct-deps/common-deps/resolve-tech-deps.spec.js +++ b/packages/graph/spec/deps/direct-deps/common-deps/resolve-tech-deps.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/direct-deps/common-deps/resolve-tech-deps', () => { it('should resolve entity depending on another entity', () => { diff --git a/packages/graph/spec/deps/direct-deps/matching-deps/matching-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/direct-deps/matching-deps/matching-tech-resolving-by-tech.spec.js index 8b7ec7e8..ba995e8c 100644 --- a/packages/graph/spec/deps/direct-deps/matching-deps/matching-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/direct-deps/matching-deps/matching-tech-resolving-by-tech.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/direct-deps/matching-deps/matching-tech-resolving-by-tech', () => { it('should resolve entity depending on another entity', () => { diff --git a/packages/graph/spec/deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js index dd22642e..dce39acc 100644 --- a/packages/graph/spec/deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech', () => { it('should resolve entity depending on another entity', () => { @@ -18,7 +11,7 @@ describe('deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech', () graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'B' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'js'); return graph; }, @@ -37,8 +30,8 @@ describe('deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech', () graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'B' }, 'js') // eslint-disable-line no-unexpected-multiline - [linkMethod]({ block: 'B' }, 'bemhtml'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'js') + [linkMethod]({ block: 'B' }, 'bemhtml'); return graph; }, @@ -59,11 +52,11 @@ describe('deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech', () graph .vertex({ block: 'A' }) - [linkMethod]({ block: 'B' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'css'); graph .vertex({ block: 'B' }) - [linkMethod]({ block: 'C' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }, 'js'); return graph; }, @@ -82,12 +75,12 @@ describe('deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech', () graph .vertex({ block: 'A' }) - [linkMethod]({ block: 'B' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'css'); graph .vertex({ block: 'B' }) - [linkMethod]({ block: 'C' }, 'bemhtml') // eslint-disable-line no-unexpected-multiline - [linkMethod]({ block: 'D' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }, 'bemhtml') + [linkMethod]({ block: 'D' }, 'js'); return graph; }, @@ -108,11 +101,11 @@ describe('deps/direct-deps/matching-deps/mismatching-tech-resolving-by-tech', () graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'C' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }, 'js'); graph .vertex({ block: 'B' }, 'css') - [linkMethod]({ block: 'C' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }, 'js'); return graph; }, diff --git a/packages/graph/spec/deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js b/packages/graph/spec/deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js index 25da9b51..ce1960d7 100644 --- a/packages/graph/spec/deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js +++ b/packages/graph/spec/deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech', () => { it('should resolve entity depending on another entity', () => { @@ -18,7 +11,7 @@ describe('deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech', () => { graph .vertex({ block: 'A' }) - [linkMethod]({ block: 'B' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'css'); return graph; }, @@ -37,8 +30,8 @@ describe('deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech', () => { graph .vertex({ block: 'A' }) - [linkMethod]({ block: 'B' }, 'css') // eslint-disable-line no-unexpected-multiline - [linkMethod]({ block: 'B' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'css') + [linkMethod]({ block: 'B' }, 'js'); return graph; }, @@ -57,8 +50,8 @@ describe('deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech', () => { graph .vertex({ block: 'A' }) - [linkMethod]({ block: 'B' }, 'css') // eslint-disable-line no-unexpected-multiline - [linkMethod]({ block: 'C' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }, 'css') + [linkMethod]({ block: 'C' }, 'css'); return graph; }, @@ -77,11 +70,11 @@ describe('deps/direct-deps/tech-deps/entity-common-tech-to-entity-tech', () => { graph .vertex({ block: 'A' }) - [linkMethod]({ block: 'C' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }, 'css'); graph .vertex({ block: 'B' }) - [linkMethod]({ block: 'C' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }, 'css'); return graph; }, diff --git a/packages/graph/spec/deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js b/packages/graph/spec/deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js index ea453ab2..6d21586d 100644 --- a/packages/graph/spec/deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js +++ b/packages/graph/spec/deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech', () => { it('should resolve entity depending on another entity', () => { @@ -18,7 +11,7 @@ describe('deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'B' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }); return graph; }, @@ -37,8 +30,8 @@ describe('deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'B' }) // eslint-disable-line no-unexpected-multiline - [linkMethod]({ block: 'C' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }) + [linkMethod]({ block: 'C' }); return graph; }, @@ -58,11 +51,11 @@ describe('deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'B' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }); graph .vertex({ block: 'A' }, 'js') - [linkMethod]({ block: 'B' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'B' }); return graph; }, @@ -81,11 +74,11 @@ describe('deps/direct-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'A' }, 'css') - [linkMethod]({ block: 'C' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }); graph .vertex({ block: 'B' }, 'css') - [linkMethod]({ block: 'C' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'C' }); return graph; }, diff --git a/packages/graph/spec/deps/ignore-deps/common-deps/resolve-common-deps.spec.js b/packages/graph/spec/deps/ignore-deps/common-deps/resolve-common-deps.spec.js index b8a1c563..4909208f 100644 --- a/packages/graph/spec/deps/ignore-deps/common-deps/resolve-common-deps.spec.js +++ b/packages/graph/spec/deps/ignore-deps/common-deps/resolve-common-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/ignore-deps/common-deps/resolve-common-deps', () => { it('should not include entity if no entity from decl depends on it', () => { @@ -34,7 +29,7 @@ describe('deps/ignore-deps/common-deps/resolve-common-deps', () => { graph .vertex({ block: 'B' }) - [linkMethod]({ block: 'A' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'A' }); return graph; }, @@ -53,7 +48,7 @@ describe('deps/ignore-deps/common-deps/resolve-common-deps', () => { graph .vertex({ block: 'C' }) - [linkMethod]({ block: 'D' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }); return graph; }, diff --git a/packages/graph/spec/deps/ignore-deps/common-deps/resolve-tech-deps.spec.js b/packages/graph/spec/deps/ignore-deps/common-deps/resolve-tech-deps.spec.js index cca751a7..926f33f5 100644 --- a/packages/graph/spec/deps/ignore-deps/common-deps/resolve-tech-deps.spec.js +++ b/packages/graph/spec/deps/ignore-deps/common-deps/resolve-tech-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/ignore-deps/common-deps/resolve-tech-deps', () => { it('should not include entity if no entity from decl depends on it', () => { @@ -55,7 +50,7 @@ describe('deps/ignore-deps/common-deps/resolve-tech-deps', () => { graph .vertex({ block: 'C' }) - [linkMethod]({ block: 'D' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }); return graph; }, diff --git a/packages/graph/spec/deps/ignore-deps/matching-deps/matching-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/ignore-deps/matching-deps/matching-tech-resolving-by-tech.spec.js index 714f9f78..dca9dea7 100644 --- a/packages/graph/spec/deps/ignore-deps/matching-deps/matching-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/ignore-deps/matching-deps/matching-tech-resolving-by-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/ignore-deps/matching-deps/matching-tech-resolving-by-tech', () => { it('should not include entity if no entity from decl depends on it and this entity has dependency on entity' + diff --git a/packages/graph/spec/deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech.spec.js index 415c64e7..30a8673d 100644 --- a/packages/graph/spec/deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech', () => { it('should not include entity if no entity from decl depends on it and this entity has dependency on entity' + @@ -17,7 +12,7 @@ describe('deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech', () graph .vertex({ block: 'B' }, 'css') - [linkMethod]({ block: 'A' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'A' }, 'js'); return graph; }, @@ -36,7 +31,7 @@ describe('deps/ignore-deps/matching-deps/mismatchig-tech-resolving-by-tech', () graph .vertex({ block: 'C' }, 'css') - [linkMethod]({ block: 'D' }, 'js'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }, 'js'); return graph; }, diff --git a/packages/graph/spec/deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js b/packages/graph/spec/deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js index 051f1080..5ae0cd8a 100644 --- a/packages/graph/spec/deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js +++ b/packages/graph/spec/deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech', () => { it('should not include entity if no entity from decl depends on it and this entity has dependency on entity' + @@ -17,7 +12,7 @@ describe('deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech', () => { graph .vertex({ block: 'B' }) - [linkMethod]({ block: 'A' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'A' }, 'css'); return graph; }, @@ -36,7 +31,7 @@ describe('deps/ignore-deps/tech-deps/entity-common-tech-to-entity-tech', () => { graph .vertex({ block: 'C' }) - [linkMethod]({ block: 'D' }, 'css'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }, 'css'); return graph; }, diff --git a/packages/graph/spec/deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js b/packages/graph/spec/deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js index f542d9a0..2b67cf63 100644 --- a/packages/graph/spec/deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js +++ b/packages/graph/spec/deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech', () => { it('should not include entity if no entity from decl depends on it and this entity has dependency on entity' + @@ -17,7 +12,7 @@ describe('deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'B' }, 'css') - [linkMethod]({ block: 'A' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'A' }); return graph; }, @@ -36,7 +31,7 @@ describe('deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'C' }, 'css') - [linkMethod]({ block: 'D' }); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }); return graph; }, @@ -57,11 +52,11 @@ describe('deps/ignore-deps/tech-deps/entity-tech-to-entity-common-tech', () => { graph .vertex({ block: 'A' }, 't1') - [linkMethod]({ block: 'D' }, 'r1'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }, 'r1'); graph .vertex({ block: 'B' }, 't2') - [linkMethod]({ block: 'D' }, 'r2'); // eslint-disable-line no-unexpected-multiline + [linkMethod]({ block: 'D' }, 'r2'); return graph; }, diff --git a/packages/graph/spec/deps/itself-deps/common-deps/resolve-common-deps.spec.js b/packages/graph/spec/deps/itself-deps/common-deps/resolve-common-deps.spec.js index b99c3b48..ca1c9909 100644 --- a/packages/graph/spec/deps/itself-deps/common-deps/resolve-common-deps.spec.js +++ b/packages/graph/spec/deps/itself-deps/common-deps/resolve-common-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/itself-deps/common-deps/resolve-common-deps', () => { it('should include entity once if entity depends on a', () => { diff --git a/packages/graph/spec/deps/itself-deps/common-deps/resolve-tech-deps.spec.js b/packages/graph/spec/deps/itself-deps/common-deps/resolve-tech-deps.spec.js index 7990f4da..984064ed 100644 --- a/packages/graph/spec/deps/itself-deps/common-deps/resolve-tech-deps.spec.js +++ b/packages/graph/spec/deps/itself-deps/common-deps/resolve-tech-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/itself-deps/common-deps/resolve-tech-deps', () => { it('should include entity once if entity depends on a', () => { diff --git a/packages/graph/spec/deps/itself-deps/matching-deps/matching-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/itself-deps/matching-deps/matching-tech-resolving-by-tech.spec.js index cadd7a7b..08dce0bf 100644 --- a/packages/graph/spec/deps/itself-deps/matching-deps/matching-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/itself-deps/matching-deps/matching-tech-resolving-by-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/itself-deps/matching-deps/matching-tech-resolving-by-tech', () => { it('should include entity once if entity depends on a', () => { diff --git a/packages/graph/spec/deps/itself-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js b/packages/graph/spec/deps/itself-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js index df2088d0..ab5d5c33 100644 --- a/packages/graph/spec/deps/itself-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js +++ b/packages/graph/spec/deps/itself-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/itself-deps/tech-deps/entity-common-tech-to-entity-tech', () => { it('should include entity once if entity depends on a', () => { diff --git a/packages/graph/spec/deps/itself-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js b/packages/graph/spec/deps/itself-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js index 52ec27bb..f4bfb1fd 100644 --- a/packages/graph/spec/deps/itself-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js +++ b/packages/graph/spec/deps/itself-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/itself-deps/tech-deps/entity-tech-to-entity-common-tech', () => { it('should include entity once if entity depends on a', () => { diff --git a/packages/graph/spec/deps/transitive-deps/common-deps/resolve-common-deps.spec.js b/packages/graph/spec/deps/transitive-deps/common-deps/resolve-common-deps.spec.js index 60cc475e..c96ec6c8 100644 --- a/packages/graph/spec/deps/transitive-deps/common-deps/resolve-common-deps.spec.js +++ b/packages/graph/spec/deps/transitive-deps/common-deps/resolve-common-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/transitive-deps/common-deps/resolve-common-deps', () => { it('should resolve transitive dependency', () => { diff --git a/packages/graph/spec/deps/transitive-deps/common-deps/resolve-tech-deps.spec.js b/packages/graph/spec/deps/transitive-deps/common-deps/resolve-tech-deps.spec.js index c9102209..0c687f55 100644 --- a/packages/graph/spec/deps/transitive-deps/common-deps/resolve-tech-deps.spec.js +++ b/packages/graph/spec/deps/transitive-deps/common-deps/resolve-tech-deps.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/transitive-deps/common-deps/resolve-tech-deps', () => { it('should resolve transitive dependency', () => { diff --git a/packages/graph/spec/deps/transitive-deps/matching-deps/matching-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/transitive-deps/matching-deps/matching-tech-resolving-by-tech.spec.js index a105c095..307b78ec 100644 --- a/packages/graph/spec/deps/transitive-deps/matching-deps/matching-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/transitive-deps/matching-deps/matching-tech-resolving-by-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/transitive-deps/matching-deps/matching-tech-resolving-by-tech', () => { it('should resolve transitive dependency', () => { diff --git a/packages/graph/spec/deps/transitive-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js b/packages/graph/spec/deps/transitive-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js index c5810974..769ae60b 100644 --- a/packages/graph/spec/deps/transitive-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js +++ b/packages/graph/spec/deps/transitive-deps/matching-deps/mismatching-tech-resolving-by-tech.spec.js @@ -1,14 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; -const findIndex = require('../../../../lib/test-utils').findIndex; -const findLastIndex = require('../../../../lib/test-utils').findLastIndex; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro, findIndex, findLastIndex } from '../../../../lib/test-utils.js'; describe('deps/transitive-deps/matching-deps/mismatching-tech-resolving-by-tech', () => { it('should not resolve transitive dependency', () => { diff --git a/packages/graph/spec/deps/transitive-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js b/packages/graph/spec/deps/transitive-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js index 8a8fae93..35c1055e 100644 --- a/packages/graph/spec/deps/transitive-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js +++ b/packages/graph/spec/deps/transitive-deps/tech-deps/entity-common-tech-to-entity-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/transitive-deps/tech-deps/entity-common-tech-to-entity-tech', () => { it('should resolve transitive dependency', () => { diff --git a/packages/graph/spec/deps/transitive-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js b/packages/graph/spec/deps/transitive-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js index 434b941d..e76bf57a 100644 --- a/packages/graph/spec/deps/transitive-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js +++ b/packages/graph/spec/deps/transitive-deps/tech-deps/entity-tech-to-entity-common-tech.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../../../lib').BemGraph; -const macro = require('../../../../lib/test-utils').depsMacro; +import { BemGraph } from '../../../../lib/index.js'; +import { depsMacro as macro } from '../../../../lib/test-utils.js'; describe('deps/transitive-deps/tech-deps/entity-tech-to-entity-common-tech', () => { it('should resolve transitive dependency', () => { diff --git a/packages/graph/spec/ignore-tech-deps/common-deps.spec.js b/packages/graph/spec/ignore-tech-deps/common-deps.spec.js index 7e382d22..b412ecc7 100644 --- a/packages/graph/spec/ignore-tech-deps/common-deps.spec.js +++ b/packages/graph/spec/ignore-tech-deps/common-deps.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; // TODO: make it non-uebansky // diff --git a/packages/graph/spec/ignore-tech-deps/mismatching-tech.spec.js b/packages/graph/spec/ignore-tech-deps/mismatching-tech.spec.js index f2a1c853..5f77e8aa 100644 --- a/packages/graph/spec/ignore-tech-deps/mismatching-tech.spec.js +++ b/packages/graph/spec/ignore-tech-deps/mismatching-tech.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; // TODO: make it non-uebansky diff --git a/packages/graph/spec/loops/broken-loops.spec.js b/packages/graph/spec/loops/broken-loops.spec.js index 70a3f189..6b803d35 100644 --- a/packages/graph/spec/loops/broken-loops.spec.js +++ b/packages/graph/spec/loops/broken-loops.spec.js @@ -1,12 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('loops/broken-loops', () => { it('should not throw error if detected ordered loop broken in the middle by unordered dependency', () => { diff --git a/packages/graph/spec/loops/direct-loops.spec.js b/packages/graph/spec/loops/direct-loops.spec.js index af6a7d1f..4f02adfe 100644 --- a/packages/graph/spec/loops/direct-loops.spec.js +++ b/packages/graph/spec/loops/direct-loops.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('loops/direct-loops', () => { it('should not throw error if detected unordered direct loop', () => { diff --git a/packages/graph/spec/loops/indirect-loops.spec.js b/packages/graph/spec/loops/indirect-loops.spec.js index 8b68e586..fd378868 100644 --- a/packages/graph/spec/loops/indirect-loops.spec.js +++ b/packages/graph/spec/loops/indirect-loops.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('loops/indirect-loops', () => { it('should not throw error if detected unordered indirect loop', () => { diff --git a/packages/graph/spec/loops/intermediate-loops.spec.js b/packages/graph/spec/loops/intermediate-loops.spec.js index 930d88d2..be1f30ef 100644 --- a/packages/graph/spec/loops/intermediate-loops.spec.js +++ b/packages/graph/spec/loops/intermediate-loops.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('loops/intermediate-loops', () => { it('should not throw error if detected unordered intermediate loop', () => { diff --git a/packages/graph/spec/loops/itself-loops.spec.js b/packages/graph/spec/loops/itself-loops.spec.js index e16bddac..012d3512 100644 --- a/packages/graph/spec/loops/itself-loops.spec.js +++ b/packages/graph/spec/loops/itself-loops.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('loops/itself-loops', () => { it('should not throw error if detected unordered loop on itself', () => { diff --git a/packages/graph/spec/loops/tech-loops.spec.js b/packages/graph/spec/loops/tech-loops.spec.js index 8779656c..a6ef46c6 100644 --- a/packages/graph/spec/loops/tech-loops.spec.js +++ b/packages/graph/spec/loops/tech-loops.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('loops/tech-loops', () => { it('should throw error if detected ordered loop between same techs', () => { diff --git a/packages/graph/spec/natural-order/decl-order.spec.js b/packages/graph/spec/natural-order/decl-order.spec.js index caaac3a7..840cd698 100644 --- a/packages/graph/spec/natural-order/decl-order.spec.js +++ b/packages/graph/spec/natural-order/decl-order.spec.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('natural-order/decl-order', () => { it('should place block before its element', () => { diff --git a/packages/graph/spec/natural-order/deps-recommended-order.spec.js b/packages/graph/spec/natural-order/deps-recommended-order.spec.js index 64f4f855..1555bf96 100644 --- a/packages/graph/spec/natural-order/deps-recommended-order.spec.js +++ b/packages/graph/spec/natural-order/deps-recommended-order.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('natural-order/deps-recommended-order', () => { it('should place block before its element', () => { diff --git a/packages/graph/spec/ordered-deps/ordering.spec.js b/packages/graph/spec/ordered-deps/ordering.spec.js index 3cf54cae..736afa2f 100644 --- a/packages/graph/spec/ordered-deps/ordering.spec.js +++ b/packages/graph/spec/ordered-deps/ordering.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('ordered-deps/ordering', () => { it('should place ordered entity from decl before entity depending on it', () => { diff --git a/packages/graph/spec/ordering-priority/decl-vs-deps-recommended.spec.js b/packages/graph/spec/ordering-priority/decl-vs-deps-recommended.spec.js index 283be81c..e2e8441e 100644 --- a/packages/graph/spec/ordering-priority/decl-vs-deps-recommended.spec.js +++ b/packages/graph/spec/ordering-priority/decl-vs-deps-recommended.spec.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('ordering-priority/decl-vs-deps-recommended', () => { it('should prioritise decl order over recommended deps order', () => { diff --git a/packages/graph/spec/ordering-priority/ordered-vs-bem.spec.js b/packages/graph/spec/ordering-priority/ordered-vs-bem.spec.js index 381747be..091f6245 100644 --- a/packages/graph/spec/ordering-priority/ordered-vs-bem.spec.js +++ b/packages/graph/spec/ordering-priority/ordered-vs-bem.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('ordering-priority/ordered-vs-bem', () => { it('should prioritise ordered dependency over block-element natural ordering', () => { diff --git a/packages/graph/spec/ordering-priority/ordered-vs-decl.spec.js b/packages/graph/spec/ordering-priority/ordered-vs-decl.spec.js index 582e34a0..bb5ab2f7 100644 --- a/packages/graph/spec/ordering-priority/ordered-vs-decl.spec.js +++ b/packages/graph/spec/ordering-priority/ordered-vs-decl.spec.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; +import { BemGraph } from '../../lib/index.js'; describe('ordering-priority/ordered-vs-decl', () => { it('should resolve ordered dependencies independently for each declaration entity', () => { diff --git a/packages/graph/spec/ordering-priority/ordered-vs-unordered.spec.js b/packages/graph/spec/ordering-priority/ordered-vs-unordered.spec.js index 379728d2..fba11d9a 100644 --- a/packages/graph/spec/ordering-priority/ordered-vs-unordered.spec.js +++ b/packages/graph/spec/ordering-priority/ordered-vs-unordered.spec.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const BemGraph = require('../../lib').BemGraph; -const findIndex = require('../../lib/test-utils').findIndex; +import { BemGraph } from '../../lib/index.js'; +import { findIndex } from '../../lib/test-utils.js'; describe('ordering-priority/ordered-vs-unordered', () => { it('should prioritise ordered dependency over decl recommended ordering', () => { diff --git a/packages/graph/test/directed-graph/add-edge.test.js b/packages/graph/test/directed-graph/add-edge.test.js index b218b414..e4c2e4ed 100644 --- a/packages/graph/test/directed-graph/add-edge.test.js +++ b/packages/graph/test/directed-graph/add-edge.test.js @@ -1,15 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const DirectedGraph = require('../../lib/directed-graph'); +import DirectedGraph from '../../lib/directed-graph.js'; const vertex1 = new BemCell({ entity: new BemEntityName({ block: 'button' }) }); const vertex2 = new BemCell({ entity: new BemEntityName({ block: 'control' }) }); diff --git a/packages/graph/test/directed-graph/add-vertex.test.js b/packages/graph/test/directed-graph/add-vertex.test.js index 39057704..5553a9aa 100644 --- a/packages/graph/test/directed-graph/add-vertex.test.js +++ b/packages/graph/test/directed-graph/add-vertex.test.js @@ -1,15 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const DirectedGraph = require('../../lib/directed-graph'); +import DirectedGraph from '../../lib/directed-graph.js'; const vertex = new BemCell({ entity: new BemEntityName({ block: 'button' }) }); diff --git a/packages/graph/test/directed-graph/direct-successors.test.js b/packages/graph/test/directed-graph/direct-successors.test.js index e8df409c..7dac82c4 100644 --- a/packages/graph/test/directed-graph/direct-successors.test.js +++ b/packages/graph/test/directed-graph/direct-successors.test.js @@ -1,15 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const DirectedGraph = require('../../lib/directed-graph'); +import DirectedGraph from '../../lib/directed-graph.js'; describe('directed-graph/direct-successors', () => { it('should return successors', () => { diff --git a/packages/graph/test/directed-graph/successors.test.js b/packages/graph/test/directed-graph/successors.test.js index 7207398d..7469a20e 100644 --- a/packages/graph/test/directed-graph/successors.test.js +++ b/packages/graph/test/directed-graph/successors.test.js @@ -1,15 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const DirectedGraph = require('../../lib/directed-graph'); +import DirectedGraph from '../../lib/directed-graph.js'; const vertex1 = new BemCell({ entity: new BemEntityName({ block: 'select' }) }); const vertex2 = new BemCell({ entity: new BemEntityName({ block: 'button' }) }); diff --git a/packages/graph/test/mixed-graph/add-edge.test.js b/packages/graph/test/mixed-graph/add-edge.test.js index 8056e34a..c35f27a6 100644 --- a/packages/graph/test/mixed-graph/add-edge.test.js +++ b/packages/graph/test/mixed-graph/add-edge.test.js @@ -1,19 +1,11 @@ -'use strict'; +import { expect } from 'chai'; +import sinon from 'sinon'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const beforeEach = require('mocha').beforeEach; -const afterEach = require('mocha').afterEach; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - -const sinon = require('sinon'); - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const MixedGraph = require('../../lib/mixed-graph'); -const DirectedGraph = require('../../lib/directed-graph'); +import MixedGraph from '../../lib/mixed-graph.js'; +import DirectedGraph from '../../lib/directed-graph.js'; const vertex1 = new BemCell({ entity: new BemEntityName({ block: 'button' }), tech: 'css' }); const vertex2 = new BemCell({ entity: new BemEntityName({ block: 'control' }), tech: 'css' }); diff --git a/packages/graph/test/mixed-graph/add-vertex.test.js b/packages/graph/test/mixed-graph/add-vertex.test.js index 782fb62e..0fee7b4f 100644 --- a/packages/graph/test/mixed-graph/add-vertex.test.js +++ b/packages/graph/test/mixed-graph/add-vertex.test.js @@ -1,15 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const MixedGraph = require('../../lib/mixed-graph'); +import MixedGraph from '../../lib/mixed-graph.js'; const vertex = new BemCell({ entity: new BemEntityName({ block: 'button' }) }); diff --git a/packages/graph/test/mixed-graph/direct-successors.test.js b/packages/graph/test/mixed-graph/direct-successors.test.js index f7f97c49..c2b85245 100644 --- a/packages/graph/test/mixed-graph/direct-successors.test.js +++ b/packages/graph/test/mixed-graph/direct-successors.test.js @@ -1,14 +1,8 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import MixedGraph from '../../lib/mixed-graph.js'; -const expect = require('chai').expect; - - -const MixedGraph = require('../../lib/mixed-graph'); - -const createVertex = require('../../lib/test-utils').createVertex; +import { createVertex } from '../../lib/test-utils.js'; describe('mixed-graph/direct-successors', () => { it('should return empty set if no successors', () => { diff --git a/packages/graph/test/mixed-graph/get-subgraph.test.js b/packages/graph/test/mixed-graph/get-subgraph.test.js index 283c9799..0c875347 100644 --- a/packages/graph/test/mixed-graph/get-subgraph.test.js +++ b/packages/graph/test/mixed-graph/get-subgraph.test.js @@ -1,13 +1,7 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const DirectedGraph = require('../../lib/directed-graph'); -const MixedGraph = require('../../lib/mixed-graph'); +import DirectedGraph from '../../lib/directed-graph.js'; +import MixedGraph from '../../lib/mixed-graph.js'; describe('mixed-graph/get-subgraph', () => { it('should return unordered subgraph with common deps', () => { diff --git a/packages/graph/test/utils/create-graph.test.js b/packages/graph/test/utils/create-graph.test.js index 4e0b2fa7..511df178 100644 --- a/packages/graph/test/utils/create-graph.test.js +++ b/packages/graph/test/utils/create-graph.test.js @@ -1,13 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const createGraph = require('../../lib/test-utils').createGraph; -const createVertex = require('../../lib/test-utils').createVertex; +import { createGraph, createVertex } from '../../lib/test-utils.js'; const depsOfGraph = (s, decl, tech) => createGraph(s) .dependenciesOf(decl, tech) diff --git a/packages/graph/test/utils/create-vertex.test.js b/packages/graph/test/utils/create-vertex.test.js index 9727ed1b..5a8bd08f 100644 --- a/packages/graph/test/utils/create-vertex.test.js +++ b/packages/graph/test/utils/create-vertex.test.js @@ -1,12 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - - -const v = require('../../lib/test-utils').createVertex; +import { createVertex as v } from '../../lib/test-utils.js'; describe('utils/create-vertex.test.js', () => { it('should create block vertex', () => { diff --git a/packages/graph/test/utils/find-index.test.js b/packages/graph/test/utils/find-index.test.js index cd7b246a..8248cf7b 100644 --- a/packages/graph/test/utils/find-index.test.js +++ b/packages/graph/test/utils/find-index.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const findIndex = require('../../lib/test-utils').findIndex; +import { findIndex } from '../../lib/test-utils.js'; describe('utils/find-index', () => { it('should not find non existing block', () => { diff --git a/packages/graph/test/utils/find-last-index.test.js b/packages/graph/test/utils/find-last-index.test.js index a31ebe85..a763f9a4 100644 --- a/packages/graph/test/utils/find-last-index.test.js +++ b/packages/graph/test/utils/find-last-index.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const findLastIndex = require('../../lib/test-utils').findLastIndex; +import { findLastIndex } from '../../lib/test-utils.js'; describe('utils/find-last-index', () => { it('should not find non existing block', () => { diff --git a/packages/graph/test/utils/simplify-vertices.test.js b/packages/graph/test/utils/simplify-vertices.test.js index efa37a3c..700b1413 100644 --- a/packages/graph/test/utils/simplify-vertices.test.js +++ b/packages/graph/test/utils/simplify-vertices.test.js @@ -1,12 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const simplifyVertices = require('../../lib/test-utils').simplifyVertices; -const createVertex = require('../../lib/test-utils').createVertex; +import { simplifyVertices, createVertex } from '../../lib/test-utils.js'; describe('utils/simplify-vertices', () => { it('should simplify vertex', () => { diff --git a/packages/graph/test/vertex-set.test.js b/packages/graph/test/vertex-set.test.js index ca905839..383a5904 100644 --- a/packages/graph/test/vertex-set.test.js +++ b/packages/graph/test/vertex-set.test.js @@ -1,15 +1,9 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; +import BemEntityName from '@bem/sdk.entity-name'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; - - -const BemEntityName = require('@bem/sdk.entity-name'); -const BemCell = require('@bem/sdk.cell'); - -const VertexSet = require('../lib/vertex-set'); +import VertexSet from '../lib/vertex-set.js'; describe('vertex-set.test.js', () => { it('should add different vertices', () => { diff --git a/packages/import-notation/.eslintrc b/packages/import-notation/.eslintrc deleted file mode 100644 index cfc486cb..00000000 --- a/packages/import-notation/.eslintrc +++ /dev/null @@ -1,44 +0,0 @@ -{ - "parserOptions" : { - "ecmaVersion" : 6, - "sourceType" : "module" - }, - "rules" : { - "semi" : "error", - "indent" : ["error", 4], - "no-mixed-spaces-and-tabs" : "error", - "max-len" : ["error", { "code" : 120 }], - "eol-last" : "error", - "no-unused-vars" : ["error", { - "vars" : "all", - "args" : "none" - }], - "key-spacing" : ["error", { - "beforeColon" : true, - "afterColon" : true, - "mode" : "strict" - }], - "object-curly-spacing" : ["error", "always"], - "keyword-spacing" : ["error", { - "before" : true, - "after" : true, - "overrides" : { - "if" : { "after" : false }, - "for" : { "after" : false }, - "while" : { "after" : false }, - "switch" : { "after" : false }, - "catch" : { "after" : false } - } - }], - "array-bracket-spacing" : ["error", "never"], - "func-call-spacing" : "error", - "space-before-blocks" : ["error", "always"], - "quotes" : ["error", "single", { "avoidEscape" : true }], - "camelcase" : ["error", { "properties" : "never" }], - "no-trailing-spaces" : "error", - "comma-dangle" : ["error", "never"], - "react/sort-prop-types" : "off", - "react/forbid-component-props" : "off", - "react/display-name" : "off" - } -} diff --git a/packages/import-notation/index.js b/packages/import-notation/index.js index 009ac10e..f9c6431f 100644 --- a/packages/import-notation/index.js +++ b/packages/import-notation/index.js @@ -1,4 +1,29 @@ -const hashSet = require('hash-set'); +class HashSet { + constructor(hashFn) { + this._hashFn = hashFn; + this._map = new Map(); + } + + add(item) { + const key = this._hashFn(item); + if (!this._map.has(key)) { + this._map.set(key, item); + } + return this; + } + + get size() { + return this._map.size; + } + + forEach(fn) { + this._map.forEach(value => fn(value)); + } + + [Symbol.iterator]() { + return this._map.values(); + } +} const tmpl = { b : b => `b:${b}`, @@ -13,11 +38,10 @@ const btmpl = Object.assign({}, tmpl, { m : m => m ? `${tmpl.mn(m['name'])}${tmpl.mv([m['val']])}` : '' }); -const BemCellSet = hashSet(cell => +const cellHashFn = cell => ['block', 'elem', 'mod', 'tech'] .map(k => btmpl[k[0]](cell[k])) - .join('') -); + .join(''); /** * Parse import statement and extract bem entities @@ -77,7 +101,7 @@ function parse(importString, scope) { } } return acc; - }, new BemCellSet())); + }, new HashSet(cellHashFn))); } /** @@ -107,7 +131,4 @@ function stringify(cells) { return ['b', 'e', 'm', 't'].map(k => tmpl[k](merged[k])).join(''); } -module.exports = { - parse, - stringify -}; +export { parse, stringify }; diff --git a/packages/import-notation/package.json b/packages/import-notation/package.json index cdb6dac6..208fe60b 100644 --- a/packages/import-notation/package.json +++ b/packages/import-notation/package.json @@ -2,14 +2,17 @@ "name": "@bem/sdk.import-notation", "version": "0.0.7", "description": "BEM import notation parser", + "type": "module", "publishConfig": { "access": "public" }, "main": "index.js", + "engines": { + "node": ">= 24.0" + }, "scripts": { "test": "npm run specs", - "specs": "mocha", - "cover": "nyc mocha" + "specs": "mocha" }, "repository": "bem/bem-sdk", "keywords": [ @@ -22,7 +25,5 @@ "url": "https://github.com/bem/bem-sdk/issues?q=label%3Apkg%3Aimport-notation" }, "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/import-notation#readme", - "dependencies": { - "hash-set": "^1.0.1" - } + "dependencies": {} } diff --git a/packages/import-notation/test/parse.test.js b/packages/import-notation/test/parse.test.js index 78c5a695..4103f6ca 100644 --- a/packages/import-notation/test/parse.test.js +++ b/packages/import-notation/test/parse.test.js @@ -1,5 +1,5 @@ -var expect = require('chai').expect, - p = require('..').parse; +import { expect } from 'chai'; +import { parse as p } from '../index.js'; it('should return an array', () => { expect(p('b:button')).to.be.an('Array'); diff --git a/packages/import-notation/test/stringify.test.js b/packages/import-notation/test/stringify.test.js index 9004461e..2044024b 100644 --- a/packages/import-notation/test/stringify.test.js +++ b/packages/import-notation/test/stringify.test.js @@ -1,5 +1,5 @@ -var expect = require('chai').expect, - s = require('..').stringify; +import { expect } from 'chai'; +import { stringify as s } from '../index.js'; it('should return a string', () => { expect(s([{ block : 'button' }])).to.be.an('String'); diff --git a/packages/keyset/index.js b/packages/keyset/index.js index e58201c0..376284f9 100644 --- a/packages/keyset/index.js +++ b/packages/keyset/index.js @@ -1,10 +1,8 @@ -'use strict'; +import { Key, ParamedKey, PluralKey } from './lib/key.js'; +import { LangKeys } from './lib/langKeys.js'; +import { Keyset } from './lib/keyset.js'; -const { Key, ParamedKey, PluralKey } = require('./lib/key'); -const { LangKeys } = require('./lib/langKeys'); -const { Keyset } = require('./lib/keyset'); - -module.exports = { +export { Key, ParamedKey, PluralKey, diff --git a/packages/keyset/lib/formats/enb/index.js b/packages/keyset/lib/formats/enb/index.js index 53c9ab26..29a2f2db 100644 --- a/packages/keyset/lib/formats/enb/index.js +++ b/packages/keyset/lib/formats/enb/index.js @@ -1,17 +1,21 @@ -'use strict'; +import assert from 'node:assert'; +import vm from 'node:vm'; -const assert = require('assert'); +import parseXML from './parseXML.js'; -const nEval = require('node-eval'); - -const parseXML = require('./parseXML'); +function nodeEval(code) { + const m = { exports: {} }; + const wrapped = `(function(module, exports) { ${code}\n})(m, m.exports)`; + vm.runInNewContext(wrapped, { m }); + return m.exports; +} const Key = { paramsReg: () => /(\w+)<\/i18n:param>/g, getParams: function (name, value) { const r = this.paramsReg(); const params = []; - let res = null; + let res; while ((res = r.exec(value)) !== null) { params.push(res[1]); @@ -91,7 +95,7 @@ const LangKeys = { let data = null; let errMsg = ''; try { - data = nEval(str); + data = nodeEval(str); } catch(err) { const s = err.stack.split('\n'); errMsg += err.message + '\n'; @@ -119,7 +123,7 @@ const LangKeys = { } -module.exports = { +export { LangKeys, Key -} +}; diff --git a/packages/keyset/lib/formats/enb/parseXML.js b/packages/keyset/lib/formats/enb/parseXML.js index 75c49bfa..cf323f63 100644 --- a/packages/keyset/lib/formats/enb/parseXML.js +++ b/packages/keyset/lib/formats/enb/parseXML.js @@ -1,87 +1,101 @@ -'use strict'; +import { XMLParser } from 'fast-xml-parser'; -const xamel = require('xamel'); - -module.exports = async function transform(str) { +export default async function transform(str) { if (!str.includes(' - xamel.parse(str, { strict: false, trim: false }, async function(err, xml) { - if (err) { - console.log('Error while transform XML'); - rej(err); - } + // Wrap in a root element so the parser handles it as valid XML + const wrappedStr = `${str}`; + + const parser = new XMLParser({ + ignoreAttributes: false, + attributeNamePrefix: '', + preserveOrder: true, + trimValues: false, + textNodeName: '#text', + processEntities: false, + // Treat i18n: prefixed tags properly + allowBooleanAttributes: true + }); - const _transformed = await processNodes(xml, true); + const parsed = parser.parse(wrappedStr); + // parsed is an array, root element is first + const rootChildren = parsed[0].root; - res(_transformed); - }) - ); + const transformed = await processNodes(rootChildren); return transformed; } async function processNodes(nodes) { - return await new Promise(async (res, rej) => { - const unknown = []; - - const transformed = await nodes.reduce(async (accP, node) => { - const acc = await accP; + const unknown = []; + const transformed = []; + + for (const node of nodes) { + // Text node + if (typeof node['#text'] === 'string' || typeof node['#text'] === 'number') { + transformed.push([String(node['#text'])]); + continue; + } - if (typeof node === 'string') { - acc.push([node]); - return Promise.resolve(acc); - } + const nodeName = getNodeName(node); + if (!nodeName) continue; - if (node.name === 'I18N:DYNAMIC') { - const { KEY } = node.attrs || {}; + const upperName = nodeName.toUpperCase(); - if (KEY === 'plural' || KEY === 'plural_adv') { - const pluralNode = await transformPlural(node) - acc.push([pluralNode]); - } + if (upperName === 'I18N:DYNAMIC') { + const attrs = getNodeAttrs(node, nodeName); + const key = attrs.key || attrs.KEY; - return Promise.resolve(acc); + if (key === 'plural' || key === 'plural_adv') { + const children = getNodeChildren(node, nodeName); + const pluralNode = await transformPlural(children); + transformed.push([pluralNode]); } - if (node.name === 'I18N:PARAM') { - acc.push([ - transformParam(node), - extractText(node) - ]); - return Promise.resolve(acc); - } - - if (process.env.DEBUG) { - console.log('need transform:'); - console.log(node); - unknown.push(node); - } + continue; + } - return Promise.resolve(acc); - }, Promise.resolve([])); + if (upperName === 'I18N:PARAM') { + const textContent = extractText(node, nodeName); + transformed.push([ + `{${textContent}}`, + textContent + ]); + continue; + } - if (unknown.length) { - rej(unknown); + if (process.env.DEBUG) { + console.log('need transform:'); + console.log(node); + unknown.push(node); } + } - return res(transformed); - }); -} + if (unknown.length) { + throw unknown; + } -async function transformPlural({ children = [] }) { + return transformed; +} +async function transformPlural(children) { const pluralObj = {}; - for (let node of children) { - for (let type of ['one', 'some', 'many', 'none']) { - if (node.name === `I18N:${type.toUpperCase()}`) { + for (const node of children) { + const nodeName = getNodeName(node); + if (!nodeName) continue; + + const upperName = nodeName.toUpperCase(); + + for (const type of ['one', 'some', 'many', 'none']) { + if (upperName === `I18N:${type.toUpperCase()}`) { try { - pluralObj[type] = await processNodes(node.children); + const nodeChildren = getNodeChildren(node, nodeName); + pluralObj[type] = await processNodes(nodeChildren); } catch(err) { console.log('Failed to process nodes'); console.log(err); @@ -93,11 +107,37 @@ async function transformPlural({ children = [] }) { return pluralObj; } -function transformParam(node) { - const text = extractText(node); - return `{${text}}`; +// Helper: get the element name from a fast-xml-parser preserveOrder node +function getNodeName(node) { + for (const key of Object.keys(node)) { + if (key !== '#text' && key !== ':@') { + return key; + } + } + return null; +} + +// Helper: get attributes from a preserveOrder node +function getNodeAttrs(node, _nodeName) { + if (node[':@']) { + return node[':@']; + } + return {}; } -function extractText(node) { - return node.$(`text()`); +// Helper: get children array from a preserveOrder node +function getNodeChildren(node, nodeName) { + return node[nodeName] || []; +} + +// Helper: extract text content from a node (like xamel's .$('text()')) +function extractText(node, nodeName) { + const children = node[nodeName] || []; + let text = ''; + for (const child of children) { + if (typeof child['#text'] === 'string' || typeof child['#text'] === 'number') { + text += String(child['#text']); + } + } + return text; } diff --git a/packages/keyset/lib/formats/index.js b/packages/keyset/lib/formats/index.js index ddf858a7..5b6850aa 100644 --- a/packages/keyset/lib/formats/index.js +++ b/packages/keyset/lib/formats/index.js @@ -1,9 +1,7 @@ -'use strict'; +import * as taburet from './taburet/index.js'; +import * as enb from './enb/index.js'; -const taburet = require('./taburet'); -const enb = require('./enb'); - -module.exports = { +export default { taburet, enb }; diff --git a/packages/keyset/lib/formats/taburet/index.js b/packages/keyset/lib/formats/taburet/index.js index 5f175183..34a1fbfb 100644 --- a/packages/keyset/lib/formats/taburet/index.js +++ b/packages/keyset/lib/formats/taburet/index.js @@ -1,8 +1,12 @@ -'use strict'; +import assert from 'node:assert'; +import vm from 'node:vm'; -const assert = require('assert'); - -const nEval = require('node-eval'); +function nodeEval(code) { + const m = { exports: {} }; + const wrapped = `(function(module, exports) { ${code}\n})(m, m.exports)`; + vm.runInNewContext(wrapped, { m }); + return m.exports; +} const LangKeys = { stringify: langKeys => { @@ -36,7 +40,7 @@ const LangKeys = { let data = null; try { - data = nEval(strToParse); + data = nodeEval(strToParse); } catch(err) { console.log(err); } @@ -90,7 +94,7 @@ const Key = { getParams: function (name) { const r = this.paramsReg(); const params = []; - let res = null; + let res; while ((res = r.exec(name)) !== null) { params.push(res[1]); @@ -100,7 +104,7 @@ const Key = { } } -module.exports = { +export { LangKeys, Key -} +}; diff --git a/packages/keyset/lib/key.js b/packages/keyset/lib/key.js index 33c27624..df5782c9 100644 --- a/packages/keyset/lib/key.js +++ b/packages/keyset/lib/key.js @@ -1,7 +1,5 @@ -'use strict'; - -const assert = require('assert'); -const util = require('util'); +import assert from 'node:assert'; +import util from 'node:util'; class Key { constructor(name, value) { @@ -54,7 +52,7 @@ class PluralKey extends Key { } } -module.exports = { +export { Key, ParamedKey, PluralKey diff --git a/packages/keyset/lib/keyset.js b/packages/keyset/lib/keyset.js index ff94c55c..8b2ae583 100644 --- a/packages/keyset/lib/keyset.js +++ b/packages/keyset/lib/keyset.js @@ -1,17 +1,8 @@ -'use strict'; +import { readdir, readFile, mkdir, unlink, writeFile } from 'node:fs/promises'; +import { resolve, parse, join } from 'node:path'; -const fs = require('fs'); -const { promisify } = require('util'); -const { resolve, parse, join } = require('path'); - -const formats = require('./formats'); -const { LangKeys } = require('./langKeys'); - -const readdir = promisify(fs.readdir); -const readFile = promisify(fs.readFile); -const mkdir = promisify(fs.mkdir); -const unlink = promisify(fs.unlink); -const writeFile = promisify(fs.writeFile); +import formats from './formats/index.js'; +import { LangKeys } from './langKeys.js'; class Keyset { constructor(name, path, format) { @@ -141,11 +132,7 @@ class Keyset { for (let [lang, langKeys] of this.langKeys) { try { const filePath = resolve(this.path, lang + this.langsKeysExt); - try { - await writeFile(filePath, langKeys.stringify(this.format)); - } catch(err) { - throw err; - } + await writeFile(filePath, langKeys.stringify(this.format)); } catch(err) { this.errors.push(err); } @@ -172,17 +159,17 @@ class Keyset { async load() { this.isBroken = false; - let files = []; + let files; try { files = await readdir(resolve(this.path)); } catch(err) { - throw new Error(`${this.path} is not directory`); + throw new Error(`${this.path} is not directory`, { cause: err }); } for (let file of files) { const filePath = resolve(this.path, file); const lang = parse(file).name; - let data = null; + let data; if (lang === 'index') { continue; @@ -190,12 +177,12 @@ class Keyset { try { data = await readFile(filePath, 'utf8'); - } catch(err) { + } catch { this.errors.push(new Error(`${filePath} is broken`)); continue; } - let langKeys = null; + let langKeys; try { langKeys = await LangKeys.parse(data, this.format); langKeys.lang = lang; @@ -224,6 +211,6 @@ class Keyset { Keyset.availableFormats = formats; -module.exports = { +export { Keyset -} +}; diff --git a/packages/keyset/lib/langKeys.js b/packages/keyset/lib/langKeys.js index c0bd61b5..394976f7 100644 --- a/packages/keyset/lib/langKeys.js +++ b/packages/keyset/lib/langKeys.js @@ -1,10 +1,8 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); +import formats from './formats/index.js'; -const formats = require('./formats'); - -const { Key, ParamedKey, PluralKey } = require('./key'); +import { Key, ParamedKey, PluralKey } from './key.js'; class LangKeys { @@ -65,6 +63,6 @@ class LangKeys { } -module.exports = { +export { LangKeys }; diff --git a/packages/keyset/package.json b/packages/keyset/package.json index dcfc2d6d..de74418b 100644 --- a/packages/keyset/package.json +++ b/packages/keyset/package.json @@ -2,14 +2,17 @@ "name": "@bem/sdk.keyset", "version": "0.1.1", "description": "Representation of BEM i18n keyset", + "type": "module", "publishConfig": { "access": "public" }, "main": "index.js", + "engines": { + "node": ">= 24.0" + }, "scripts": { "test": "npm run specs", - "specs": "mocha", - "cover": "nyc mocha" + "specs": "mocha" }, "repository": "bem/bem-sdk", "keywords": [ @@ -28,7 +31,6 @@ "common-tags": "^1.8.0" }, "dependencies": { - "node-eval": "^2.0.0", - "xamel": "^0.3.1" + "fast-xml-parser": "^4.5.3" } } diff --git a/packages/keyset/test/key.test.js b/packages/keyset/test/key.test.js index 4306cf0f..316d5378 100644 --- a/packages/keyset/test/key.test.js +++ b/packages/keyset/test/key.test.js @@ -1,8 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const expect = require('chai').expect; - -const { Key, ParamedKey, PluralKey } = require('..'); +import { Key, ParamedKey, PluralKey } from '../index.js'; describe('Key', () => { @@ -20,11 +18,11 @@ describe('Key', () => { it('should throw with wrong type of key_name', () => { expect(() => { - new Key({ 42 : 42 }, 'Разница во времени'); // eslint-disable-line + new Key({ 42 : 42 }, 'Разница во времени'); }).to.throw(); expect(() => { - new Key(42, 'Разница во времени'); // eslint-disable-line + new Key(42, 'Разница во времени'); }).to.throw(); }); }); @@ -40,7 +38,7 @@ describe('Key', () => { it('should throw if value doesn\'t include param', () => { expect(() => { - new ParamedKey('Time in {city}', 'Точное время {city} {val}', ['city', 'town']); // eslint-disable-line + new ParamedKey('Time in {city}', 'Точное время {city} {val}', ['city', 'town']); }).to.throw('Key: value should include param: town'); }); }); diff --git a/packages/keyset/test/keyset.test.js b/packages/keyset/test/keyset.test.js index 03e23296..979bb812 100644 --- a/packages/keyset/test/keyset.test.js +++ b/packages/keyset/test/keyset.test.js @@ -1,12 +1,10 @@ -'use strict'; +import fs from 'node:fs'; -const fs = require('fs'); +import { stripIndent } from 'common-tags'; +import { expect } from 'chai'; +import mock from 'mock-fs'; -const { stripIndent } = require('common-tags'); -const expect = require('chai').expect; -const mock = require('mock-fs'); - -const { Keyset, Key, ParamedKey, PluralKey, LangKeys } = require('..'); +import { Keyset, Key, ParamedKey, PluralKey, LangKeys } from '../index.js'; describe('Keyset', () => { it('should create Keyset', () => { diff --git a/packages/keyset/test/langKeys.test.js b/packages/keyset/test/langKeys.test.js index 9cb48b9c..caaf9eae 100644 --- a/packages/keyset/test/langKeys.test.js +++ b/packages/keyset/test/langKeys.test.js @@ -1,9 +1,7 @@ -'use strict'; +import { stripIndent, oneLineTrim } from 'common-tags'; +import { expect } from 'chai'; -const { stripIndent, oneLineTrim } = require('common-tags'); -const expect = require('chai').expect; - -const { Key, ParamedKey, PluralKey, LangKeys } = require('..'); +import { Key, ParamedKey, PluralKey, LangKeys } from '../index.js'; describe('LangKeys', () => { it('should create LangKeys', () => { @@ -36,7 +34,7 @@ describe('LangKeys', () => { it('should stringify paramed keys', () => { const langKeys = new LangKeys('ru', [ new Key('Time difference', 'Разница во времени'), - new ParamedKey('Time in {city}', 'Точное время {city}') + new ParamedKey('Time in {city}', 'Точное время {city}') ]); expect(langKeys.stringify('taburet')).to.eql(stripIndent` diff --git a/packages/naming.cell.match/cell-match.js b/packages/naming.cell.match/cell-match.js index e29fd63e..3e269136 100644 --- a/packages/naming.cell.match/cell-match.js +++ b/packages/naming.cell.match/cell-match.js @@ -1,10 +1,8 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const BemCell = require('@bem/sdk.cell'); -const bemNamingParse = require('@bem/sdk.naming.entity.parse'); -const pathPatternParser = require('@bem/sdk.naming.cell.pattern-parser'); +import BemCell from '@bem/sdk.cell'; +import bemNamingParse from '@bem/sdk.naming.entity.parse'; +import pathPatternParser from '@bem/sdk.naming.cell.pattern-parser'; const ALPHANUM_RE = '[A-Za-z][\\w\\-]*'; const resc = s => String(s).replace(/[\\^$*+?.()|[\]{}]/g, '\\$&'); @@ -31,7 +29,7 @@ const SCHEMES = { let i = 1; return entity.block === parts[0] && (!entity.elem || (parts[i++] === elem + entity.elem)) && - (!entity.mod || (parts[i++] == mod + entity.mod.name)); + (!entity.mod || (parts[i] == mod + entity.mod.name)); } ] }; @@ -136,7 +134,7 @@ function buildPathParseMethod(conv) { * @param {BemNamingConvention} conv - naming, path and scheme * @returns {function(string): {cell: ?BemCell, isMatch: boolean, rest: ?string}} converts cell to file path */ -module.exports = (conv = {}) => { +export default (conv = {}) => { assert(conv.fs && typeof conv.fs.pattern === 'string', '@bem/sdk.naming.cell.match: fs.pattern field required in convention'); @@ -146,7 +144,7 @@ module.exports = (conv = {}) => { // Special crunch for nested scheme and empty elem if (conv.fs.delims && conv.fs.delims.elem === '') { const parse1 = parse; - const parse2 = buildPathParseMethod({ ...conv, fs: { ...conv.fs, delims: { ...conv.fs.delims, elem: '💩' } } }); + const parse2 = buildPathParseMethod({ ...conv, fs: { ...conv.fs, delims: { ...conv.fs.delims, elem: '\u{1F4A9}' } } }); parse = (relPath) => parse1(relPath) || parse2(relPath); } diff --git a/packages/naming.cell.match/cell-match.test.js b/packages/naming.cell.match/cell-match.test.js index 9051d471..313ac160 100644 --- a/packages/naming.cell.match/cell-match.test.js +++ b/packages/naming.cell.match/cell-match.test.js @@ -1,10 +1,12 @@ -'use strict'; +import BemCell from '@bem/sdk.cell'; +import { legacy, origin, react } from '@bem/sdk.naming.presets'; +import createMatch from './cell-match.js'; -const safeEval = require('node-eval'); +import { expect } from 'chai'; -const BemCell = require('@bem/sdk.cell'); -const { legacy, origin, react } = require('@bem/sdk.naming.presets'); -const createMatch = require('.'); +function safeEval(code) { + return new Function(`return ${code}`)(); +} const flatLegacyMatch = createMatch(Object.assign({}, legacy, { fs: Object.assign({}, legacy.fs, { scheme: 'flat' }) })); const flatOriginMatch = createMatch(Object.assign({}, origin, { fs: Object.assign({}, origin.fs, { scheme: 'flat' }) })); @@ -17,8 +19,6 @@ const nestedModernMatch = createMatch(Object.assign({}, origin, { fs: Object.ass const nestedModernEmptyElemMatch = createMatch(Object.assign({}, react, { fs: Object.assign({}, react.fs, { scheme: 'nested', pattern: '${entity}${layer?@${layer}}.${tech}' }) })); -const { expect } = require('chai'); - describe('naming.cell.match', () => { for (const [dTitle, [match, its]] of Object.entries({ 'flat / legacy': [flatLegacyMatch, rawses` @@ -190,7 +190,7 @@ function rawses(strings) { return lines .map(line => { - const [ title, relPath, rawExpected ] = line.slice(minLineIndent).split('→').map(s => s.trim()); + const [ title, relPath, rawExpected ] = line.slice(minLineIndent).split('\u2192').map(s => s.trim()); const expected = { cell: null, diff --git a/packages/naming.cell.match/package.json b/packages/naming.cell.match/package.json index ef002a35..f64dc43a 100644 --- a/packages/naming.cell.match/package.json +++ b/packages/naming.cell.match/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.cell.match", "version": "0.1.3", "description": "BemCell parser", + "type": "module", "license": "MPL-2.0", "author": "Alexey Yaroshevich (github.com/zxqfox)", "keywords": [ @@ -13,9 +14,10 @@ ], "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "cell-match.js", + "exports": "./cell-match.js", "files": [ "cell-match.js" ], @@ -28,6 +30,6 @@ "@bem/sdk.naming.presets": "^0.2.3" }, "scripts": { - "test": "nyc mocha *.test.js" + "test": "mocha *.test.js" } } diff --git a/packages/naming.cell.pattern-parser/package.json b/packages/naming.cell.pattern-parser/package.json index fb985ff6..0466544b 100644 --- a/packages/naming.cell.pattern-parser/package.json +++ b/packages/naming.cell.pattern-parser/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.cell.pattern-parser", "version": "0.0.7", "description": "Pattern parser", + "type": "module", "publishConfig": { "access": "public" }, @@ -20,13 +21,13 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/naming.cell.pattern-parser#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "pattern-parser.js", "files": [ "pattern-parser.js" ], "scripts": { - "test": "nyc mocha" + "test": "mocha" } } diff --git a/packages/naming.cell.pattern-parser/pattern-parser.js b/packages/naming.cell.pattern-parser/pattern-parser.js index a45f6b2d..d4e56ead 100644 --- a/packages/naming.cell.pattern-parser/pattern-parser.js +++ b/packages/naming.cell.pattern-parser/pattern-parser.js @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = (pattern) => { +const patternParser = (pattern) => { const separation = []; let ref = { separation }; @@ -47,3 +45,5 @@ module.exports = (pattern) => { return separation; }; + +export default patternParser; diff --git a/packages/naming.cell.pattern-parser/test/pattern-parser.test.js b/packages/naming.cell.pattern-parser/test/pattern-parser.test.js index 42e09248..d7d4bf60 100644 --- a/packages/naming.cell.pattern-parser/test/pattern-parser.test.js +++ b/packages/naming.cell.pattern-parser/test/pattern-parser.test.js @@ -1,8 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const expect = require('chai').expect; - -const method = require('..'); +import method from '../pattern-parser.js'; describe('pattern-parser', () => { it('should throw on incorrect pattern', () => { diff --git a/packages/naming.cell.stringify/cell-stringify.js b/packages/naming.cell.stringify/cell-stringify.js index e29e2663..acd6aa3b 100644 --- a/packages/naming.cell.stringify/cell-stringify.js +++ b/packages/naming.cell.stringify/cell-stringify.js @@ -1,9 +1,7 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const bemNaming = require('@bem/sdk.naming.entity'); -const pathPatternParser = require('@bem/sdk.naming.cell.pattern-parser'); +import bemNaming from '@bem/sdk.naming.entity'; +import pathPatternParser from '@bem/sdk.naming.cell.pattern-parser'; const buildPathStringifyMethod = (pattern, defaultLayer) => { const separation = pathPatternParser(pattern); @@ -35,7 +33,7 @@ const buildPathStringifyMethod = (pattern, defaultLayer) => { * @param {INamingConvention} conv - naming, path and scheme * @returns {function(BemCell): string} converts cell to file path */ -module.exports = (conv) => { +export default (conv) => { assert(typeof conv === 'object', '@bem/sdk.naming.cell.stringify: convention object required'); assert(typeof Object(conv.fs).pattern === 'string', diff --git a/packages/naming.cell.stringify/lib/schemes/flat.js b/packages/naming.cell.stringify/lib/schemes/flat.js index ea1a31c9..36436f39 100644 --- a/packages/naming.cell.stringify/lib/schemes/flat.js +++ b/packages/naming.cell.stringify/lib/schemes/flat.js @@ -1,13 +1,11 @@ -'use strict'; +import path from 'node:path'; +import assert from 'node:assert'; +import BemCell from '@bem/sdk.cell'; +import bemNaming from '@bem/sdk.naming.entity'; -var path = require('path'); -var assert = require('assert'); -var BemCell = require('@bem/sdk.cell'); -var bemNaming = require('@bem/sdk.naming.entity'); +import presets from '../presets.js'; -var presets = require('../presets'); - -module.exports = { +export default { path: function(cell, options) { assert(BemCell.isBemCell(cell), 'Provide instance of [@bem/sdk.cell](https://github.com/bem/bem-sdk/tree/master/packages/cell).' @@ -17,7 +15,6 @@ module.exports = { var b_; if (!options) { - opts = presets['origin']; b_ = bemNaming; } else if (typeof options === 'string') { var preset = presets[options]; diff --git a/packages/naming.cell.stringify/lib/schemes/nested.js b/packages/naming.cell.stringify/lib/schemes/nested.js index 8b116cc3..e2db4ecd 100644 --- a/packages/naming.cell.stringify/lib/schemes/nested.js +++ b/packages/naming.cell.stringify/lib/schemes/nested.js @@ -1,13 +1,11 @@ -'use strict'; +import path from 'node:path'; +import assert from 'node:assert'; +import BemCell from '@bem/sdk.cell'; +import bemNaming from '@bem/sdk.naming.entity'; -var path = require('path'); -var assert = require('assert'); -var BemCell = require('@bem/sdk.cell'); -var bemNaming = require('@bem/sdk.naming.entity'); +import presets from '../presets.js'; -var presets = require('../presets'); - -module.exports = { +export default { path: function(cell, options) { assert(BemCell.isBemCell(cell), 'Provide instance of [@bem/sdk.cell](https://github.com/bem/bem-sdk/tree/master/packages/cell).' diff --git a/packages/naming.cell.stringify/package.json b/packages/naming.cell.stringify/package.json index f62b7880..2ee769e7 100644 --- a/packages/naming.cell.stringify/package.json +++ b/packages/naming.cell.stringify/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.cell.stringify", "version": "0.0.13", "description": "BemCell stringifier (aka @bem/fs-scheme/path)", + "type": "module", "publishConfig": { "access": "public" }, @@ -19,7 +20,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/naming.cell.stringify#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "cell-stringify.js", "files": [ @@ -33,6 +34,6 @@ "@bem/sdk.naming.entity": "^0.2.11" }, "scripts": { - "test": "nyc mocha" + "test": "mocha" } } diff --git a/packages/naming.cell.stringify/test/cell-stringify.test.js b/packages/naming.cell.stringify/test/cell-stringify.test.js index 292486fc..f1d3d393 100644 --- a/packages/naming.cell.stringify/test/cell-stringify.test.js +++ b/packages/naming.cell.stringify/test/cell-stringify.test.js @@ -1,9 +1,7 @@ -'use strict'; +import { expect } from 'chai'; +import BemCell from '@bem/sdk.cell'; -const expect = require('chai').expect; -const BemCell = require('@bem/sdk.cell'); - -const method = require('..'); +import method from '../cell-stringify.js'; const button = BemCell.create({ block: 'button', tech: 'css' }); const buttonCommon = BemCell.create({ block: 'button', layer: 'common', tech: 'css' }); diff --git a/packages/naming.cell.stringify/test/mocha.opts b/packages/naming.cell.stringify/test/mocha.opts deleted file mode 100644 index 0d112102..00000000 --- a/packages/naming.cell.stringify/test/mocha.opts +++ /dev/null @@ -1,2 +0,0 @@ ---inline-diffs ---reporter spec diff --git a/packages/naming.entity.parse/benchmark/parse.bench.js b/packages/naming.entity.parse/benchmark/parse.bench.js index e0c766f5..8160a5fb 100644 --- a/packages/naming.entity.parse/benchmark/parse.bench.js +++ b/packages/naming.entity.parse/benchmark/parse.bench.js @@ -1,12 +1,11 @@ -'use strict'; +import naming from '../index.js'; -var naming = require('../index'), - strings = { - block: 'block', - blockMod: 'block_mod-name_mod-val', - elem: 'block__elem', - elemMod: 'block__elem_mod-name_mod-val' - }; +const strings = { + block: 'block', + blockMod: 'block_mod-name_mod-val', + elem: 'block__elem', + elemMod: 'block__elem_mod-name_mod-val' +}; suite('parse', function () { set('iterations', 2000000); diff --git a/packages/naming.entity.parse/index.js b/packages/naming.entity.parse/index.js index 3aee7da4..3098f3d0 100644 --- a/packages/naming.entity.parse/index.js +++ b/packages/naming.entity.parse/index.js @@ -1,6 +1,4 @@ -'use strict'; - -const BemEntityName = require('@bem/sdk.entity-name'); +import BemEntityName from '@bem/sdk.entity-name'; /** * Builds regex for specified naming convention. @@ -49,7 +47,7 @@ function parse(str, regex) { * @param {INamingConvention} convention - options for naming convention. * @returns {Function} */ -module.exports = (convention) => { +export default (convention) => { const regex = buildRegex(convention.delims, convention.wordPattern); return (str) => parse(str, regex); diff --git a/packages/naming.entity.parse/package.json b/packages/naming.entity.parse/package.json index 5af981bc..57859bfc 100644 --- a/packages/naming.entity.parse/package.json +++ b/packages/naming.entity.parse/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.entity.parse", "version": "0.2.9", "description": "Parses slugs of BEM entities", + "type": "module", "publishConfig": { "access": "public" }, @@ -21,7 +22,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/naming.entity.parse#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "index.js", "files": [ diff --git a/packages/naming.entity.stringify/benchmark/stringify.bench.js b/packages/naming.entity.stringify/benchmark/stringify.bench.js index 52d1bbc8..80f69f0b 100644 --- a/packages/naming.entity.stringify/benchmark/stringify.bench.js +++ b/packages/naming.entity.stringify/benchmark/stringify.bench.js @@ -1,12 +1,11 @@ -'use strict'; +import naming from '../index.js'; -var naming = require('../index'), - notations = { - block: { block: 'block' }, - blockMod: { block: 'block', mod: { name: 'mod-name', val: 'mod-val' } }, - elem: { block: 'block', elem: 'elem' }, - elemMod: { block: 'block', elem: 'elem', mod: { name: 'mod-name', val: 'mod-val' } } - }; +var notations = { + block: { block: 'block' }, + blockMod: { block: 'block', mod: { name: 'mod-name', val: 'mod-val' } }, + elem: { block: 'block', elem: 'elem' }, + elemMod: { block: 'block', elem: 'elem', mod: { name: 'mod-name', val: 'mod-val' } } +}; suite('stringify', function () { set('iterations', 2000000); diff --git a/packages/naming.entity.stringify/index.d.ts b/packages/naming.entity.stringify/index.d.ts index ff740fbf..74404f59 100644 --- a/packages/naming.entity.stringify/index.d.ts +++ b/packages/naming.entity.stringify/index.d.ts @@ -1,7 +1,5 @@ -declare module '@bem/sdk.naming.entity.stringify' { - import { INamingConvention } from '@bem/sdk.naming.presets'; - import { EntityName } from '@bem/sdk.entity-name'; +import { INamingConvention } from '@bem/sdk.naming.presets'; +import { IOptions } from '@bem/sdk.entity-name'; - export type Stringify = (entity: EntityName.IOptions) => string; - export function stringifyWrapper(convention: INamingConvention): Stringify; -} +export type Stringify = (entity: IOptions) => string; +export default function stringifyWrapper(convention: INamingConvention): Stringify; diff --git a/packages/naming.entity.stringify/index.js b/packages/naming.entity.stringify/index.js index 90dbc63c..a879e722 100644 --- a/packages/naming.entity.stringify/index.js +++ b/packages/naming.entity.stringify/index.js @@ -1,5 +1,3 @@ -'use strict'; - /** * Forms a string according to object representation of BEM entity. * @@ -50,5 +48,5 @@ function stringifyWrapper(convention) { }; } -module.exports = stringifyWrapper; -module.exports.stringifyWrapper = stringifyWrapper; +export default stringifyWrapper; +export { stringifyWrapper }; diff --git a/packages/naming.entity.stringify/package.json b/packages/naming.entity.stringify/package.json index b9fa4d14..d9f39dfc 100644 --- a/packages/naming.entity.stringify/package.json +++ b/packages/naming.entity.stringify/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.entity.stringify", "version": "1.1.2", "description": "Stringifier for BEM entities", + "type": "module", "publishConfig": { "access": "public" }, @@ -21,7 +22,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/naming.entity.stringify#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "index.js", "files": [ @@ -31,11 +32,10 @@ ], "devDependencies": { "@bem/sdk.entity-name": "^0.2.11", - "@bem/sdk.naming.presets": "^0.0.9" + "@bem/sdk.naming.presets": "^0.2.3" }, "scripts": { - "test": "nyc mocha", - "bench": "matcha benchmark/*.js" + "test": "mocha" }, "typings": "index.d.ts" } diff --git a/packages/naming.entity.stringify/test/stringify.test.js b/packages/naming.entity.stringify/test/stringify.test.js index 32e1257f..d8d4290f 100644 --- a/packages/naming.entity.stringify/test/stringify.test.js +++ b/packages/naming.entity.stringify/test/stringify.test.js @@ -1,10 +1,10 @@ -'use strict'; +import { expect } from 'chai'; +import BemEntityName from '@bem/sdk.entity-name'; -const expect = require('chai').expect; -const BemEntityName = require('@bem/sdk.entity-name'); +import originNaming from '@bem/sdk.naming.presets/origin'; +import stringifyWrapper from '../index.js'; -const originNaming = require('@bem/sdk.naming.presets/origin'); -const stringify = require('..')(originNaming); +const stringify = stringifyWrapper(originNaming); describe('naming.entity.stringify', () => { it('should not stringify not valid notation', () => { diff --git a/packages/naming.entity/index.js b/packages/naming.entity/index.js index c4072b3d..84867d4c 100644 --- a/packages/naming.entity/index.js +++ b/packages/naming.entity/index.js @@ -1,5 +1,3 @@ -'use strict'; - /** * Delims of bem entity, elem and/or mod. * @@ -19,9 +17,9 @@ * element and modifier's names. */ -const createStringify = require('@bem/sdk.naming.entity.stringify'); -const createParse = require('@bem/sdk.naming.entity.parse'); -const createPreset = require('@bem/sdk.naming.presets/create'); +import createStringify from '@bem/sdk.naming.entity.stringify'; +import createParse from '@bem/sdk.naming.entity.parse'; +import createPreset from '@bem/sdk.naming.presets/create'; /** * It is necessary not to create new instances for the same custom naming. @@ -61,4 +59,4 @@ function createNaming(options) { return namespace; } -module.exports = Object.assign(createNaming, createNaming()); +export default Object.assign(createNaming, createNaming()); diff --git a/packages/naming.entity/package.json b/packages/naming.entity/package.json index 391387f0..692aa601 100644 --- a/packages/naming.entity/package.json +++ b/packages/naming.entity/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.entity", "version": "0.2.11", "description": "Manage naming of BEM entities", + "type": "module", "publishConfig": { "access": "public" }, @@ -26,7 +27,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/naming.entity#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "index.js", "files": [ @@ -41,7 +42,6 @@ }, "scripts": { "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" } } diff --git a/packages/naming.entity/test/cache.test.js b/packages/naming.entity/test/cache.test.js index 4a90fca7..e0d9939f 100644 --- a/packages/naming.entity/test/cache.test.js +++ b/packages/naming.entity/test/cache.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const naming = require('../index'); +import naming from '../index.js'; describe('cache.test.js', () => { it('should cache instance of original naming', () => { diff --git a/packages/naming.entity/test/defaults.test.js b/packages/naming.entity/test/defaults.test.js index 0883e46a..37c1e3ef 100644 --- a/packages/naming.entity/test/defaults.test.js +++ b/packages/naming.entity/test/defaults.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const naming = require('..'); +import naming from '../index.js'; describe('defaults.test.js', () => { it.skip('should be elem delim by default', () => { diff --git a/packages/naming.entity/test/fields.test.js b/packages/naming.entity/test/fields.test.js index 067d83f1..1cfb876b 100644 --- a/packages/naming.entity/test/fields.test.js +++ b/packages/naming.entity/test/fields.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const naming = require('../index'); +import naming from '../index.js'; describe('fields.test.js', () => { it('should have elem delim field', () => { diff --git a/packages/naming.entity/test/namespace.test.js b/packages/naming.entity/test/namespace.test.js index 53da652e..05c763c6 100644 --- a/packages/naming.entity/test/namespace.test.js +++ b/packages/naming.entity/test/namespace.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const bemNaming = require('../index'); +import bemNaming from '../index.js'; describe('namespace.test.js', () => { it('should be a namespace', () => { diff --git a/packages/naming.entity/test/options.test.js b/packages/naming.entity/test/options.test.js index ba441b26..e87660d0 100644 --- a/packages/naming.entity/test/options.test.js +++ b/packages/naming.entity/test/options.test.js @@ -1,11 +1,6 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; - -const naming = require('../index'); +import naming from '../index.js'; describe('options.test.js', () => { it('should throw error if specified preset is unknow', () => { diff --git a/packages/naming.file.stringify/file-stringify.js b/packages/naming.file.stringify/file-stringify.js index ad8e226d..03ecc16b 100644 --- a/packages/naming.file.stringify/file-stringify.js +++ b/packages/naming.file.stringify/file-stringify.js @@ -1,8 +1,6 @@ -'use strict'; +import assert from 'node:assert'; -const assert = require('assert'); - -const createCellStringify = require('@bem/sdk.naming.cell.stringify'); +import createCellStringify from '@bem/sdk.naming.cell.stringify'; /** * Stringifier generator @@ -10,7 +8,7 @@ const createCellStringify = require('@bem/sdk.naming.cell.stringify'); * @param {INamingConvention} conv - naming, path and scheme * @returns {function(BemCell): string} converts cell to file path */ -module.exports = (conv) => { +export default (conv) => { assert(typeof conv === 'object', '@bem/sdk.naming.file.stringify: convention object required'); const stringify = createCellStringify(conv); diff --git a/packages/naming.file.stringify/package.json b/packages/naming.file.stringify/package.json index 8779ea87..d5dbf690 100644 --- a/packages/naming.file.stringify/package.json +++ b/packages/naming.file.stringify/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.file.stringify", "version": "0.1.11", "description": "BemFile stringifier (aka @bem/fs-scheme/path)", + "type": "module", "publishConfig": { "access": "public" }, @@ -19,7 +20,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/naming.file.stringify#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "dependencies": { "@bem/sdk.naming.cell.stringify": "^0.0.13" @@ -32,6 +33,6 @@ "file-stringify.js" ], "scripts": { - "test": "nyc mocha" + "test": "mocha" } } diff --git a/packages/naming.file.stringify/test/file-stringify.test.js b/packages/naming.file.stringify/test/file-stringify.test.js index a27b24fc..ba003fd7 100644 --- a/packages/naming.file.stringify/test/file-stringify.test.js +++ b/packages/naming.file.stringify/test/file-stringify.test.js @@ -1,9 +1,7 @@ -'use strict'; +import { expect } from 'chai'; +import BemFile from '@bem/sdk.file'; -const expect = require('chai').expect; -const BemFile = require('@bem/sdk.file'); - -const method = require('..'); +import method from '../file-stringify.js'; const f = (cell, level) => (new BemFile({ cell, level })); diff --git a/packages/naming.presets/create.js b/packages/naming.presets/create.js index 5d5fdbe0..4ae1b3da 100644 --- a/packages/naming.presets/create.js +++ b/packages/naming.presets/create.js @@ -1,38 +1,34 @@ -'use strict'; +import * as presets from './index.js'; -var presets = require('.'); - -var DEFAULT_PRESET = 'origin'; - -module.exports = init; +const DEFAULT_PRESET = 'origin'; /** * Returns an object with `delims`, `fs` and `wordPattern` properties * that describes the naming convention. * - * @param {(Object|string)} [options] — user options or preset name. + * @param {(Object|string)} [options] - user options or preset name. * If not specified, default preset will be returned. - * @param {string} [options.preset] — preset name that should be used as default preset. - * @param {Object} [options.delims] — strings to separate names of bem entities. + * @param {string} [options.preset] - preset name that should be used as default preset. + * @param {Object} [options.delims] - strings to separate names of bem entities. * This object has the same structure with `INamingConventionDelims`, * but all properties inside are optional. - * @param {Object} [options.fs] — user options to separate names of files with bem entities. - * @param {Object} [options.fs.delims] — strings to separate names of files in a BEM project. + * @param {Object} [options.fs] - user options to separate names of files with bem entities. + * @param {Object} [options.fs.delims] - strings to separate names of files in a BEM project. * This object has the same structure with `INamingConventionDelims`, * but all properties inside are optional. - * @param {string} [options.fs.pattern] — pattern that describes the file structure of a BEM project.s - * @param {string} [options.fs.scheme] — schema name that describes the file structure of one BEM entity. - * @param {string} [options.wordPattern] — a regular expression that will be used to match an entity name. - * @param {(Object|string)} [userDefaults] — default options that will override the options from default preset. + * @param {string} [options.fs.pattern] - pattern that describes the file structure of a BEM project.s + * @param {string} [options.fs.scheme] - schema name that describes the file structure of one BEM entity. + * @param {string} [options.wordPattern] - a regular expression that will be used to match an entity name. + * @param {(Object|string)} [userDefaults] - default options that will override the options from default preset. * @returns {INamingConvention} */ -function init(options, userDefaults) { +export default function init(options, userDefaults) { if (!options) { return presets[DEFAULT_PRESET]; } if (typeof options === 'string') { - var preset = presets[options]; + const preset = presets[options]; if (!preset) { throw new Error('The `' + options + '` naming is unknown.'); @@ -41,7 +37,7 @@ function init(options, userDefaults) { return preset; } - var defaultPreset = options.preset || DEFAULT_PRESET; + const defaultPreset = options.preset || DEFAULT_PRESET; // TODO: Warn about incorrect preset if (typeof userDefaults === 'string') { @@ -50,11 +46,11 @@ function init(options, userDefaults) { userDefaults = {}; } - var defaults = presets[defaultPreset]; - var defaultDelims = userDefaults.delims || defaults.delims; - var defaultModDelims = userDefaults.mod || defaultDelims.mod; - var optionsDelims = options.delims || {}; - var mod = optionsDelims.mod || defaultModDelims; + const defaults = presets[defaultPreset]; + const defaultDelims = userDefaults.delims || defaults.delims; + const defaultModDelims = userDefaults.mod || defaultDelims.mod; + const optionsDelims = options.delims || {}; + const mod = optionsDelims.mod || defaultModDelims; const res = { delims: { diff --git a/packages/naming.presets/index.d.ts b/packages/naming.presets/index.d.ts index 014e73a1..b87df531 100644 --- a/packages/naming.presets/index.d.ts +++ b/packages/naming.presets/index.d.ts @@ -1,23 +1,21 @@ -declare module '@bem/sdk.naming.presets' { - interface INamingConventionDelims { - elem: string; - mod: string | { - name: string; - val: string; - }; - } +interface INamingConventionDelims { + elem: string; + mod: string | { + name: string; + val: string; + }; +} - export interface INamingConvention { +export interface INamingConvention { + delims: INamingConventionDelims; + fs: { + pattern: string; + scheme: string; delims: INamingConventionDelims; - fs: { - pattern: string; - scheme: string; - delims: INamingConventionDelims; - }; - wordPattern: string; - } - - // TODO: Add export for two-dashes (https://github.com/bem/bem-sdk/issues/315) - export const react: INamingConvention; - export const origin: INamingConvention; + }; + wordPattern: string; } + +// TODO: Add export for two-dashes (https://github.com/bem/bem-sdk/issues/315) +export const react: INamingConvention; +export const origin: INamingConvention; diff --git a/packages/naming.presets/index.js b/packages/naming.presets/index.js index 4a06d14d..843da417 100644 --- a/packages/naming.presets/index.js +++ b/packages/naming.presets/index.js @@ -1,9 +1,10 @@ -'use strict'; +export { default } from './legacy.js'; +export { default as legacy } from './legacy.js'; +export { default as origin } from './origin.js'; +export { default as react } from './react.js'; -exports.default = require('./legacy'); +import originReact from './origin-react.js'; +import twoDashes from './two-dashes.js'; -exports.legacy = require('./legacy'); -exports.origin = require('./origin'); -exports.react = require('./react'); -exports['origin-react'] = require('./origin-react'); -exports['two-dashes'] = require('./two-dashes'); +export { originReact as 'origin-react' }; +export { twoDashes as 'two-dashes' }; diff --git a/packages/naming.presets/legacy.js b/packages/naming.presets/legacy.js index d65119d0..ec52c690 100644 --- a/packages/naming.presets/legacy.js +++ b/packages/naming.presets/legacy.js @@ -1,8 +1,6 @@ -'use strict'; +import origin from './origin.js'; -const origin = require('./origin'); - -module.exports = Object.assign({}, origin, { +export default Object.assign({}, origin, { fs: Object.assign({}, origin.fs, { pattern: '${entity}${layer?@${layer}}.${tech}', }) diff --git a/packages/naming.presets/origin-react.js b/packages/naming.presets/origin-react.js index 761ff2cf..569cde24 100644 --- a/packages/naming.presets/origin-react.js +++ b/packages/naming.presets/origin-react.js @@ -1,8 +1,6 @@ -'use strict'; +import origin from './origin.js'; -const origin = require('./origin'); - -module.exports = Object.assign({}, origin, { +export default Object.assign({}, origin, { delims: Object.assign({}, origin.delims, { elem: '-' }), diff --git a/packages/naming.presets/origin.js b/packages/naming.presets/origin.js index bbbf2959..966f69da 100644 --- a/packages/naming.presets/origin.js +++ b/packages/naming.presets/origin.js @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +export default { delims: { elem: '__', mod: { name: '_', val: '_' } diff --git a/packages/naming.presets/package.json b/packages/naming.presets/package.json index 71f1c9fc..0f6d46ad 100644 --- a/packages/naming.presets/package.json +++ b/packages/naming.presets/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.naming.presets", "version": "0.2.3", "description": "Presets for naming", + "type": "module", "publishConfig": { "access": "public" }, @@ -30,15 +31,30 @@ "@bem/sdk.naming.entity": "^0.2.11" }, "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "index.js", + "exports": { + ".": "./index.js", + "./create": "./create.js", + "./create.js": "./create.js", + "./origin": "./origin.js", + "./origin.js": "./origin.js", + "./origin-react": "./origin-react.js", + "./origin-react.js": "./origin-react.js", + "./react": "./react.js", + "./react.js": "./react.js", + "./legacy": "./legacy.js", + "./legacy.js": "./legacy.js", + "./two-dashes": "./two-dashes.js", + "./two-dashes.js": "./two-dashes.js" + }, "typings": "index.d.ts", "files": [ "*.js", "index.d.ts" ], "scripts": { - "test": "nyc mocha" + "test": "mocha" } } diff --git a/packages/naming.presets/react.js b/packages/naming.presets/react.js index 11e9cf75..71fc67d5 100644 --- a/packages/naming.presets/react.js +++ b/packages/naming.presets/react.js @@ -1,9 +1,7 @@ -'use strict'; +import base from './origin-react.js'; -const base = require('./origin-react'); - -module.exports = Object.assign({}, base, { - fs: Object.assign(base.fs, { +export default Object.assign({}, base, { + fs: Object.assign({}, base.fs, { pattern: '${entity}${layer?@${layer}}.${tech}' }) }); diff --git a/packages/naming.presets/test/cell.test.js b/packages/naming.presets/test/cell.test.js index fd60c051..42cca5ca 100644 --- a/packages/naming.presets/test/cell.test.js +++ b/packages/naming.presets/test/cell.test.js @@ -1,13 +1,11 @@ -'use strict'; +import { expect } from 'chai'; -const expect = require('chai').expect; +import BemCell from '@bem/sdk.cell'; +import BemEntityName from '@bem/sdk.entity-name'; -const BemCell = require('@bem/sdk.cell'); -const BemEntityName = require('@bem/sdk.entity-name'); +import createStringify from '@bem/sdk.naming.cell.stringify'; -const createStringify = require('@bem/sdk.naming.cell.stringify'); - -const presets = require('..'); +import * as presets from '../index.js'; const createPreset = (name, fsConv, conv) => { const res = Object.assign({}, presets[name], conv); diff --git a/packages/naming.presets/test/mocha.opts b/packages/naming.presets/test/mocha.opts deleted file mode 100644 index 4a523201..00000000 --- a/packages/naming.presets/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---recursive diff --git a/packages/naming.presets/test/origin/parse.test.js b/packages/naming.presets/test/origin/parse.test.js index 60e837fb..157053cc 100644 --- a/packages/naming.presets/test/origin/parse.test.js +++ b/packages/naming.presets/test/origin/parse.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const naming = require('@bem/sdk.naming.entity')('origin'); -const parse = naming.parse; +import { assert } from 'chai'; +import naming from '@bem/sdk.naming.entity'; +const parse = naming('origin').parse; describe('origin parse', () => { it('should not parse not valid string', () => { diff --git a/packages/naming.presets/test/origin/stringify.test.js b/packages/naming.presets/test/origin/stringify.test.js index 4a6c6400..4e332141 100644 --- a/packages/naming.presets/test/origin/stringify.test.js +++ b/packages/naming.presets/test/origin/stringify.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const naming = require('@bem/sdk.naming.entity')('origin'); -const stringify = naming.stringify; +import { assert } from 'chai'; +import naming from '@bem/sdk.naming.entity'; +const stringify = naming('origin').stringify; describe('origin stringify', () => { it('should stringify block', () => { diff --git a/packages/naming.presets/test/react/parse.test.js b/packages/naming.presets/test/react/parse.test.js index 68585a44..80f4b1df 100644 --- a/packages/naming.presets/test/react/parse.test.js +++ b/packages/naming.presets/test/react/parse.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const naming = require('@bem/sdk.naming.entity')('react'); -const parse = naming.parse; +import { assert } from 'chai'; +import naming from '@bem/sdk.naming.entity'; +const parse = naming('react').parse; describe('react parse', () => { it('should not parse not valid string', () => { diff --git a/packages/naming.presets/test/react/stringify.test.js b/packages/naming.presets/test/react/stringify.test.js index c2ca5a9e..3916a231 100644 --- a/packages/naming.presets/test/react/stringify.test.js +++ b/packages/naming.presets/test/react/stringify.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const naming = require('@bem/sdk.naming.entity')('react'); -const stringify = naming.stringify; +import { assert } from 'chai'; +import naming from '@bem/sdk.naming.entity'; +const stringify = naming('react').stringify; describe('react stringify', () => { it('should stringify block', () => { diff --git a/packages/naming.presets/test/two-dashes/parse.test.js b/packages/naming.presets/test/two-dashes/parse.test.js index 6579ecc2..cd928251 100644 --- a/packages/naming.presets/test/two-dashes/parse.test.js +++ b/packages/naming.presets/test/two-dashes/parse.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const naming = require('@bem/sdk.naming.entity')('two-dashes'); -const parse = naming.parse; +import { assert } from 'chai'; +import naming from '@bem/sdk.naming.entity'; +const parse = naming('two-dashes').parse; describe('two-dashes parse', () => { it('should not parse not valid string', () => { diff --git a/packages/naming.presets/test/two-dashes/stringify.test.js b/packages/naming.presets/test/two-dashes/stringify.test.js index 182d282d..3207ea10 100644 --- a/packages/naming.presets/test/two-dashes/stringify.test.js +++ b/packages/naming.presets/test/two-dashes/stringify.test.js @@ -1,8 +1,6 @@ -'use strict'; - -const assert = require('chai').assert; -const naming = require('@bem/sdk.naming.entity')('two-dashes'); -const stringify = naming.stringify; +import { assert } from 'chai'; +import naming from '@bem/sdk.naming.entity'; +const stringify = naming('two-dashes').stringify; describe('two-dashes stringify', () => { it('should stringify block', () => { diff --git a/packages/naming.presets/two-dashes.js b/packages/naming.presets/two-dashes.js index b45174ce..b51e35bd 100644 --- a/packages/naming.presets/two-dashes.js +++ b/packages/naming.presets/two-dashes.js @@ -1,8 +1,6 @@ -'use strict'; +import origin from './origin.js'; -const origin = require('./origin'); - -module.exports = Object.assign({}, origin, { +export default Object.assign({}, origin, { delims: { elem: '__', mod: { name: '--', val: '_' } diff --git a/packages/walk/bench/enb.js b/packages/walk/bench/enb.js index 04c72392..96f4c34b 100644 --- a/packages/walk/bench/enb.js +++ b/packages/walk/bench/enb.js @@ -1,10 +1,8 @@ -'use strict'; +import vow from 'vow'; +import Level from 'enb/lib/levels/level'; +import LevelPlain from 'enb/lib/levels/level-plain'; -const vow = require('vow'); -const Level = require('enb/lib/levels/level'); -const LevelPlain = require('enb/lib/levels/level-plain'); - -module.exports = function run(levels, scheme, done) { +export default function run(levels, scheme, done) { var plain = scheme === 'flat' ? LevelPlain : null; vow.all(levels.map(function (level) { diff --git a/packages/walk/bench/fixtures/index.js b/packages/walk/bench/fixtures/index.js index 95c24496..a5982734 100644 --- a/packages/walk/bench/fixtures/index.js +++ b/packages/walk/bench/fixtures/index.js @@ -1,6 +1,9 @@ -'use strict'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -const path = require('path'); const levels = path.resolve(__dirname, 'levels'); const libs = path.resolve(__dirname, 'libs'); const fixtures = { @@ -38,4 +41,4 @@ const fixtures = { fixtures.libs.o2 = [].concat(fixtures.libs['bem-core'], fixtures.libs['bem-components']); -module.exports = fixtures; +export default fixtures; diff --git a/packages/walk/bench/run.js b/packages/walk/bench/run.js index 6bf959e3..9a6a234f 100644 --- a/packages/walk/bench/run.js +++ b/packages/walk/bench/run.js @@ -1,17 +1,15 @@ -'use strict'; +import fs from 'node:fs'; +import stream from 'node:stream'; -const fs = require('fs'); -const stream = require('stream'); +import Benchmark from 'Benchmark'; +import series from 'promise-map-series'; +import { stringify as stringifyEntity } from '@bem/naming'; -const Benchmark = require('Benchmark'); -const series = require('promise-map-series'); -const stringifyEntity = require('@bem/naming').stringify; +import fixtures from './fixtures/index.js'; -const fixtures = require('./fixtures'); - -const walk = require('../lib'); -const enb = require('./enb'); -const scanl = require('./scan-level'); +import walk from '../lib/index.js'; +import enb from './enb.js'; +import scanl from './scan-level.js'; const cases = [ { name: 'flat level', levels: fixtures.levels.flat, scheme: 'flat' }, diff --git a/packages/walk/bench/scan-level.js b/packages/walk/bench/scan-level.js index a9566b88..30ae8527 100644 --- a/packages/walk/bench/scan-level.js +++ b/packages/walk/bench/scan-level.js @@ -1,8 +1,6 @@ -'use strict'; +import scan from 'scan-level'; -var scan = require('scan-level'); - -module.exports = function run(levels, scheme, done) { +export default function run(levels, scheme, done) { var opts = {}; if (scheme === 'flat') { diff --git a/packages/walk/lib/index.js b/packages/walk/lib/index.js index bc250e49..be568b3c 100644 --- a/packages/walk/lib/index.js +++ b/packages/walk/lib/index.js @@ -1,15 +1,16 @@ -'use strict'; +import { Readable } from 'node:stream'; -const { Readable } = require('stream'); -const each = require('async-each'); -const deprecate = require('depd')('@bem/sdk.walk'); - -const Config = require('@bem/sdk.config'); -const namingCreate = require('@bem/sdk.naming.presets/create'); -const walkers = require('./walkers'); +import Config from '@bem/sdk.config'; +import namingCreate from '@bem/sdk.naming.presets/create'; +import walkers from './walkers/index.js'; const legacycallLayerName = 'legacycall'; +const _warned = new Set(); +function deprecate(msg) { + if (!_warned.has(msg)) { _warned.add(msg); process.emitWarning(msg, 'DeprecationWarning'); } +} + /** * Legacy callback for walker. * @@ -23,7 +24,7 @@ const legacycallLayerName = 'legacycall'; * * @returns {module:stream.Readable} stream with info about found files and directories. */ -module.exports = (levels, options) => { +const bemWalk = (levels, options) => { if (!levels || !levels.length) { const output = new Readable({ objectMode: true, read() {} }); output.push(null); @@ -31,7 +32,7 @@ module.exports = (levels, options) => { } const config = {...(options || {})}; - const defaults = config.defaults = {...(config.defaults || {})}; // eslint-disable-line + const defaults = config.defaults = {...(config.defaults || {})}; defaults.sets = {...(defaults.sets || {})}; @@ -50,7 +51,7 @@ module.exports = (levels, options) => { // const defaultScheme = defaultNaming.scheme || defaults.scheme; // const defaultWalker = (typeof defaultScheme === 'string' ? walkers[defaultScheme] : defaultScheme) || walkers.sdk; - return module.exports.walk({ sets: legacycallLayerName, config }); + return bemWalk.walk({ sets: legacycallLayerName, config }); }; // TODO: V KONFIG @@ -70,7 +71,7 @@ Config.create = function(config) { * * @returns {module:stream.Readable} stream with info about found files and directories. */ -module.exports.walk = ({ /*levels,*/ sets, config: userConfig }) => { +bemWalk.walk = ({ /*levels,*/ sets, config: userConfig }) => { const walkConfig = Config.create(userConfig); const output = new Readable({ objectMode: true, read() {} }); @@ -111,11 +112,27 @@ module.exports.walk = ({ /*levels,*/ sets, config: userConfig }) => { // object[] levelsForWalk .then(levels => { - each(levels, scan, err => { - err - ? output.emit('error', err) - : output.push(null); - }); + if (levels.length === 0) { + output.push(null); + return; + } + + let completed = 0; + let errored = false; + + for (const level of levels) { + scan(level, (err) => { + if (errored) return; + if (err) { + errored = true; + output.emit('error', err); + return; + } + if (++completed === levels.length) { + output.push(null); + } + }); + } }) .catch(error => output.emit('error', error)); @@ -127,12 +144,16 @@ module.exports.walk = ({ /*levels,*/ sets, config: userConfig }) => { * * @returns {Promise} */ -module.exports.asArray = function(...args) { +bemWalk.asArray = function(...args) { return new Promise((resolve, reject) => { const files = []; - module.exports(...args) + bemWalk(...args) .on('data', file => files.push(file)) .on('error', reject) .on('end', () => resolve(files)); }); }; + +export default bemWalk; +export const walk = bemWalk.walk; +export const asArray = bemWalk.asArray; diff --git a/packages/walk/lib/walkers/flat.js b/packages/walk/lib/walkers/flat.js index d5b9223b..8ddc2981 100644 --- a/packages/walk/lib/walkers/flat.js +++ b/packages/walk/lib/walkers/flat.js @@ -1,11 +1,9 @@ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; -const fs = require('fs'); -const path = require('path'); - -const namingEntityParse = require('@bem/sdk.naming.entity.parse'); -const createNamingPreset = require('@bem/sdk.naming.presets/create'); -const BemFile = require('@bem/sdk.file'); +import namingEntityParse from '@bem/sdk.naming.entity.parse'; +import createNamingPreset from '@bem/sdk.naming.presets/create'; +import BemFile from '@bem/sdk.file'; /** * Plugin to scan flat levels. @@ -16,7 +14,7 @@ const BemFile = require('@bem/sdk.file'); * @param {function} add The function to provide info about found files. * @param {function} callback The callback function. */ -module.exports = (info, add, callback) => { +const flat = (info, add, callback) => { const levelpath = info.path; // Create `@bem/sdk.naming.preset` instance for specified options. const parseEntityName = namingEntityParse(createNamingPreset(info.naming)); @@ -48,3 +46,5 @@ module.exports = (info, add, callback) => { callback(); }); }; + +export default flat; diff --git a/packages/walk/lib/walkers/index.js b/packages/walk/lib/walkers/index.js index eec3cc2f..d2beba1c 100644 --- a/packages/walk/lib/walkers/index.js +++ b/packages/walk/lib/walkers/index.js @@ -1,7 +1,6 @@ -'use strict'; +import sdk from './sdk.js'; +import nested from './nested.js'; +import flat from './flat.js'; -module.exports = { - sdk: require('./sdk'), - nested: require('./nested'), - flat: require('./flat') -}; +export { sdk, nested, flat }; +export default { sdk, nested, flat }; diff --git a/packages/walk/lib/walkers/nested.js b/packages/walk/lib/walkers/nested.js index a505b280..c8268b26 100644 --- a/packages/walk/lib/walkers/nested.js +++ b/packages/walk/lib/walkers/nested.js @@ -1,13 +1,10 @@ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; -const fs = require('fs'); -const path = require('path'); - -const each = require('async-each'); -const BemFile = require('@bem/sdk.file'); -const createPreset = require('@bem/sdk.naming.presets/create'); -const createParse = require('@bem/sdk.naming.entity.parse'); -const createStringify = require('@bem/sdk.naming.entity.stringify'); +import BemFile from '@bem/sdk.file'; +import createPreset from '@bem/sdk.naming.presets/create'; +import createParse from '@bem/sdk.naming.entity.parse'; +import createStringify from '@bem/sdk.naming.entity.stringify'; /** * Calls specified callback for each file or directory in specified directory. @@ -48,7 +45,25 @@ const eachDirItem = (dirname, fn, callback) => { }; }); - each(files, fn, callback); + if (files.length === 0) { + return callback(); + } + + let completed = 0; + let errored = false; + + for (const file of files) { + fn(file, (err) => { + if (errored) return; + if (err) { + errored = true; + return callback(err); + } + if (++completed === files.length) { + callback(); + } + }); + } }); }; @@ -247,8 +262,10 @@ class LevelWalker { * @param {function} add The function to provide info about found files. * @param {function} callback The callback function. */ -module.exports = (info, add, callback) => { +const nested = (info, add, callback) => { const walker = new LevelWalker(info, add); walker.scanLevel(callback); }; + +export default nested; diff --git a/packages/walk/lib/walkers/sdk.js b/packages/walk/lib/walkers/sdk.js index 8d227b80..4b866506 100644 --- a/packages/walk/lib/walkers/sdk.js +++ b/packages/walk/lib/walkers/sdk.js @@ -1,12 +1,9 @@ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; -const fs = require('fs'); -const path = require('path'); - -const each = require('async-each'); -const BemFile = require('@bem/sdk.file'); -const createPreset = require('@bem/sdk.naming.presets/create'); -const createMatch = require('@bem/sdk.naming.cell.match'); +import BemFile from '@bem/sdk.file'; +import createPreset from '@bem/sdk.naming.presets/create'; +import createMatch from '@bem/sdk.naming.cell.match'; /** * Calls specified callback for each file or directory in specified directory. @@ -31,7 +28,26 @@ const eachDirItem = (dirname, fn, callback) => { } const files = filenames.map(basename => path.join(dirname, basename)); - each(files, fn, callback); + + if (files.length === 0) { + return callback(); + } + + let completed = 0; + let errored = false; + + for (const file of files) { + fn(file, (err) => { + if (errored) return; + if (err) { + errored = true; + return callback(err); + } + if (++completed === files.length) { + callback(); + } + }); + } }); }; @@ -45,7 +61,7 @@ const eachDirItem = (dirname, fn, callback) => { * @param {function} add The function to provide info about found files. * @param {function} callback The callback function. */ -module.exports = (info, add, callback) => { +const sdk = (info, add, callback) => { const conv = createPreset(info.naming || 'origin'); const match = createMatch(conv); @@ -75,3 +91,4 @@ module.exports = (info, add, callback) => { } }; +export default sdk; diff --git a/packages/walk/package.json b/packages/walk/package.json index 411b92b7..0e3db225 100644 --- a/packages/walk/package.json +++ b/packages/walk/package.json @@ -2,6 +2,7 @@ "name": "@bem/sdk.walk", "version": "0.6.0", "description": "Walk easily thru BEM file structure", + "type": "module", "publishConfig": { "access": "public" }, @@ -21,7 +22,7 @@ "homepage": "https://github.com/bem/bem-sdk/tree/master/packages/walk#readme", "repository": "bem/bem-sdk", "engines": { - "node": ">= 8.0" + "node": ">= 24.0" }, "main": "lib/index.js", "files": [ @@ -35,21 +36,10 @@ "@bem/sdk.naming.cell.match": "^0.1.3", "@bem/sdk.naming.entity.parse": "^0.2.9", "@bem/sdk.naming.entity.stringify": "^1.1.2", - "@bem/sdk.naming.presets": "^0.2.3", - "async-each": "1.0.1", - "depd": "1.1.0" - }, - "devDependencies": { - "benchmark": "^2.1.0", - "chai-subset": "^1.6.0", - "promise-map-series": "^0.2.2", - "stream-to-array": "^2.3.0" + "@bem/sdk.naming.presets": "^0.2.3" }, "scripts": { - "bench": "npm run bench-deps && node ./bench/run.js", - "bench-deps": "cd bench && npm i && cd fixtures && bower i", "specs": "mocha", - "cover": "nyc mocha", "test": "npm run specs" } } diff --git a/packages/walk/test/core/defaults.test.js b/packages/walk/test/core/defaults.test.js index aa6151c7..34bb8bff 100644 --- a/packages/walk/test/core/defaults.test.js +++ b/packages/walk/test/core/defaults.test.js @@ -1,35 +1,33 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const beforeEach = require('mocha').beforeEach; -const afterEach = require('mocha').afterEach; +import esmock from 'esmock'; +import sinon from 'sinon'; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; - -const proxyquire = require('proxyquire'); -const sinon = require('sinon'); -const mockFs = require('mock-fs'); - -const walkers = require('../../lib/walkers'); +import walkers from '../../lib/walkers/index.js'; describe('core/defaults', () => { const context = {}; - beforeEach(() => { + beforeEach(async () => { const flatStub = sinon.stub(walkers, 'flat').callsArg(2); const nestedStub = sinon.stub(walkers, 'nested').callsArg(2); const sdkStub = sinon.stub(walkers, 'sdk').callsArg(2); - const walk = proxyquire('../..', { - './walkers': { + const walk = await esmock('../../lib/index.js', { + '../../lib/walkers/index.js': { + default: { + 'flat': flatStub, + 'nested': nestedStub, + 'sdk': sdkStub, + }, 'flat': flatStub, 'nested': nestedStub, 'sdk': sdkStub, } }); - context.walk = walk; + context.walk = walk.default; context.flatStub = flatStub; context.nestedStub = nestedStub; context.sdkStub = sdkStub; diff --git a/packages/walk/test/core/walkers.test.js b/packages/walk/test/core/walkers.test.js index 10cc33a8..a8bad3f2 100644 --- a/packages/walk/test/core/walkers.test.js +++ b/packages/walk/test/core/walkers.test.js @@ -1,36 +1,35 @@ -'use strict'; +import { expect, use } from 'chai'; +import chaiSubset from 'chai-subset'; +use(chaiSubset); -const describe = require('mocha').describe; -const it = require('mocha').it; -const beforeEach = require('mocha').beforeEach; -const afterEach = require('mocha').afterEach; +import esmock from 'esmock'; +import sinon from 'sinon'; +import mockFs from 'mock-fs'; -const chai = require('chai'); -chai.use(require('chai-subset')); -const { expect } = chai; - -const proxyquire = require('proxyquire'); -const sinon = require('sinon'); -const mockFs = require('mock-fs'); - -const walkers = require('../../lib/walkers'); +import walkers from '../../lib/walkers/index.js'; describe('core/walkers', () => { const context = {}; - beforeEach(() => { + beforeEach(async () => { const flatStub = sinon.stub(walkers, 'flat').callsArg(2); const nestedStub = sinon.stub(walkers, 'nested').callsArg(2); const sdkStub = sinon.stub(walkers, 'sdk').callsArg(2); - const walk = proxyquire('../../lib/index', { - './walkers': { + const walkModule = await esmock('../../lib/index.js', { + '../../lib/walkers/index.js': { + default: { + 'flat': flatStub, + 'nested': nestedStub, + 'sdk': sdkStub, + }, 'flat': flatStub, - 'nested': nestedStub + 'nested': nestedStub, + 'sdk': sdkStub, } }); - context.walk = walk; + context.walk = walkModule.default; context.flatStub = flatStub; context.nestedStub = nestedStub; context.sdkStub = sdkStub; diff --git a/packages/walk/test/index.test.js b/packages/walk/test/index.test.js index 794706f8..6fd1ef42 100644 --- a/packages/walk/test/index.test.js +++ b/packages/walk/test/index.test.js @@ -1,10 +1,8 @@ -'use strict'; +import { expect, use } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +use(chaiAsPromised); -const { describe, it } = require('mocha'); -const { expect, use } = require('chai'); -use(require('chai-as-promised')); - -const { asArray } = require('..'); +import { asArray } from '../lib/index.js'; describe('asArray', () => { it('should return an empty array', async () => { diff --git a/packages/walk/test/mocha.opts b/packages/walk/test/mocha.opts deleted file mode 100644 index 4a523201..00000000 --- a/packages/walk/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---recursive diff --git a/packages/walk/test/naming/naming.test.js b/packages/walk/test/naming/naming.test.js index 2900668b..0491b5ad 100644 --- a/packages/walk/test/naming/naming.test.js +++ b/packages/walk/test/naming/naming.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../..'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} describe('naming/naming legacy version', () => { afterEach('restore fs', () => { diff --git a/packages/walk/test/schemes/flat/detect.test.js b/packages/walk/test/schemes/flat/detect.test.js index 663b38d0..ee390335 100644 --- a/packages/walk/test/schemes/flat/detect.test.js +++ b/packages/walk/test/schemes/flat/detect.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} const options = { levels: { diff --git a/packages/walk/test/schemes/flat/error.test.js b/packages/walk/test/schemes/flat/error.test.js index fbf4c51d..fc558a24 100644 --- a/packages/walk/test/schemes/flat/error.test.js +++ b/packages/walk/test/schemes/flat/error.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; +import path from 'node:path'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; -const path = require('path'); - -const walk = require('../../../lib/index'); +import walk from '../../../lib/index.js'; describe('schemes/flat/error', () => { it('should throw error if level is not found', done => { @@ -15,7 +10,7 @@ describe('schemes/flat/error', () => { defaults: { scheme: 'flat' } }; - walk([levelpath], options) + walk(levelpath ? [levelpath] : [], options) .resume() .on('error', err => { expect(err.code).to.equal('ENOENT', 'err code is wrong'); diff --git a/packages/walk/test/schemes/flat/ignore.test.js b/packages/walk/test/schemes/flat/ignore.test.js index 4f18a55a..eaebe4d1 100644 --- a/packages/walk/test/schemes/flat/ignore.test.js +++ b/packages/walk/test/schemes/flat/ignore.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} const options = { levels: { diff --git a/packages/walk/test/schemes/flat/levels.test.js b/packages/walk/test/schemes/flat/levels.test.js index 227a7d31..ee9c5432 100644 --- a/packages/walk/test/schemes/flat/levels.test.js +++ b/packages/walk/test/schemes/flat/levels.test.js @@ -1,22 +1,21 @@ -'use strict'; +import { expect } from 'chai'; +import path from 'node:path'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; -const path = require('path'); +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} describe('schemes/flat/levels', () => { afterEach('restore fs', () => { try { mockFs.restore(); - } catch (e) { + } catch { // ... } }); diff --git a/packages/walk/test/schemes/flat/techs.test.js b/packages/walk/test/schemes/flat/techs.test.js index a8b82dbe..c5b15989 100644 --- a/packages/walk/test/schemes/flat/techs.test.js +++ b/packages/walk/test/schemes/flat/techs.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} const options = { levels: { diff --git a/packages/walk/test/schemes/multi.test.js b/packages/walk/test/schemes/multi.test.js index e0e6725c..025734cd 100644 --- a/packages/walk/test/schemes/multi.test.js +++ b/packages/walk/test/schemes/multi.test.js @@ -1,16 +1,15 @@ -'use strict'; +import { expect } from 'chai'; +import path from 'node:path'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; -const path = require('path'); +import walk from '../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} describe('schemes/multi', () => { afterEach('restore fs', () => { diff --git a/packages/walk/test/schemes/nested/detect.test.js b/packages/walk/test/schemes/nested/detect.test.js index d964bb01..985484e4 100644 --- a/packages/walk/test/schemes/nested/detect.test.js +++ b/packages/walk/test/schemes/nested/detect.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} const options = { levels: { diff --git a/packages/walk/test/schemes/nested/error.test.js b/packages/walk/test/schemes/nested/error.test.js index 06732084..f4c8e0e9 100644 --- a/packages/walk/test/schemes/nested/error.test.js +++ b/packages/walk/test/schemes/nested/error.test.js @@ -1,12 +1,7 @@ -'use strict'; +import { expect } from 'chai'; +import path from 'node:path'; -const describe = require('mocha').describe; -const it = require('mocha').it; - -const expect = require('chai').expect; -const path = require('path'); - -const walk = require('../../../lib/index'); +import walk from '../../../lib/index.js'; describe('schemes/nested/error', () => { it('should throw error if level is not found', done => { diff --git a/packages/walk/test/schemes/nested/ignore.test.js b/packages/walk/test/schemes/nested/ignore.test.js index 2357a412..6103f7d1 100644 --- a/packages/walk/test/schemes/nested/ignore.test.js +++ b/packages/walk/test/schemes/nested/ignore.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} const options = { levels: { diff --git a/packages/walk/test/schemes/nested/levels.test.js b/packages/walk/test/schemes/nested/levels.test.js index 3f361425..36cef4ad 100644 --- a/packages/walk/test/schemes/nested/levels.test.js +++ b/packages/walk/test/schemes/nested/levels.test.js @@ -1,22 +1,21 @@ -'use strict'; +import { expect } from 'chai'; +import path from 'node:path'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; -const path = require('path'); +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} describe('schemes/nested/levels', () => { afterEach('restore fs', () => { try { mockFs.restore(); - } catch (e) { + } catch { // ... } }); diff --git a/packages/walk/test/schemes/nested/techs.test.js b/packages/walk/test/schemes/nested/techs.test.js index c57ac5d9..9eb148e8 100644 --- a/packages/walk/test/schemes/nested/techs.test.js +++ b/packages/walk/test/schemes/nested/techs.test.js @@ -1,15 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const describe = require('mocha').describe; -const it = require('mocha').it; -const afterEach = require('mocha').afterEach; +import mockFs from 'mock-fs'; -const expect = require('chai').expect; +import walk from '../../../lib/index.js'; -const mockFs = require('mock-fs'); -const toArray = require('stream-to-array'); - -const walk = require('../../../lib/index'); +async function toArray(stream) { + const result = []; + for await (const chunk of stream) result.push(chunk); + return result; +} const options = { levels: { diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 9e1edaa3..00000000 --- a/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "tslint-config-typings" -}