Skip to content

rules editor: the built-in fs module of wb-rules (typed require/import, module preserve) - #1215

Draft
evgeny-boger wants to merge 2 commits into
rules-editor-typescriptfrom
rules-editor-fs
Draft

rules editor: the built-in fs module of wb-rules (typed require/import, module preserve)#1215
evgeny-boger wants to merge 2 commits into
rules-editor-typescriptfrom
rules-editor-fs

Conversation

@evgeny-boger

Copy link
Copy Markdown
Member

Что происходит; кому и зачем нужно

Редактор правил узнаёт встроенный модуль fs движка wb-rules (wirenboard/wb-rules#231, поверх #1202): типизированные require("fs") / import * as fs from "fs" в language service, автодополнение fs., и параметры проверки, зеркалящие фоновую проверку движка (module: preserve, esModuleInterop).

Что поменялось для пользователей

  • В редакторе const fs = require("fs"), import * as fs from "fs", import fs from "fs", import x = require("fs") типизированы: подсказки по функциям и опциям, ошибки типов (fs.readFileSync(1)), require("some.mod") по-прежнему any.
  • Language service проверяет файлы с module: Preserve + esModuleInterop: true — как движок; иначе import x = require() / export = (которые теперь работают в .ts-правилах) подсвечивались бы как синтаксические ошибки, а import fs from "fs" — как отсутствие default-экспорта.
  • Генератор глобальных дополнений корректно обрабатывает перегрузки require (раньше взял бы первую, специализированную на литералах "fs" | "node:fs"); результат globals-generated.ts байт-в-байт прежний.

Как устроено

  • frontend/src/stores/rules/autocomplete/wb-rules.d.ts — дословная копия types/wb-rules.d.ts из wb-rules quickjs-fs.
  • ts-language-service.tsModuleKind.Preserve, esModuleInterop: true.
  • scripts/generate-wb-rules-completions.mjs — при нескольких перегрузках берётся первая без литеральных параметров.
  • Тесты: ts-language-service-fs.test.ts (typed require, ESM-импорты + export, import x = require / export =, completions после fs.).

Коммиты: 6d5705e5, b85aa0ee.

Как проверял

  • npx vitest run src/stores/rules/autocomplete/ — 13 файлов, 89 тестов; npm run check:types — 0; eslint по затронутым файлам — 0.
  • Тест на preserve load-bearing: с ESNext падает («Import assignment cannot be used when targeting ECMAScript modules»).
  • Примечание: homeui использует TypeScript 6.0.3, где esModuleInterop/allowSyntheticDefaultImports уже true по умолчанию — опция задана явно ради паритета с движком (tsgo), где это не так.

evgeny-boger and others added 2 commits August 24, 2026 22:50
…language service

wb-rules gained a built-in fs module (require("fs"), require("fs/promises")
and the node: aliases), declared in its types/wb-rules.d.ts as ambient
modules plus typed require() overloads ahead of the loose
require(id: string): any. Its transpiler now emits CommonJS with
esModuleInterop and its background check passes --esModuleInterop, so .ts
rule files may write import * as fs from "fs", import fs from "fs" and
export const x = ...

- Sync the vendored wb-rules.d.ts (verbatim copy; the previous vendored
  file was byte-identical to wb-rules' quickjs-ts version).
- Language service: add esModuleInterop: true to the compiler options that
  mirror the engine's check, so a default import of the module checks clean
  regardless of the bundled TypeScript's defaults.
- Completion generator: choose the first overload not specialised on literal
  arguments, so the require global keeps its generic
  function require(id: string): any detail instead of the fs-specific
  overload that now precedes it. Only top-level statements were ever walked,
  so the declare module blocks add no globals; globals-generated.ts is
  unchanged by regeneration.
- Tests (ts-language-service-fs.test.ts, a sibling like the CRLF one to stay
  under max-lines): typed require("fs") flags readFileSync(1) and accepts a
  string path, unknown modules stay any, namespace and default imports plus
  exports check clean, and member completion after fs. offers readFileSync
  and promises.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eclarations

The engine's background check moved from --module esnext to --module
preserve (still with --esModuleInterop): preserve accepts the CommonJS forms
the transpiler emits and runs - import x = require("m") and export = ... -
which esnext rejects as TS1202/TS1203 syntax errors. Mirror that in the
editor's language service (module: Preserve, moduleDetection force and
esModuleInterop unchanged) so the two verdicts keep agreeing; top-level
await and the ESM import/export forms still check clean.

Re-sync the vendored wb-rules.d.ts: fallback overloads for stat/readdir/
mkdir called with boolean variables, more OpenFlag values and a symlink type
union. The generated completion globals are unchanged by regeneration.

Test: import x = require("fs"); typed use; export = x; in a .ts rule file
yields no diagnostics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 102 complexity · 2 duplication

Metric Results
Complexity 102
Duplication 2

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant