@7n/rules-lang-js 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +14 -4
- package/rules/bun/bunfig/bunfig.mdc +17 -0
- package/rules/bun/bunfig/bunfig.rego +29 -0
- package/rules/bun/bunfig/concern.json +9 -0
- package/rules/bun/bunfig/template/bunfig.toml.snippet.toml +2 -0
- package/rules/bun/docs/index.md +11 -0
- package/rules/bun/layout/concern.json +16 -0
- package/rules/bun/layout/docs/fix-layout.md +29 -0
- package/rules/bun/layout/docs/main.md +34 -0
- package/rules/bun/layout/fix-layout.mjs +63 -0
- package/rules/bun/layout/layout.mdc +60 -0
- package/rules/bun/layout/main.mjs +53 -0
- package/rules/bun/licensee/concern.json +7 -0
- package/rules/bun/licensee/docs/fix-licensee.md +27 -0
- package/rules/bun/licensee/docs/index.md +12 -0
- package/rules/bun/licensee/docs/main.md +30 -0
- package/rules/bun/licensee/fix-licensee.mjs +31 -0
- package/rules/bun/licensee/main.mjs +68 -0
- package/rules/bun/lint-surface/concern.json +3 -0
- package/rules/bun/lint-surface/lint-surface.mdc +13 -0
- package/rules/bun/main.json +1 -0
- package/rules/bun/main.mdc +11 -0
- package/rules/bun/package_json/concern.json +9 -0
- package/rules/bun/package_json/docs/fix-package_json.md +28 -0
- package/rules/bun/package_json/docs/index.md +9 -0
- package/rules/bun/package_json/fix-package_json.mjs +311 -0
- package/rules/bun/package_json/package_json.mdc +14 -0
- package/rules/bun/package_json/package_json.rego +64 -0
- package/rules/bun/package_json/template/package.json.deny.json +4 -0
- package/rules/js/check/check.mdc +26 -0
- package/rules/js/check/concern.json +19 -0
- package/rules/js/check/docs/eslint-config.md +56 -0
- package/rules/js/check/docs/fix-check.md +48 -0
- package/rules/js/check/docs/index.md +13 -0
- package/rules/js/check/docs/main.md +48 -0
- package/rules/js/check/eslint-config.mjs +262 -0
- package/rules/js/check/fix-check.mjs +82 -0
- package/rules/js/check/main.mjs +310 -0
- package/rules/js/dep-policy/concern.json +4 -0
- package/rules/js/dep-policy/dep-policy.mdc +36 -0
- package/rules/js/dep-policy/docs/main.md +35 -0
- package/rules/js/dep-policy/main.mjs +99 -0
- package/rules/js/docs/index.md +11 -0
- package/rules/js/eslint/concern.json +8 -0
- package/rules/js/eslint/docs/fix-eslint.md +50 -0
- package/rules/js/eslint/docs/fix-worker.md +31 -0
- package/rules/js/eslint/docs/index.md +11 -0
- package/rules/js/eslint/docs/main.md +35 -0
- package/rules/js/eslint/fix-eslint.mjs +160 -0
- package/rules/js/eslint/fix-worker.mjs +139 -0
- package/rules/js/eslint/main.mjs +115 -0
- package/rules/js/file-extensions/concern.json +3 -0
- package/rules/js/file-extensions/file-extensions.mdc +12 -0
- package/rules/js/jscpd_config/concern.json +11 -0
- package/rules/js/jscpd_config/docs/fix-jscpd_config.md +25 -0
- package/rules/js/jscpd_config/docs/index.md +9 -0
- package/rules/js/jscpd_config/fix-jscpd_config.mjs +3 -0
- package/rules/js/jscpd_config/jscpd_config.mdc +42 -0
- package/rules/js/jscpd_config/jscpd_config.rego +44 -0
- package/rules/js/jscpd_config/template/.jscpd.json.snippet.json +7 -0
- package/rules/js/jscpd_duplicates/concern.json +7 -0
- package/rules/js/jscpd_duplicates/docs/main.md +29 -0
- package/rules/js/jscpd_duplicates/main.mjs +69 -0
- package/rules/js/knip/concern.json +7 -0
- package/rules/js/knip/docs/main.md +31 -0
- package/rules/js/knip/knip.mdc +15 -0
- package/rules/js/knip/main.mjs +89 -0
- package/rules/js/lint-findings/concern.json +3 -0
- package/rules/js/lint-findings/docs/main.md +40 -0
- package/rules/js/lint-findings/main.mjs +125 -0
- package/rules/js/main.json +1 -0
- package/rules/js/main.mdc +18 -0
- package/rules/js/package_json/concern.json +9 -0
- package/rules/js/package_json/docs/fix-package_json.md +25 -0
- package/rules/js/package_json/docs/index.md +9 -0
- package/rules/js/package_json/fix-package_json.mjs +3 -0
- package/rules/js/package_json/package_json.mdc +15 -0
- package/rules/js/package_json/package_json.rego +142 -0
- package/rules/js/package_json/template/package.json.snippet.json +6 -0
- package/rules/js/tooling/concern.json +3 -0
- package/rules/js/tooling/data/tooling/knip-canonical.json +30 -0
- package/rules/js/tooling/data/tooling/oxlint-canonical.json +400 -0
- package/rules/js/tooling/docs/main.md +53 -0
- package/rules/js/tooling/main.mjs +183 -0
- package/rules/js/utils_imports/concern.json +4 -0
- package/rules/js/utils_imports/docs/main.md +50 -0
- package/rules/js/utils_imports/main.mjs +185 -0
- package/rules/js/utils_imports/utils_imports.mdc +15 -0
- package/rules/js/vscode_extensions/concern.json +11 -0
- package/rules/js/vscode_extensions/docs/fix-vscode_extensions.md +24 -0
- package/rules/js/vscode_extensions/docs/index.md +11 -0
- package/rules/js/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/js/vscode_extensions/template/extensions.json.snippet.json +6 -0
- package/rules/js/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/js/vscode_extensions/vscode_extensions.rego +12 -0
- package/rules/js-bun-db/connection/concern.json +3 -0
- package/rules/js-bun-db/connection/connection.mdc +42 -0
- package/rules/js-bun-db/docs/index.md +11 -0
- package/rules/js-bun-db/lib/bun-sql-scan.mjs +1047 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +63 -0
- package/rules/js-bun-db/lib/docs/index.md +11 -0
- package/rules/js-bun-db/main.json +1 -0
- package/rules/js-bun-db/main.mdc +8 -0
- package/rules/js-bun-db/package_json/concern.json +9 -0
- package/rules/js-bun-db/package_json/package_json.mdc +31 -0
- package/rules/js-bun-db/package_json/package_json.rego +15 -0
- package/rules/js-bun-db/package_json/template/package.json.deny.json +6 -0
- package/rules/js-bun-db/pg_format_identifiers/concern.json +3 -0
- package/rules/js-bun-db/pg_format_identifiers/pg_format_identifiers.mdc +104 -0
- package/rules/js-bun-db/safety/concern.json +4 -0
- package/rules/js-bun-db/safety/docs/main.md +34 -0
- package/rules/js-bun-db/safety/main.mjs +430 -0
- package/rules/js-bun-db/safety/safety.mdc +458 -0
- package/rules/js-bun-redis/docs/index.md +11 -0
- package/rules/js-bun-redis/imports/concern.json +4 -0
- package/rules/js-bun-redis/imports/docs/main.md +36 -0
- package/rules/js-bun-redis/imports/imports.mdc +47 -0
- package/rules/js-bun-redis/imports/main.mjs +88 -0
- package/rules/js-bun-redis/lib/docs/index.md +11 -0
- package/rules/js-bun-redis/lib/docs/redis-imports.md +227 -0
- package/rules/js-bun-redis/lib/redis-imports.mjs +130 -0
- package/rules/js-bun-redis/main.json +1 -0
- package/rules/js-bun-redis/main.mdc +8 -0
- package/rules/js-bun-redis/package_json/concern.json +9 -0
- package/rules/js-bun-redis/package_json/package_json.mdc +11 -0
- package/rules/js-bun-redis/package_json/package_json.rego +15 -0
- package/rules/js-bun-redis/package_json/template/package.json.deny.json +12 -0
- package/rules/js-mssql/deps/concern.json +4 -0
- package/rules/js-mssql/deps/docs/main.md +33 -0
- package/rules/js-mssql/deps/main.mjs +297 -0
- package/rules/js-mssql/docs/index.md +11 -0
- package/rules/js-mssql/lib/docs/index.md +11 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +380 -0
- package/rules/js-mssql/lib/mssql-pool-scan.mjs +610 -0
- package/rules/js-mssql/main.json +1 -0
- package/rules/js-mssql/main.mdc +144 -0
- package/rules/js-mssql/mssql-tvp/concern.json +3 -0
- package/rules/js-mssql/mssql-tvp/mssql-tvp.mdc +77 -0
- package/rules/js-mssql/package_json/concern.json +9 -0
- package/rules/js-mssql/package_json/package_json.mdc +9 -0
- package/rules/js-mssql/package_json/package_json.rego +57 -0
- package/rules/js-run/configmap/concern.json +9 -0
- package/rules/js-run/configmap/configmap.mdc +37 -0
- package/rules/js-run/configmap/configmap.rego +21 -0
- package/rules/js-run/configmap/template/configmap.yaml.contains.yml +4 -0
- package/rules/js-run/docs/index.md +11 -0
- package/rules/js-run/jsconfig/concern.json +9 -0
- package/rules/js-run/jsconfig/docs/fix-jsconfig.md +28 -0
- package/rules/js-run/jsconfig/docs/index.md +9 -0
- package/rules/js-run/jsconfig/fix-jsconfig.mjs +119 -0
- package/rules/js-run/jsconfig/jsconfig.mdc +48 -0
- package/rules/js-run/jsconfig/jsconfig.rego +59 -0
- package/rules/js-run/jsconfig/template/jsconfig.json.snippet.json +10 -0
- package/rules/js-run/lib/bunyan-imports.mjs +98 -0
- package/rules/js-run/lib/check-env-scan.mjs +338 -0
- package/rules/js-run/lib/conn-file-rules.mjs +214 -0
- package/rules/js-run/lib/conn-imports-scan.mjs +154 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +121 -0
- package/rules/js-run/lib/docs/check-env-scan.md +438 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +304 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +208 -0
- package/rules/js-run/lib/docs/index.md +16 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +334 -0
- package/rules/js-run/lib/docs/temporal-scan.md +29 -0
- package/rules/js-run/lib/promise-settimeout-scan.mjs +128 -0
- package/rules/js-run/lib/temporal-scan.mjs +52 -0
- package/rules/js-run/main.json +1 -0
- package/rules/js-run/main.mdc +16 -0
- package/rules/js-run/package_json/concern.json +9 -0
- package/rules/js-run/package_json/package_json.mdc +44 -0
- package/rules/js-run/package_json/package_json.rego +37 -0
- package/rules/js-run/package_json/template/package.json.deny.json +22 -0
- package/rules/js-run/project-structure/concern.json +3 -0
- package/rules/js-run/project-structure/project-structure.mdc +11 -0
- package/rules/js-run/runtime/concern.json +12 -0
- package/rules/js-run/runtime/docs/fix-runtime.md +27 -0
- package/rules/js-run/runtime/docs/main.md +35 -0
- package/rules/js-run/runtime/fix-runtime.mjs +46 -0
- package/rules/js-run/runtime/main.mjs +496 -0
- package/rules/js-run/runtime/runtime.mdc +184 -0
- package/rules/js-run/scope/concern.json +3 -0
- package/rules/js-run/scope/scope.mdc +11 -0
- package/rules/npm-module/docs/index.md +11 -0
- package/rules/npm-module/emit_types_config/concern.json +9 -0
- package/rules/npm-module/emit_types_config/docs/fix-emit_types_config.md +25 -0
- package/rules/npm-module/emit_types_config/docs/index.md +9 -0
- package/rules/npm-module/emit_types_config/emit_types_config.mdc +43 -0
- package/rules/npm-module/emit_types_config/emit_types_config.rego +28 -0
- package/rules/npm-module/emit_types_config/fix-emit_types_config.mjs +5 -0
- package/rules/npm-module/emit_types_config/template/tsconfig.emit-types.json.snippet.json +9 -0
- package/rules/npm-module/header_doc_pointer/concern.json +5 -0
- package/rules/npm-module/header_doc_pointer/docs/main.md +40 -0
- package/rules/npm-module/header_doc_pointer/header_doc_pointer.mdc +18 -0
- package/rules/npm-module/header_doc_pointer/main.mjs +131 -0
- package/rules/npm-module/main.json +1 -0
- package/rules/npm-module/main.mdc +36 -0
- package/rules/npm-module/npm_package_json/concern.json +9 -0
- package/rules/npm-module/npm_package_json/docs/fix-npm_package_json.md +26 -0
- package/rules/npm-module/npm_package_json/docs/index.md +9 -0
- package/rules/npm-module/npm_package_json/fix-npm_package_json.mjs +5 -0
- package/rules/npm-module/npm_package_json/npm_package_json.mdc +57 -0
- package/rules/npm-module/npm_package_json/npm_package_json.rego +73 -0
- package/rules/npm-module/npm_package_json/template/package.json.snippet.json +1 -0
- package/rules/npm-module/package_structure/concern.json +5 -0
- package/rules/npm-module/package_structure/docs/main.md +37 -0
- package/rules/npm-module/package_structure/main.mjs +448 -0
- package/rules/npm-module/package_structure/package_structure.mdc +63 -0
- package/rules/npm-module/root_package_json/concern.json +9 -0
- package/rules/npm-module/root_package_json/docs/fix-root_package_json.md +25 -0
- package/rules/npm-module/root_package_json/docs/index.md +9 -0
- package/rules/npm-module/root_package_json/fix-root_package_json.mjs +5 -0
- package/rules/npm-module/root_package_json/root_package_json.mdc +41 -0
- package/rules/npm-module/root_package_json/root_package_json.rego +28 -0
- package/rules/npm-module/root_package_json/template/package.json.snippet.json +1 -0
- package/rules/npm-module/rule_meta/concern.json +8 -0
- package/rules/npm-module/rule_meta/docs/main.md +35 -0
- package/rules/npm-module/rule_meta/main.mjs +119 -0
- package/rules/npm-module/rule_meta/rule_meta.mdc +11 -0
- package/rules/npm-module/skill_meta/concern.json +5 -0
- package/rules/npm-module/skill_meta/docs/main.md +149 -0
- package/rules/npm-module/skill_meta/main.mjs +91 -0
- package/rules/npm-module/skill_meta/skill_meta.mdc +11 -0
- package/rules/tool-surface/docs/index.md +11 -0
- package/rules/tool-surface/main.json +6 -0
- package/rules/tool-surface/main.mdc +72 -0
- package/rules/vue/composition-api/composition-api.mdc +82 -0
- package/rules/vue/composition-api/concern.json +3 -0
- package/rules/vue/docs/index.md +11 -0
- package/rules/vue/lib/docs/index.md +11 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +265 -0
- package/rules/vue/lib/vue-forbidden-imports.mjs +240 -0
- package/rules/vue/main.json +1 -0
- package/rules/vue/main.mdc +18 -0
- package/rules/vue/nheader-layout/concern.json +3 -0
- package/rules/vue/nheader-layout/nheader-layout.mdc +171 -0
- package/rules/vue/package_json/concern.json +9 -0
- package/rules/vue/package_json/package_json.mdc +30 -0
- package/rules/vue/package_json/package_json.rego +140 -0
- package/rules/vue/packages/concern.json +6 -0
- package/rules/vue/packages/docs/index.md +11 -0
- package/rules/vue/packages/docs/main.md +35 -0
- package/rules/vue/packages/main.mjs +575 -0
- package/rules/vue/packages/packages.mdc +56 -0
- package/rules/vue/quasar-ui/concern.json +3 -0
- package/rules/vue/quasar-ui/quasar-ui.mdc +32 -0
- package/rules/vue/structure/concern.json +3 -0
- package/rules/vue/structure/structure.mdc +101 -0
- package/rules/vue/testing/concern.json +3 -0
- package/rules/vue/testing/testing.mdc +40 -0
- package/rules/vue/tfm-translations/concern.json +7 -0
- package/rules/vue/tfm-translations/docs/main.md +29 -0
- package/rules/vue/tfm-translations/main.mjs +55 -0
- package/rules/vue/tfm-translations/tfm-translations.mdc +32 -0
- package/rules/vue/vite-config/concern.json +3 -0
- package/rules/vue/vite-config/vite-config.mdc +153 -0
- package/rules/vue/vite-env/concern.json +3 -0
- package/rules/vue/vite-env/vite-env.mdc +61 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: bun-sql-scan.mjs
|
|
4
|
+
resource: plugins/lang-js/rules/js-bun-db/lib/bun-sql-scan.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: eed7dede
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
AST-сканер виявляє небезпечні патерни, пов'язані з використанням Bun SQL та PostgreSQL. Він перевіряє, чи не створюється пул з'єднань через `new SQL` всередині функції, що порушує принцип singleton на рівні модуля. Сканер також виявляє виклики `<obj>.unsafe` без відповідного маркера-коментаря `// allow-unsafe: <reason>`, що заборонено за замовчуванням для `sql.unsafe`. Крім того, він ідентифікує динамічні SQL-списки у tagged template `sql\`... IN (${arr.join}) ...\``, які не використовують параметризовані значення, а також шукає інші аномалії у використанні бібліотек `pg` (js-bun-db.mdc).
|
|
12
|
+
|
|
13
|
+
## Поведінка
|
|
14
|
+
|
|
15
|
+
findPgFormatShimDefinitionInText знаходить визначення pg-format-сумісних шимів у коді, що використовує Bun SQL.
|
|
16
|
+
findPgFormatLikeQueryWrapperInText знаходить pg-сумісні обгортки запитів виду `{ query { ... unsafe ... } }` у коді, що використовує Bun SQL.
|
|
17
|
+
findBunSqlPerRequestConnectionInText знаходить створення нового екземпляра `SQL` всередині функцій, що вказує на неоптимальне використання пулу.
|
|
18
|
+
findBunSqlUnsafeUseWithoutAllowMarkerInText знаходить виклики `<obj>.unsafe` без відповідного маркера-коментаря.
|
|
19
|
+
findBunSqlUnsafeWithInterpolatedTemplateInText знаходить виклики `<obj>.unsafe` з інтерпольованим шаблоном, що створює структурну вразливість.
|
|
20
|
+
findBunSqlPgLeftoverCallInText знаходить виклики `<obj>.connect` або `<obj>.end` у файлах з Bun SQL без маркера-коментаря.
|
|
21
|
+
findUnsafeBunSqlDynamicSqlListInText знаходить динамічні SQL-списки у tagged template, де використовується `.join` замість параметризації.
|
|
22
|
+
findUnsafeBunSqlInListMissingEmptyGuardInText знаходить підстановки списків у `IN (...)`, де відсутня перевірка на пустоту з `throw`.
|
|
23
|
+
textHasBunSqlImport визначає, чи містить текст джерела імпорт імені `sql` або `SQL` з `"bun"`.
|
|
24
|
+
textHasPgLibImport визначає, чи імпортує файл npm-пакет `pg` за допомогою `import` або `require`.
|
|
25
|
+
findPgLibImportInText знаходить конкретні місця імпорту пакета `pg` у коді.
|
|
26
|
+
findPgListenNotifyUsageInText знаходить використання PostgreSQL LISTEN/NOTIFY у коді, що вимагає клієнта `pg`.
|
|
27
|
+
isBunSqlScanSourceFile визначає, чи підходить файл за розширенням для AST-скану.
|
|
28
|
+
findJsonStringifyBeforeJsonbInText знаходить виклики `JSON.stringify` перед використанням `::jsonb` у SQL template literal-ах, що призводить до подвійної серіалізації.
|
|
29
|
+
findSqlArrayWithoutTypeArgInText знаходить виклики `sql.array` або аналогічні, де відсутній другий аргумент (тип).
|
|
30
|
+
|
|
31
|
+
## Публічний API
|
|
32
|
+
|
|
33
|
+
findPgFormatShimDefinitionInText — Виявляє визначення pg-format-сумісних шимів. Прапорує функції з іменами, що вказують на форматування (`format`, `pgFormat`, `sqlFormat`, `pgFmt`), якщо їхній вміст містить літерали або регулярні вирази з `%L`, `%I`, `%s`. Також виявляє pg-format-специфічні API (`quoteLiteral`, `quoteIdent`, `escapeLiteral`, `escapeIdent`), які не потрібні при використанні Bun SQL.
|
|
34
|
+
|
|
35
|
+
findPgFormatLikeQueryWrapperInText — Виявляє pg-сумісні обгортки запитів, які маскують виклик `unsafe` під безпечне ім'я, повертаючи потенційну точку для SQL-ін'єкції.
|
|
36
|
+
|
|
37
|
+
findBunSqlPerRequestConnectionInText — Виявляє створення нового об'єкта SQL (`new SQL`) всередині функцій-обробників запитів, замість використання єдиного екземпляра.
|
|
38
|
+
|
|
39
|
+
findBunSqlUnsafeUseWithoutAllowMarkerInText — Виявляє виклики `unsafe` без відповідного маркера-коментаря. Забороняє використання `unsafe`, якщо значення не контролюється кодом (не вхідні дані користувача) і не є необхідним для підстановки назв таблиць/колонок або динамічного SQL/DDL.
|
|
40
|
+
|
|
41
|
+
findBunSqlUnsafeWithInterpolatedTemplateInText — Виявляє використання `unsafe` з шаблонним літералом, що містить інтерполяцію (`${name}`). Попереджає, що шаблонна підстановка не екранує ідентифікатори та не прив'язує значення, створюючи ризик структурної ін'єкції.
|
|
42
|
+
|
|
43
|
+
findBunSqlPgLeftoverCallInText — Виявляє виклики `connect` або `end` для pg-клієнта у файлах, що імпортують Bun SQL, без відповідного маркера-коментаря.
|
|
44
|
+
|
|
45
|
+
findUnsafeBunSqlDynamicSqlListInText — Виявляє динамічні SQL-списки у контекстах `IN (...)` або `VALUES (...)`, де використовується метод `.join` серед виразів.
|
|
46
|
+
|
|
47
|
+
findUnsafeBunSqlInListMissingEmptyGuardInText — Виявляє підстановки списків у `IN (...)`, які або не винесені в окрему змінну, або винесені, але перед запитом відсутня перевірка на порожній список.
|
|
48
|
+
|
|
49
|
+
textHasBunSqlImport — Перевіряє, чи містить текст джерела імпорт імені `sql` або `SQL` з модуля `"bun"`. Реалізація живе в ядрі (`@7n/rules/scripts/lib/js-source-signals.mjs`, спільна з auto-rules) — тут ре-експорт.
|
|
50
|
+
|
|
51
|
+
textHasPgLibImport — Перевіряє, чи імпортує файл бібліотеку `pg` (саме клієнт, а не `pg-format` чи `@types/pg`).
|
|
52
|
+
|
|
53
|
+
findPgLibImportInText — Знаходить явний імпорт пакета `pg` у коді, повертаючи місце виявлення для точного відображення у повідомленнях про помилку.
|
|
54
|
+
|
|
55
|
+
findPgListenNotifyUsageInText — Виявляє використання PostgreSQL команд `LISTEN`/`NOTIFY` у запитах або обробниках подій, оскільки Bun SQL поки не підтримує ці функції.
|
|
56
|
+
|
|
57
|
+
findJsonStringifyBeforeJsonbInText — Знаходить виклики `JSON.stringify::jsonb` у SQL-шаблонах, що призводить до подвійної серіалізації даних.
|
|
58
|
+
|
|
59
|
+
findSqlArrayWithoutTypeArgInText — Знаходить виклики функції для створення масиву (`sql.array` тощо) без вказання обов'язкового другого аргументу (типу pg-елемента), що може спричинити невідповідність типів.
|
|
60
|
+
|
|
61
|
+
## Гарантії поведінки
|
|
62
|
+
|
|
63
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Directory Index
|
|
3
|
+
title: npm/rules/js-bun-db/lib
|
|
4
|
+
resource: plugins/lang-js/rules/js-bun-db/lib/
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# npm/rules/js-bun-db/lib
|
|
8
|
+
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
| ----------------------------------- | --------- |
|
|
11
|
+
| [bun-sql-scan.mjs](bun-sql-scan.md) | JS Module |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "auto": { "predicate": "jsBunDbSignal" } }
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Використання pg / mysql2 / Bun SQL у Node.js та Bun
|
|
3
|
+
globs: "**/package.json,**/src/conn/**"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
version: '1.15'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Правило забезпечує безпечне підключення й виконання запитів через Bun native SQL замість `pg` / `pg-format` / `mysql2`, із захистом від SQL injection, pg-leftover та небезпечних патернів `sql.unsafe`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
## Заборонені залежності у package.json
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_bun_db.package_json`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `**/package.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє поле `dependencies` на наявність пакетів із deny-списку [`package.json.deny.json`](./template/package.json.deny.json). Список керується даними (`--data`), тому розширюється без зміни rego-коду.
|
|
8
|
+
|
|
9
|
+
Поточний deny-список:
|
|
10
|
+
|
|
11
|
+
- `pg-format` — заміни на Bun native SQL (без ручного форматування)
|
|
12
|
+
- `mysql2` — заміни на Bun native SQL
|
|
13
|
+
|
|
14
|
+
`pg` у dependencies **не** є порушенням на рівні Rego — виняток для LISTEN/NOTIFY зважується у JS-сканері (`safety/main.mjs`, детальніше — `safety/safety.mdc`, секція «pg: виключення для LISTEN/NOTIFY»).
|
|
15
|
+
|
|
16
|
+
✓ `{ "dependencies": { "pg": "^8.0.0" } }` — дозволено
|
|
17
|
+
✗ `{ "dependencies": { "pg-format": "^1.0.0" } }` — `deny: dependencies.pg-format — заміни на Bun native SQL`
|
|
18
|
+
|
|
19
|
+
### Перехід з `pg` / `mysql2` на Bun native SQL
|
|
20
|
+
|
|
21
|
+
PostgreSQL 18+, MariaDB 10.6+ (сумісний з MySQL-протоколом, підключаємось як `mysql://`).
|
|
22
|
+
|
|
23
|
+
Якщо в проєкті використовуються бібліотеки `pg`, `pg-format` або `mysql2`, їх потрібно замінити на Bun native SQL: <https://bun.com/docs/runtime/sql>.
|
|
24
|
+
|
|
25
|
+
- Видалити з `dependencies`: `pg-pool`, `pg-native`, `pg-format`, `mysql`, `mysql2`.
|
|
26
|
+
- Видалити з коду: усі `import` / `require` цих пакетів та власні обгортки над ними.
|
|
27
|
+
- Замінити на `import { sql, SQL } from 'bun'` — Bun має вбудований клієнт із пулом, prepared statements та tagged templates.
|
|
28
|
+
|
|
29
|
+
`pg-format` (unscoped) — це ручне форматування SQL через escape (`format('... %L ...', value)`); такі рядки легко поламати неправильним типом, locale-залежним escape або забутим `%L`. Tagged template Bun SQL параметризує значення нативно (``sql`... ${value} ...` ``) і не лишає простору для injection — окремий «форматер» **для значень** не потрібен.
|
|
30
|
+
|
|
31
|
+
Виключення є **лише** для **динамічних identifiers** (назви схем / таблиць / колонок / індексів / ролей / БД) і whitelist-фрагментів типу `ASC`/`DESC`: Bun SQL їх параметризувати не вміє, тож тут дозволено окремий пакет **`@scaleleap/pg-format`** (scoped форк, не unscoped `pg-format`) — деталі й приклади у `pg_format_identifiers/pg_format_identifiers.mdc`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Перевірка `dependencies` (js-bun-db.mdc).
|
|
2
|
+
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "deny": ... } }
|
|
4
|
+
# Структура --data сформована з template/package.json.deny.json.
|
|
5
|
+
# AST-скан коду (`new SQL(...)` у функціях, `unsafe()` без маркера, pg-leftover,
|
|
6
|
+
# динамічні `IN (…)` через `.join(',')`) лишається у JS.
|
|
7
|
+
package js_bun_db.package_json
|
|
8
|
+
|
|
9
|
+
import rego.v1
|
|
10
|
+
|
|
11
|
+
deny contains msg if {
|
|
12
|
+
some pkg, reason in data.template.deny.dependencies
|
|
13
|
+
pkg in object.keys(object.get(input, "dependencies", {}))
|
|
14
|
+
msg := sprintf("dependencies.%s — %s", [pkg, reason])
|
|
15
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
## Динамічна SQL-структура: `@scaleleap/pg-format` для identifiers
|
|
2
|
+
|
|
3
|
+
Bun SQL **не вміє** параметризувати назви схем, таблиць, колонок, індексів, ролей, БД — а ``sql`SELECT * FROM ${table}` `` забіндив би це як значення і зламав би синтаксис. Для **динамічних identifiers** дозволено окремий пакет:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun add @scaleleap/pg-format
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
⚠️ Це **scoped `@scaleleap/pg-format`**, а не unscoped `pg-format` (той у [deny-списку](../package_json/template/package.json.deny.json)). Беремо форк `@scaleleap` **тільки** заради `%I` / `%s`-можливостей; значення все одно проходять через Bun parameters, **не** через `%L`.
|
|
10
|
+
|
|
11
|
+
### Дозволений патерн
|
|
12
|
+
|
|
13
|
+
- **`%I`** — escape SQL identifier (schema / table / column / index / role / database).
|
|
14
|
+
- **`%s`** — raw fragment, **тільки** для whitelist-значень (`ASC` / `DESC`, тип JOIN'у тощо).
|
|
15
|
+
- Значення — позиційні параметри `$1, $2, …`, які передаються другим аргументом у `sql.unsafe(query, [bindParams])`.
|
|
16
|
+
- На рядку виклику `sql.unsafe(...)` обов'язковий маркер `// allow-unsafe: <причина>` (див. `safety/safety.mdc`, секція «sql.unsafe(...) за замовчуванням заборонено»).
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
import format from '@scaleleap/pg-format'
|
|
20
|
+
import { sql } from 'bun'
|
|
21
|
+
|
|
22
|
+
const allowedColumns = new Set(['created_at', 'email', 'name'])
|
|
23
|
+
if (!allowedColumns.has(sortBy)) throw new Error('Invalid sort column')
|
|
24
|
+
|
|
25
|
+
const direction = sortDir === 'asc' ? 'ASC' : 'DESC'
|
|
26
|
+
|
|
27
|
+
const query = format(
|
|
28
|
+
'SELECT * FROM %I.%I ORDER BY %I %s LIMIT $1',
|
|
29
|
+
schemaName,
|
|
30
|
+
tableName,
|
|
31
|
+
sortBy,
|
|
32
|
+
direction
|
|
33
|
+
)
|
|
34
|
+
// allow-unsafe: динамічні schema/table/column; значення біндяться через $N
|
|
35
|
+
const rows = await sql.unsafe(query, [limit])
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Multi-row `INSERT` через `VALUES %L` теж типовий легітимний кейс, але передавай значення колонок як паралельні масиви через `unnest(...)` Bun SQL — `format('VALUES %L', rows)` лишай тільки коли альтернатива з `unnest` неможлива:
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
const query = format(
|
|
42
|
+
/* sql */ `
|
|
43
|
+
INSERT INTO "order".delivery_status (order_id, status, changed_at)
|
|
44
|
+
SELECT v.order_id::uuid, v.status, v.changed_at::timestamptz
|
|
45
|
+
FROM (VALUES %L) AS v(order_id, status, changed_at)
|
|
46
|
+
`,
|
|
47
|
+
values
|
|
48
|
+
)
|
|
49
|
+
// allow-unsafe: multi-row VALUES для бекфілу; values формуються з валідованого input
|
|
50
|
+
await sql.unsafe(query)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Заборонено й після підключення `@scaleleap/pg-format`
|
|
54
|
+
|
|
55
|
+
- **`%L` для user input** — це повернення `pg-format`-стилю. Завжди bind через Bun (``sql`... = ${value}` ``) або позиційний параметр `$N` + `sql.unsafe(query, [params])`.
|
|
56
|
+
- Збирати весь `WHERE` через `format(...)` з `%L` — користуйся whitelist полів і ручним складанням `$N`-placeholder'ів (приклад нижче).
|
|
57
|
+
- Власні функції `format` / `pgFormat` / `sqlFormat` / `pgFmt` з тілом, що містить `%L` / `%I` / `%s`, — `fail` сканера (це шим, а не імпорт з бібліотеки); детектор — `findPgFormatShimDefinitionInText` (`lib/bun-sql-scan.mjs`, підключений з `safety/main.mjs`).
|
|
58
|
+
- Експортовані `quoteLiteral` / `quoteIdent` / `escapeLiteral` / `escapeIdent` — `fail` сканера (pg-format-специфічні API замість Bun parameters).
|
|
59
|
+
|
|
60
|
+
### Dynamic `WHERE` — без `format(...)`, через whitelist + `$N`
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
const conditions = []
|
|
64
|
+
const values = []
|
|
65
|
+
|
|
66
|
+
if (email) {
|
|
67
|
+
values.push(email)
|
|
68
|
+
conditions.push(`email = $${values.length}`)
|
|
69
|
+
}
|
|
70
|
+
if (status) {
|
|
71
|
+
values.push(status)
|
|
72
|
+
conditions.push(`status = $${values.length}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : ''
|
|
76
|
+
const query = `SELECT * FROM users ${where}`
|
|
77
|
+
// allow-unsafe: динамічний WHERE з whitelist-полів; значення біндяться через $N
|
|
78
|
+
const rows = await sql.unsafe(query, values)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Коротка таблиця рішень
|
|
82
|
+
|
|
83
|
+
| Сценарій | Що використовувати |
|
|
84
|
+
| --------------------------------- | ---------------------------------------------------- |
|
|
85
|
+
| `WHERE id = ${...}` | Bun SQL tagged template |
|
|
86
|
+
| `INSERT` одного рядка | Bun SQL tagged template |
|
|
87
|
+
| `INSERT` масиву (object/colset) | Bun SQL helper `sql(rows, 'a', 'b')` або `unnest` |
|
|
88
|
+
| `UPDATE field = ${value}` | Bun SQL tagged template |
|
|
89
|
+
| Динамічна назва schema / table | `@scaleleap/pg-format` `%I` + `sql.unsafe(q, [...])` |
|
|
90
|
+
| Динамічна назва колонки | `@scaleleap/pg-format` `%I` + bind |
|
|
91
|
+
| Динамічний `ORDER BY column` | whitelist + `%I` |
|
|
92
|
+
| `ASC` / `DESC`, тип JOIN'у | whitelist + `%s` |
|
|
93
|
+
| Динамічний `WHERE` (полів багато) | whitelist + ручні `$N` + `sql.unsafe(text, vals)` |
|
|
94
|
+
| Сирий migration / DDL | `sql.unsafe(text)` з `// allow-unsafe: <причина>` |
|
|
95
|
+
| User input як value | **тільки** Bun parameters / `$N` bind |
|
|
96
|
+
| Масив значень у `unnest(...)` | `sql.array(arr, type)` — обов'язково з типом |
|
|
97
|
+
|
|
98
|
+
Головне правило:
|
|
99
|
+
|
|
100
|
+
- **SQL values** → Bun SQL parameters (tagged template `${value}` або `$N` + `sql.unsafe(text, values)`).
|
|
101
|
+
- **SQL identifiers** → `@scaleleap/pg-format` `%I` (schema, table, column, index, role, database).
|
|
102
|
+
- **SQL fragments** (`ASC`/`DESC` тощо) → whitelist + `%s`.
|
|
103
|
+
|
|
104
|
+
Ніщо з цієї сторінки (правильність використання `%I`/`%s`, вибір `@scaleleap/pg-format` замість unscoped `pg-format` у коді, а не лише у `dependencies`) наразі не має власного AST-детектора — сканер (`lib/bun-sql-scan.mjs`) ловить лише симптоми: shim-реалізації (`findPgFormatShimDefinitionInText`), обгортки над `unsafe` (`findPgFormatLikeQueryWrapperInText`) та відсутність `allow-unsafe`-маркера. Тому ця сторінка лишається docs-only; unscoped `pg-format` як залежність вже заборонено окремо в `package_json/package_json.mdc` (Rego deny-list).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: main.mjs
|
|
4
|
+
resource: plugins/lang-js/rules/js-bun-db/safety/main.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: ce094cd3
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
9
|
+
issues: judge:inaccurate:0.98
|
|
10
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Огляд
|
|
14
|
+
|
|
15
|
+
Поведінка системи описує основну функціональність програми через публічну функцію `main`. Програма керується конфігураційними параметрами, визначеними в `package.json`. Уся взаємодія з базами даних здійснюється через механізм, що відповідає логіці, описаній у `js-bun-db.mdc`. Система працює виключно в режимі читання даних, і гарантії не включають механізм кешування.
|
|
16
|
+
|
|
17
|
+
## Поведінка
|
|
18
|
+
|
|
19
|
+
1. Викликається функція main.
|
|
20
|
+
2. Система зчитує конфігураційні файли для ігнорування.
|
|
21
|
+
3. Знаходяться всі файли package.json у репозиторії.
|
|
22
|
+
4. Скануються JS/TS файли репозиторію на наявність небезпечних патернів Bun SQL.
|
|
23
|
+
5. Збираються метадані щодо використання pg-модуля (`pg`) та сигналів LISTEN/NOTIFY у файлах.
|
|
24
|
+
6. Перевіряється залежність `pg` у файлах package.json щодо наявності використання LISTEN/NOTIFY.
|
|
25
|
+
7. Якщо Bun SQL використовується, перевіряється відповідність усіх патернів (наприклад, відсутність створення new SQL у функціях, використання `allow-unsafe` маркерів, правильне використання `sql.array`, відсутність зайвих `JSON.stringify` перед `::jsonb`).
|
|
26
|
+
8. Усі результати перевірок реєструються за допомогою повідомлень з посиланням на (js-bun-db.mdc).
|
|
27
|
+
|
|
28
|
+
## Публічний API
|
|
29
|
+
|
|
30
|
+
main — перевіряє відповідність проєкту вимогам, викладеним у правилі js-bun-db.mdc.
|
|
31
|
+
|
|
32
|
+
## Гарантії поведінки
|
|
33
|
+
|
|
34
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|