@warlock.js/core 5.33.0 → 5.34.0
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 +26 -46
- package/esm/cli/commands/check/check-command.action.mjs +2 -1
- package/esm/cli/commands/check/check-command.action.mjs.map +1 -1
- package/esm/cli/commands/check.command.mjs +2 -2
- package/esm/cli/commands/check.command.mjs.map +1 -1
- package/esm/cli/commands/e2e.command.mjs +63 -0
- package/esm/cli/commands/e2e.command.mjs.map +1 -0
- package/esm/cli/commands/load-e2e-spec.mjs +47 -0
- package/esm/cli/commands/load-e2e-spec.mjs.map +1 -0
- package/esm/cli/framework-cli-commands.mjs +2 -0
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/default-health-checkers.mjs +1 -6
- package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -1
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +0 -2
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
- package/esm/dev-server/health-checker/file-health-result.d.mts +1 -1
- package/esm/dev-server/health-checker/file-health-result.mjs.map +1 -1
- package/esm/e2e/browser.d.mts +4 -0
- package/esm/e2e/browser.d.mts.map +1 -0
- package/esm/e2e/browser.mjs +88 -0
- package/esm/e2e/browser.mjs.map +1 -0
- package/esm/e2e/cdp.d.mts +152 -0
- package/esm/e2e/cdp.d.mts.map +1 -0
- package/esm/e2e/cdp.mjs +106 -0
- package/esm/e2e/cdp.mjs.map +1 -0
- package/esm/e2e/fixture.mjs +195 -0
- package/esm/e2e/fixture.mjs.map +1 -0
- package/esm/e2e/index.d.mts +5 -0
- package/esm/e2e/index.mjs +6 -0
- package/esm/e2e/owned-process.mjs +193 -0
- package/esm/e2e/owned-process.mjs.map +1 -0
- package/esm/e2e/page.d.mts +64 -0
- package/esm/e2e/page.d.mts.map +1 -0
- package/esm/e2e/page.mjs +376 -0
- package/esm/e2e/page.mjs.map +1 -0
- package/esm/e2e/run-e2e.d.mts +17 -0
- package/esm/e2e/run-e2e.d.mts.map +1 -0
- package/esm/e2e/run-e2e.mjs +143 -0
- package/esm/e2e/run-e2e.mjs.map +1 -0
- package/esm/e2e/types.d.mts +123 -0
- package/esm/e2e/types.d.mts.map +1 -0
- package/esm/e2e/types.mjs +24 -0
- package/esm/e2e/types.mjs.map +1 -0
- package/esm/secrets/errors.d.mts +1 -1
- package/esm/secrets/errors.d.mts.map +1 -1
- package/esm/secrets/errors.mjs +2 -0
- package/esm/secrets/errors.mjs.map +1 -1
- package/esm/secrets/resolve-driver.mjs +14 -0
- package/esm/secrets/resolve-driver.mjs.map +1 -0
- package/esm/secrets/secret-store.d.mts.map +1 -1
- package/esm/secrets/secret-store.mjs +4 -1
- package/esm/secrets/secret-store.mjs.map +1 -1
- package/esm/secrets/secrets.d.mts.map +1 -1
- package/esm/secrets/secrets.mjs +10 -1
- package/esm/secrets/secrets.mjs.map +1 -1
- package/esm/secrets/types.d.mts +4 -0
- package/esm/secrets/types.d.mts.map +1 -1
- package/esm/tooling/check/lint-step.d.mts +3 -3
- package/esm/tooling/check/lint-step.d.mts.map +1 -1
- package/esm/tooling/check/lint-step.mjs +3 -47
- package/esm/tooling/check/lint-step.mjs.map +1 -1
- package/esm/tooling/check/run-check.d.mts +2 -2
- package/esm/tooling/check/run-check.mjs +4 -2
- package/esm/tooling/check/run-check.mjs.map +1 -1
- package/esm/tooling/problem.d.mts +1 -1
- package/esm/tooling/problem.d.mts.map +1 -1
- package/esm/tooling/problem.mjs.map +1 -1
- package/esm/updater/package-manager.mjs +5 -1
- package/esm/updater/package-manager.mjs.map +1 -1
- package/esm/upgrade/codemods/index.mjs +2 -1
- package/esm/upgrade/codemods/index.mjs.map +1 -1
- package/esm/upgrade/codemods/oxc-toolchain.mjs +59 -10
- package/esm/upgrade/codemods/oxc-toolchain.mjs.map +1 -1
- package/esm/upgrade/codemods/oxlint-rule-schemas.mjs +6 -0
- package/esm/upgrade/codemods/oxlint-rule-schemas.mjs.map +1 -0
- package/esm/upgrade/codemods/port-eslint-rules.mjs +343 -0
- package/esm/upgrade/codemods/port-eslint-rules.mjs.map +1 -0
- package/esm/upgrade/codemods/toolchain-templates.mjs +1 -1
- package/esm/upgrade/codemods/toolchain-templates.mjs.map +1 -1
- package/esm/upgrade/codemods/validate-oxlint-rule.mjs +60 -0
- package/esm/upgrade/codemods/validate-oxlint-rule.mjs.map +1 -0
- package/esm/upgrade/notes.mjs +14 -7
- package/esm/upgrade/notes.mjs.map +1 -1
- package/esm/warlock-config/types.d.mts +0 -1
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/llms-full.txt +243 -41
- package/llms.txt +2 -1
- package/package.json +19 -20
- package/skills/create-module/SKILL.md +2 -2
- package/skills/run-app/SKILL.md +3 -3
- package/skills/store-secrets/SKILL.md +40 -1
- package/skills/test-browser/SKILL.md +119 -0
- package/skills/upgrade-from-5-29/SKILL.md +70 -29
- package/skills/warlock-check/SKILL.md +3 -3
- package/skills/warlock-doctor/SKILL.md +2 -3
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +0 -152
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +0 -1
- package/esm/dev-server/health-checker/eslint-support.mjs +0 -27
- package/esm/dev-server/health-checker/eslint-support.mjs.map +0 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.d.mts +0 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs +0 -183
- package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs.map +0 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-browser
|
|
3
|
+
description: Write or repair browser e2e specs using warlock e2e and @warlock.js/core/e2e, with owned app fixtures, direct CDP interaction, responsive screenshots and run evidence. Use for real browser flows, click races or viewport overflow; use test-http for API-only tests.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Browser e2e
|
|
7
|
+
|
|
8
|
+
Use `@warlock.js/core/e2e`, a Node-only subpath, and default-export `defineE2E` from
|
|
9
|
+
`e2e/*.e2e.ts`. Run `npx warlock e2e`. The CLI loads TypeScript itself; no Vitest
|
|
10
|
+
bootstrap, Playwright, Puppeteer or external browser server is needed.
|
|
11
|
+
|
|
12
|
+
Every run copies the app into a temporary directory, excludes dotenv files and
|
|
13
|
+
symlinks, links installed dependencies for reads, seeds its own environment and
|
|
14
|
+
owns the app/browser process groups. Keep foreground commands in the fixture;
|
|
15
|
+
never use a shared dev server or daemonize. Map the disposable `dataRoot` into the
|
|
16
|
+
app's actual storage/database config. The harness cannot infer that mapping.
|
|
17
|
+
`prepare` is where seeds and fake executables belong; `app.path` is relative to the
|
|
18
|
+
copied app. Do not install dependencies through the shared `node_modules` link.
|
|
19
|
+
|
|
20
|
+
## Complete standalone spec
|
|
21
|
+
|
|
22
|
+
This spec creates its own small app; it can be pasted into an existing project
|
|
23
|
+
with core installed and run with `npx warlock e2e`.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
import { defineE2E } from "@warlock.js/core/e2e";
|
|
29
|
+
|
|
30
|
+
export default defineE2E({
|
|
31
|
+
app: {
|
|
32
|
+
start: [process.execPath, "form-fixture.mjs"],
|
|
33
|
+
portFromFile: true,
|
|
34
|
+
path: ["fake-bin"],
|
|
35
|
+
env: ({ dataRoot }) => ({ FORM_DATA: dataRoot }),
|
|
36
|
+
prepare: async ({ directory, dataRoot }) => {
|
|
37
|
+
await mkdir(join(directory, "fake-bin"));
|
|
38
|
+
await writeFile(join(dataRoot, "prefix.txt"), "Saved");
|
|
39
|
+
await writeFile(
|
|
40
|
+
join(directory, "form-fixture.mjs"),
|
|
41
|
+
`
|
|
42
|
+
import { createServer } from 'node:http';
|
|
43
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
44
|
+
import { join } from 'node:path';
|
|
45
|
+
const prefix = readFileSync(join(process.env.FORM_DATA, 'prefix.txt'), 'utf8');
|
|
46
|
+
const server = createServer((request, response) => {
|
|
47
|
+
if (request.url === '/favicon.ico') { response.writeHead(204); response.end(); return; }
|
|
48
|
+
response.setHeader('Content-Type', 'text/html');
|
|
49
|
+
response.end('<!doctype html><meta name="viewport" content="width=device-width,initial-scale=1">'
|
|
50
|
+
+ '<input id="name"><button id="save"><span>Save</span></button><h1 id="result">Ready</h1>'
|
|
51
|
+
+ '<script>document.querySelector("#save").onclick=()=>{history.pushState({},"","/saved");document.querySelector("#result").textContent='
|
|
52
|
+
+ JSON.stringify(prefix) + '+" "+document.querySelector("#name").value}</script>');
|
|
53
|
+
});
|
|
54
|
+
server.listen(0, '127.0.0.1', () => writeFileSync(process.env.WARLOCK_E2E_PORT_FILE, String(server.address().port)));
|
|
55
|
+
`,
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
run: async ({ page, step }) => {
|
|
60
|
+
await page.goto("/");
|
|
61
|
+
await step("save the form", async () => {
|
|
62
|
+
await page.fill("#name", "Ada");
|
|
63
|
+
await page.type("#name", " Lovelace");
|
|
64
|
+
await page.waitForNavigation(() => page.click("#save"), { url: "/saved" });
|
|
65
|
+
await page.waitFor({ selector: "#result", text: "Saved Ada Lovelace" });
|
|
66
|
+
});
|
|
67
|
+
await page.captureViewports("saved");
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For an existing app, replace `prepare` and `start`; default start is
|
|
73
|
+
`[process.execPath, "dist/app.js"]`. Optional
|
|
74
|
+
`build: [process.execPath, "node_modules/@warlock.js/core/bin/warlock.js", "build"]`
|
|
75
|
+
builds inside the copy. Supply app-specific test service variables via `env` and
|
|
76
|
+
exclude production data directories with `exclude: ["storage", "data"]`.
|
|
77
|
+
By default the fixture supplies an OS-assigned `PORT`/`HTTP_PORT`. Prefer the
|
|
78
|
+
port-file handshake above when the app supports binding `0` itself.
|
|
79
|
+
|
|
80
|
+
## Interaction and evidence
|
|
81
|
+
|
|
82
|
+
- Use `page.click` for scrolling, settled boxes and hit testing, including a fresh
|
|
83
|
+
check after hover. Do not replace it with `element.click()` or fixed sleeps.
|
|
84
|
+
- `fill` clears editable content, then sends CDP text input; `type` appends Unicode
|
|
85
|
+
text. Values do not appear in step names. `type` does not simulate shortcuts.
|
|
86
|
+
- `waitFor({ selector, text, url, timeoutMs })` combines conditions. Arm navigation
|
|
87
|
+
**before** clicking with `waitForNavigation(() => page.click(...))`.
|
|
88
|
+
- `setViewport({ name, width, height, mobile })`, `assertViewport()` and
|
|
89
|
+
`screenshot(name)` are available independently. `captureViewports(name)` checks
|
|
90
|
+
and captures 1280×800 desktop and 390×844 phone by default, restoring the
|
|
91
|
+
original viewport. `viewports` overrides the list. Final captures are automatic.
|
|
92
|
+
- Overflow compares document/body scrollWidth **and innerWidth** against the
|
|
93
|
+
requested width, so a phone that expands to 448 px fails. Keep the viewport meta
|
|
94
|
+
tag; inspect the reported widest element IDs, classes and dimensions.
|
|
95
|
+
- Health requires zero console errors, exceptions, HTTP statuses >=400 and failed
|
|
96
|
+
loads (including cancellation). Narrow exceptions use
|
|
97
|
+
`allowConsoleErrors: [/^Expected warning$/]` and
|
|
98
|
+
`allowNetworkFailures: [{ url: "/missing", status: 404 }]`. Canceled-request rules
|
|
99
|
+
can match `errorText`. Strings match substrings; regexps are also accepted.
|
|
100
|
+
- `allowPendingRequests: ["/events"]` exempts an intentional stream from network
|
|
101
|
+
idle, without allowing its errors. `waitForNetworkIdle()` remains available.
|
|
102
|
+
- `page.evaluate<T>(expression)` is an escape hatch for assertions in the main
|
|
103
|
+
document. Selector helpers do not enter frames or closed shadow roots.
|
|
104
|
+
|
|
105
|
+
Use `--browser /path/to/chrome` or `WARLOCK_E2E_BROWSER` if discovery fails.
|
|
106
|
+
`browser: { args: ["--no-sandbox"] }` is an explicit option for controlled root
|
|
107
|
+
containers; it is not a default. On Windows, command arrays should invoke JS tools
|
|
108
|
+
through `process.execPath`, avoiding `.cmd` executables that require a shell.
|
|
109
|
+
|
|
110
|
+
Read `.warlock/e2e/run-*/evidence.json` and the PNGs/logs on failure. Evidence keeps
|
|
111
|
+
allowed errors, step timings, viewport dimensions and recorded process identities.
|
|
112
|
+
`--out` changes the evidence parent; `--path ./fake-bin,./engine-bin` prepends fake
|
|
113
|
+
binary paths. `runE2E(spec, { outputDirectory, browser, path, signal })` is the
|
|
114
|
+
programmatic runner; `E2ERunError.result` exposes evidence on failure.
|
|
115
|
+
|
|
116
|
+
Cleanup verifies the unique supervisor command line before stopping only its
|
|
117
|
+
recorded process group (Windows: verified PID tree). It retains disposable files
|
|
118
|
+
if ownership verification fails and reports the failure in evidence. Do not add
|
|
119
|
+
process-name or port-based kills to a spec.
|
|
@@ -441,51 +441,92 @@ The CLI preserves incremental state and changed-file filtering. Development
|
|
|
441
441
|
health checks keep one native compiler session and update its snapshots. Syntax
|
|
442
442
|
analysis uses OXC. `warlock upgrade` still parses/transforms with ts-morph's own
|
|
443
443
|
bundled TypeScript, without using it as the app's compiler. New scaffolds default
|
|
444
|
-
to Oxlint/Oxfmt (`--lint=oxc`)
|
|
445
|
-
|
|
446
|
-
and supports `>=4.8.4 <6.1.0`. Keep ESLint apps on 6.0.3 until switching tools:
|
|
447
|
-
|
|
448
|
-
```bash
|
|
449
|
-
npm install --save-dev --save-exact typescript@6.0.3
|
|
450
|
-
npx tsc --noEmit
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
The same tsconfig cleanups work with TS6. Starting in 5.33, ESLint mode prints
|
|
454
|
-
a deprecation warning naming removal in 5.34.0 and the Oxc migration command.
|
|
444
|
+
to Oxlint/Oxfmt (`--lint=oxc`) with TypeScript 7.0.2. ESLint support was
|
|
445
|
+
removed in 5.34.0; migrate legacy apps using the steps below.
|
|
455
446
|
|
|
456
447
|
## 5.32 to 5.33
|
|
457
448
|
|
|
458
|
-
|
|
459
|
-
in `warlock check` are disabled by default. Oxlint/Oxfmt replace ESLint/Prettier
|
|
460
|
-
as the default toolchain. Legacy support is deprecated now and removed in
|
|
461
|
-
5.34.0. Temporary opt-ins are `devServer.healthCheckers: { eslint: true }`,
|
|
462
|
-
`warlock check --lint eslint`, and `create-warlock --lint=eslint`; each warns
|
|
463
|
-
about removal and migration. The legacy scaffold stays on TypeScript 6.0.3;
|
|
464
|
-
Oxc apps use TypeScript 7.0.2.
|
|
465
|
-
|
|
466
|
-
ESLint + Prettier are deprecated in 5.33.0 and will be removed in **5.34.0**.
|
|
467
|
-
New apps should use `--lint=oxc`. To migrate an existing app, install the new
|
|
468
|
-
core release and `ts-morph`, then run:
|
|
449
|
+
The original `oxc-toolchain` codemod remains available:
|
|
469
450
|
|
|
470
451
|
```bash
|
|
471
452
|
npx warlock upgrade --from 5.32 --to 5.33.0 --dry-run
|
|
472
453
|
npx warlock upgrade --from 5.32 --to 5.33.0
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## 5.33 to 5.34 toolchain removal
|
|
457
|
+
|
|
458
|
+
**BREAKING:** ESLint and Prettier support was removed in **5.34.0**. Oxlint/Oxfmt is the only
|
|
459
|
+
supported toolchain. `--lint eslint` and `healthCheckers.eslint` are removed.
|
|
460
|
+
Install the new core release and `ts-morph`, then migrate an existing app:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
npm install --save-dev ts-morph
|
|
464
|
+
npx warlock upgrade --from 5.33 --to 5.34.0 --dry-run
|
|
465
|
+
npx warlock upgrade --from 5.33 --to 5.34.0
|
|
473
466
|
npm install
|
|
474
467
|
npm run format
|
|
475
468
|
npm run lint:check
|
|
476
469
|
npx warlock check
|
|
477
470
|
```
|
|
478
471
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
without writing files.
|
|
472
|
+
The `oxc-toolchain-removal` step reapplies the preserved 5.33 `oxc-toolchain`
|
|
473
|
+
migration when legacy configs, scripts or dependencies remain. Apps upgrading
|
|
474
|
+
from 5.32 can still use `npx warlock upgrade --from 5.32 --to 5.33.0` first.
|
|
475
|
+
It replaces standard scripts/dependencies, pins TypeScript 7.0.2, updates generated
|
|
476
|
+
editor settings, removes `healthCheckers.eslint` and selects Oxlint. A generated
|
|
477
|
+
`.prettierignore` becomes `.oxfmtignore`; Oxfmt scripts read it explicitly.
|
|
486
478
|
|
|
487
479
|
The `oxc-toolchain` codemod also updates generated VS Code settings and literal
|
|
488
480
|
ESLint/Oxlint health-check switches. Custom editor settings, checker arrays,
|
|
489
481
|
computed options and nonstandard scripts require review. Oxc diagnostics keep
|
|
490
482
|
framework conventions in `warlock check`. Re-run the migration after addressing
|
|
491
483
|
manual findings if needed; an app with only Oxc tooling is a no-op for this codemod.
|
|
484
|
+
|
|
485
|
+
## 5.33 to 5.34 plain object validation
|
|
486
|
+
|
|
487
|
+
**BREAKING:** Seal `v.object()` rejects arrays, dates, maps, sets, class instances
|
|
488
|
+
and objects with custom prototypes, including under `.allowUnknown()` and
|
|
489
|
+
`.stripUnknown()`. Plain and null-prototype dictionaries remain accepted. There
|
|
490
|
+
is no permissive opt-in: choose an array/instance validator or construct a plain
|
|
491
|
+
DTO explicitly before validation.
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
import { v } from "@warlock.js/seal";
|
|
495
|
+
|
|
496
|
+
class User {
|
|
497
|
+
name = "Ada";
|
|
498
|
+
}
|
|
499
|
+
const instance = new User();
|
|
500
|
+
const user = v.object({ name: v.string() });
|
|
501
|
+
await v.validate(user, { name: instance.name });
|
|
502
|
+
const names = v.array(v.string());
|
|
503
|
+
await v.validate(names, ["Ada"]);
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
`v.record(valueValidator)` remains supported. To validate dictionary keys, use
|
|
507
|
+
`v.record(keyValidator, valueValidator)`; malformed arguments now fail while
|
|
508
|
+
defining the schema. Literal-key records infer partial dictionaries because
|
|
509
|
+
only present keys are checked.
|
|
510
|
+
Literal custom rules are translated without executing the config. Per-folder
|
|
511
|
+
`no-restricted-imports` and `no-restricted-exports` become Oxlint overrides with
|
|
512
|
+
file/exclusion patterns. Supported `@typescript-eslint/*` rules become native
|
|
513
|
+
`typescript/*` rules (or native base rules). Options are checked against the
|
|
514
|
+
pinned Oxlint 1.88.0 schema. Type-aware equivalents enable `options.typeAware`
|
|
515
|
+
and add `oxlint-tsgolint@7.0.2004` to the app's dev dependencies.
|
|
516
|
+
`unused-imports/no-unused-imports` uses `no-unused-vars` with safe import fixes;
|
|
517
|
+
Oxlint shares the severity for imports and variables, so differing active
|
|
518
|
+
severities are reported for review.
|
|
519
|
+
|
|
520
|
+
Only unsupported rules/options, computed or imported settings, selectors such
|
|
521
|
+
as `no-restricted-syntax`, and conflicting existing Oxc rules need manual review.
|
|
522
|
+
Each finding names its source `file:line`, rule and affected file patterns.
|
|
523
|
+
Fully ported lint configs are removed; configs with findings remain for reference
|
|
524
|
+
until those findings are addressed. Existing Oxc rules are kept on conflict.
|
|
525
|
+
`--dry-run --json` reports the same plan without writes. Customized formatting,
|
|
526
|
+
editor settings and nonstandard scripts can also require review.
|
|
527
|
+
|
|
528
|
+
**Upgrading:** new and migrated template configs enable
|
|
529
|
+
`"categories": { "correctness": "error" }`. Address the additional diagnostics;
|
|
530
|
+
existing Oxc configs retain their categories. A real lockfile beside a workspace
|
|
531
|
+
marker determines the installer: `package-lock.json` plus `pnpm-workspace.yaml`
|
|
532
|
+
without `pnpm-lock.yaml` now produces `npm install`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: warlock-check
|
|
3
|
-
description: 'Verify a change with one command: `warlock check [--changed] [--json]` runs an incremental typecheck, the app''s
|
|
3
|
+
description: 'Verify a change with one command: `warlock check [--changed] [--json]` runs an incremental typecheck, the app''s Oxlint, the tests affected by the change and framework convention checks, and reports one JSON object per problem `{ code, category, severity, source, file, line, column, message, hint, skill, docs, rule }` with exit 1 for problems in your code and 2 for problems with this machine (missing Redis/DB, busy port, Node version, missing tool). Also `warlock typecheck [--changed]`, `warlock explain <CODE>` and the stable `WL` error codes (`errorCodeOf`, `WarlockError`). Triggers: `warlock check`, `warlock typecheck`, `warlock explain`, `--changed`, `--base`, `runCheck`, `runTypecheck`, `CHECK_EXIT_CODES`, `ToolingProblem`, `WL7101`, `WL8003`, `errorCodeOf`, `explainErrorCode`, `WarlockError`, "verify my change", "run the checks", "is this failure my code or the machine", "what does WL3001 mean", "typecheck only changed files". Skip: app diagnostics at boot — the `warlock-doctor` topic; reading the app''s routes/models — the `warlock-inspect` topic; writing tests — the `test-http` / `test-service` topics.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Warlock — `warlock check`, `typecheck`, `explain`
|
|
@@ -120,10 +120,10 @@ const types = runTypecheck({ files: ["src/app/posts/services/publish.service.ts"
|
|
|
120
120
|
## Gotchas
|
|
121
121
|
|
|
122
122
|
- `check` boots nothing — no config, no connection, no port — so it runs the same with or without services; only tests that need them fail, and those report `WL8003`/`WL8004`.
|
|
123
|
-
- Lint defaults to Oxlint (an app-root config + the app-installed package). No Oxlint config skips lint. A missing package reports `WL8002`. ESLint
|
|
123
|
+
- Lint defaults to Oxlint (an app-root config + the app-installed package). No Oxlint config skips lint. A missing package reports `WL8002`. ESLint support was removed in 5.34.0; see `upgrade-from-5-29`.
|
|
124
124
|
- Tests use the app's own vitest (`vitest run`, or `vitest related <files> --run` with `--changed`). Test files without vitest installed → `WL8002`.
|
|
125
125
|
- The typecheck runs in a child `warlock typecheck` process; running out of memory is reported as `WL8007` instead of ending the run.
|
|
126
|
-
- The convention checks are the framework's own and run the same with
|
|
126
|
+
- The convention checks are the framework's own and run the same with Oxlint or no linter. A deliberate exception gets `// warlock-check-ignore WL9006 -- why` on the problem's line or the line above (no code = every code on that line).
|
|
127
127
|
|
|
128
128
|
## See also
|
|
129
129
|
|
|
@@ -174,7 +174,6 @@ A `⚠ routes: 0 routes registered` line is the tell that a route module threw o
|
|
|
174
174
|
|
|
175
175
|
`warlock doctor` checks application wiring and HTTP health probes. Use
|
|
176
176
|
`npx warlock check` for source lint diagnostics and `npm run format:check` for
|
|
177
|
-
formatting.
|
|
178
|
-
`
|
|
179
|
-
background checks. ESLint/Prettier are deprecated and removed in 5.34.0.
|
|
177
|
+
formatting. Oxlint/Oxfmt are the only supported tools in 5.34.0. Use the
|
|
178
|
+
`oxc-toolchain-removal` upgrade step to migrate remaining legacy configs.
|
|
180
179
|
Migrate with `npx warlock upgrade --from 5.32 --to 5.33.0` (preview with `--dry-run`).
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { hasEslint, warnEslintDeprecation } from "../eslint-support.mjs";
|
|
2
|
-
import { BaseHealthChecker } from "./base-health-checker.mjs";
|
|
3
|
-
import { colors } from "@mongez/copper";
|
|
4
|
-
import { ESLint } from "eslint";
|
|
5
|
-
|
|
6
|
-
//#region ../../packages/core/src/dev-server/health-checker/checkers/eslint-health-checker.ts
|
|
7
|
-
/** @deprecated Use OxlintHealthChecker. ESLint support is removed in 5.34.0. */
|
|
8
|
-
var EslintHealthChecker = class extends BaseHealthChecker {
|
|
9
|
-
constructor() {
|
|
10
|
-
super();
|
|
11
|
-
this.eslint = null;
|
|
12
|
-
this.name = "ESLint";
|
|
13
|
-
this.workerPath = "./workers/eslint-health.worker";
|
|
14
|
-
this.initialized = false;
|
|
15
|
-
warnEslintDeprecation();
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Check if file is a lintable file
|
|
19
|
-
*/
|
|
20
|
-
isLintableFile(filePath) {
|
|
21
|
-
const ext = filePath.toLowerCase();
|
|
22
|
-
return ext.endsWith(".ts") || ext.endsWith(".tsx") || ext.endsWith(".js") || ext.endsWith(".jsx");
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Initialize the health checker
|
|
26
|
-
*/
|
|
27
|
-
initialize() {
|
|
28
|
-
try {
|
|
29
|
-
if (!hasEslint(process.cwd())) {
|
|
30
|
-
this.initialized = true;
|
|
31
|
-
return this;
|
|
32
|
-
}
|
|
33
|
-
this.eslint = new ESLint({ cwd: process.cwd() });
|
|
34
|
-
this.initialized = true;
|
|
35
|
-
} catch (error) {
|
|
36
|
-
console.warn("ESLint Health Checker: Failed to initialize:", error);
|
|
37
|
-
this.initialized = true;
|
|
38
|
-
}
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Display health check results in a pretty format
|
|
43
|
-
*/
|
|
44
|
-
displayResults(file, result) {
|
|
45
|
-
const stats = result.getStats();
|
|
46
|
-
if (stats.errors === 0 && stats.warnings === 0) return;
|
|
47
|
-
const fileName = file.relativePath.replace(/\\/g, "/");
|
|
48
|
-
const errorCount = stats.errors;
|
|
49
|
-
const warningCount = stats.warnings;
|
|
50
|
-
const sourceLines = file.source ? file.source.split("\n") : [];
|
|
51
|
-
if (errorCount > 0) {
|
|
52
|
-
const errorMessages = result.messages.filter((m) => m.type === "error");
|
|
53
|
-
for (const error of errorMessages) {
|
|
54
|
-
const icon = colors.redBright("✖");
|
|
55
|
-
const level = colors.redBright(colors.bold("ERROR"));
|
|
56
|
-
console.log(`\n${icon} ${level} ${colors.dim("in")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`);
|
|
57
|
-
const ruleId = error.ruleId || "eslint";
|
|
58
|
-
console.log(` ${colors.magentaBright(ruleId)} ${colors.dim("→")} ${colors.red(error.message)}`);
|
|
59
|
-
if (sourceLines.length > 0 && error.lineNumber > 0 && error.lineNumber <= sourceLines.length) {
|
|
60
|
-
const lineContent = sourceLines[error.lineNumber - 1];
|
|
61
|
-
const lineNum = error.lineNumber.toString().padStart(4, " ");
|
|
62
|
-
const errorLength = error.length || 1;
|
|
63
|
-
const columnIndex = error.columnNumber - 1;
|
|
64
|
-
console.log(` ${colors.dim(lineNum)} ${colors.dim("│")} ${lineContent || ""}`);
|
|
65
|
-
const prefixPadding = lineNum.length + 3;
|
|
66
|
-
const columnPadding = " ".repeat(columnIndex);
|
|
67
|
-
const underline = colors.redBright("~".repeat(Math.max(1, errorLength)));
|
|
68
|
-
console.log(` ${colors.dim(" ".repeat(prefixPadding))}${columnPadding}${underline}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (warningCount > 0) {
|
|
73
|
-
const warningMessages = result.messages.filter((m) => m.type === "warning");
|
|
74
|
-
for (const warning of warningMessages) {
|
|
75
|
-
const icon = colors.yellowBright("⚠");
|
|
76
|
-
const level = colors.yellowBright(colors.bold("WARNING"));
|
|
77
|
-
console.log(`\n${icon} ${level} ${colors.dim("in")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`);
|
|
78
|
-
const ruleId = warning.ruleId || "eslint";
|
|
79
|
-
console.log(` ${colors.magentaBright(ruleId)} ${colors.dim("→")} ${colors.yellow(warning.message)}`);
|
|
80
|
-
if (sourceLines.length > 0 && warning.lineNumber > 0 && warning.lineNumber <= sourceLines.length) {
|
|
81
|
-
const lineContent = sourceLines[warning.lineNumber - 1];
|
|
82
|
-
const lineNum = warning.lineNumber.toString().padStart(4, " ");
|
|
83
|
-
const warningLength = warning.length || 1;
|
|
84
|
-
const columnIndex = warning.columnNumber - 1;
|
|
85
|
-
console.log(` ${colors.dim(lineNum)} ${colors.dim("│")} ${lineContent || ""}`);
|
|
86
|
-
const prefixPadding = lineNum.length + 3;
|
|
87
|
-
const columnPadding = " ".repeat(columnIndex);
|
|
88
|
-
const underline = colors.yellowBright("~".repeat(Math.max(1, warningLength)));
|
|
89
|
-
console.log(` ${colors.dim(" ".repeat(prefixPadding))}${columnPadding}${underline}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const summary = [];
|
|
94
|
-
if (errorCount > 0) summary.push(colors.red(`${errorCount} error${errorCount > 1 ? "s" : ""}`));
|
|
95
|
-
if (warningCount > 0) summary.push(colors.yellow(`${warningCount} warning${warningCount > 1 ? "s" : ""}`));
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Validate the health of the file
|
|
99
|
-
*/
|
|
100
|
-
async validate(file, result) {
|
|
101
|
-
if (!this.isLintableFile(file.absolutePath)) {
|
|
102
|
-
result.markAsHealthy();
|
|
103
|
-
return result;
|
|
104
|
-
}
|
|
105
|
-
if (!this.eslint) {
|
|
106
|
-
result.markAsHealthy();
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
const lintResult = (await this.eslint.lintText(file.source, { filePath: file.absolutePath }))[0];
|
|
111
|
-
if (!lintResult) {
|
|
112
|
-
console.log("No lint results", file.relativePath);
|
|
113
|
-
result.markAsHealthy();
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
const errors = [];
|
|
117
|
-
const warnings = [];
|
|
118
|
-
for (const message of lintResult.messages) {
|
|
119
|
-
const isError = message.severity === 2;
|
|
120
|
-
const isWarning = message.severity === 1;
|
|
121
|
-
if (isError) errors.push({
|
|
122
|
-
message: message.message,
|
|
123
|
-
type: "error",
|
|
124
|
-
lineNumber: message.line || 1,
|
|
125
|
-
columnNumber: message.column || 1,
|
|
126
|
-
length: message.endColumn && message.column ? message.endColumn - message.column : 1,
|
|
127
|
-
ruleId: message.ruleId || void 0
|
|
128
|
-
});
|
|
129
|
-
else if (isWarning) warnings.push({
|
|
130
|
-
message: message.message,
|
|
131
|
-
type: "warning",
|
|
132
|
-
lineNumber: message.line || 1,
|
|
133
|
-
columnNumber: message.column || 1,
|
|
134
|
-
length: message.endColumn && message.column ? message.endColumn - message.column : 1,
|
|
135
|
-
ruleId: message.ruleId || void 0
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
if (errors.length > 0) result.addErrors(errors);
|
|
139
|
-
if (warnings.length > 0) result.addWarnings(warnings);
|
|
140
|
-
if (errors.length === 0 && warnings.length === 0) result.markAsHealthy();
|
|
141
|
-
else this.displayResults(file, result);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
console.log("ESlint Error:", error);
|
|
144
|
-
result.markAsHealthy();
|
|
145
|
-
}
|
|
146
|
-
return result;
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
//#endregion
|
|
151
|
-
export { EslintHealthChecker };
|
|
152
|
-
//# sourceMappingURL=eslint-health-checker.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"eslint-health-checker.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/dev-server/health-checker/checkers/eslint-health-checker.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { ESLint } from \"eslint\";\nimport { hasEslint, warnEslintDeprecation } from \"../eslint-support\";\nimport type { FileManager } from \"../../file-manager\";\nimport type { FileHealthCheckerContract } from \"../file-health-checker.contract\";\nimport { FileHealthResult } from \"../file-health-result\";\nimport { BaseHealthChecker } from \"./base-health-checker\";\n\n/** @deprecated Use OxlintHealthChecker. ESLint support is removed in 5.34.0. */\nexport class EslintHealthChecker extends BaseHealthChecker implements FileHealthCheckerContract {\n public constructor() {\n super();\n // Construction happens on the main thread for both inline and worker checking.\n warnEslintDeprecation();\n }\n\n /**\n * ESLint instance (using new ESLint v9 API with flat config)\n */\n private eslint: ESLint | null = null;\n\n /**\n * Health checker name\n */\n public name: string = \"ESLint\";\n\n /**\n * Path to dedicated worker file for ESLint checking\n * Runs in a separate thread to avoid blocking the main dev server\n */\n public workerPath: string = \"./workers/eslint-health.worker\";\n\n /**\n * Whether checker is initialized\n */\n private initialized: boolean = false;\n\n /**\n * Check if file is a lintable file\n */\n private isLintableFile(filePath: string): boolean {\n const ext = filePath.toLowerCase();\n return (\n ext.endsWith(\".ts\") || ext.endsWith(\".tsx\") || ext.endsWith(\".js\") || ext.endsWith(\".jsx\")\n );\n }\n\n /**\n * Initialize the health checker\n */\n public initialize(): EslintHealthChecker {\n try {\n const hasFlatConfig = hasEslint(process.cwd());\n\n if (!hasFlatConfig) {\n // No flat config found, skip initialization\n this.initialized = true;\n return this;\n }\n\n // Use new ESLint v9 API with flat config\n // ESLint will automatically find eslint.config.js in the project root\n this.eslint = new ESLint({\n cwd: process.cwd(),\n });\n\n this.initialized = true;\n } catch (error) {\n // Handle any errors during initialization gracefully\n console.warn(\"ESLint Health Checker: Failed to initialize:\", error);\n this.initialized = true; // Mark as initialized to prevent retries\n }\n\n return this;\n }\n\n /**\n * Display health check results in a pretty format\n */\n private displayResults(file: FileManager, result: FileHealthResult): void {\n const stats = result.getStats();\n\n // Only display if there are errors or warnings\n if (stats.errors === 0 && stats.warnings === 0) {\n return;\n }\n\n const fileName = file.relativePath.replace(/\\\\/g, \"/\");\n const errorCount = stats.errors;\n const warningCount = stats.warnings;\n const sourceLines = file.source ? file.source.split(\"\\n\") : [];\n\n // Display errors\n if (errorCount > 0) {\n const errorMessages = result.messages.filter((m) => m.type === \"error\");\n for (const error of errorMessages) {\n const icon = colors.redBright(\"✖\");\n const level = colors.redBright(colors.bold(\"ERROR\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\n );\n // Get rule ID from the error if available\n const ruleId = error.ruleId || \"eslint\";\n console.log(\n ` ${colors.magentaBright(ruleId)} ${colors.dim(\"→\")} ${colors.red(error.message)}`,\n );\n\n // Display code line with underline indicator\n if (\n sourceLines.length > 0 &&\n error.lineNumber > 0 &&\n error.lineNumber <= sourceLines.length\n ) {\n const lineIndex = error.lineNumber - 1; // Convert to 0-based index\n const lineContent = sourceLines[lineIndex];\n const lineNum = error.lineNumber.toString().padStart(4, \" \");\n const errorLength = error.length || 1;\n const columnIndex = error.columnNumber - 1; // Convert to 0-based index\n\n // Display the line with normal color (not all red)\n console.log(` ${colors.dim(lineNum)} ${colors.dim(\"│\")} ${lineContent || \"\"}`);\n\n // Display underline indicator\n // Padding accounts for: lineNum.length + 1 space + 1 (│) + 1 space = lineNum.length + 3\n // (The initial 2 spaces indent is already in the console.log)\n const prefixPadding = lineNum.length + 3;\n const columnPadding = \" \".repeat(columnIndex);\n const underline = colors.redBright(\"~\".repeat(Math.max(1, errorLength)));\n console.log(` ${colors.dim(\" \".repeat(prefixPadding))}${columnPadding}${underline}`);\n }\n }\n }\n\n // Display warnings\n if (warningCount > 0) {\n const warningMessages = result.messages.filter((m) => m.type === \"warning\");\n for (const warning of warningMessages) {\n const icon = colors.yellowBright(\"⚠\");\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\n );\n // Get rule ID from the warning if available\n const ruleId = warning.ruleId || \"eslint\";\n console.log(\n ` ${colors.magentaBright(ruleId)} ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`,\n );\n\n // Display code line with underline indicator\n if (\n sourceLines.length > 0 &&\n warning.lineNumber > 0 &&\n warning.lineNumber <= sourceLines.length\n ) {\n const lineIndex = warning.lineNumber - 1; // Convert to 0-based index\n const lineContent = sourceLines[lineIndex];\n const lineNum = warning.lineNumber.toString().padStart(4, \" \");\n const warningLength = warning.length || 1;\n const columnIndex = warning.columnNumber - 1; // Convert to 0-based index\n\n // Display the line with normal color (not all yellow)\n console.log(` ${colors.dim(lineNum)} ${colors.dim(\"│\")} ${lineContent || \"\"}`);\n\n // Display underline indicator\n // Padding accounts for: lineNum.length + 1 space + 1 (│) + 1 space = lineNum.length + 3\n // (The initial 2 spaces indent is already in the console.log)\n const prefixPadding = lineNum.length + 3;\n const columnPadding = \" \".repeat(columnIndex);\n const underline = colors.yellowBright(\"~\".repeat(Math.max(1, warningLength)));\n console.log(` ${colors.dim(\" \".repeat(prefixPadding))}${columnPadding}${underline}`);\n }\n }\n }\n\n // Display summary\n const summary = [];\n if (errorCount > 0) {\n summary.push(colors.red(`${errorCount} error${errorCount > 1 ? \"s\" : \"\"}`));\n }\n if (warningCount > 0) {\n summary.push(colors.yellow(`${warningCount} warning${warningCount > 1 ? \"s\" : \"\"}`));\n }\n }\n\n /**\n * Validate the health of the file\n */\n public async validate(file: FileManager, result: FileHealthResult): Promise<FileHealthResult> {\n // Early exit: skip non-lintable files\n if (!this.isLintableFile(file.absolutePath)) {\n result.markAsHealthy();\n return result;\n }\n\n // Early exit: check if ESLint is available\n if (!this.eslint) {\n result.markAsHealthy();\n return result;\n }\n\n try {\n // Use lintText to lint the source code directly from FileManager\n // This ensures we always use the latest content\n const lintResults = await this.eslint.lintText(file.source, {\n filePath: file.absolutePath,\n });\n\n const lintResult = lintResults[0];\n if (!lintResult) {\n console.log(\"No lint results\", file.relativePath);\n result.markAsHealthy();\n return result;\n }\n\n // Convert ESLint messages to FileHealthResult format\n const errors: Array<{\n message: string;\n type: \"error\";\n lineNumber: number;\n columnNumber: number;\n length: number;\n ruleId?: string;\n }> = [];\n const warnings: Array<{\n message: string;\n type: \"warning\";\n lineNumber: number;\n columnNumber: number;\n length: number;\n ruleId?: string;\n }> = [];\n\n for (const message of lintResult.messages) {\n const isError = message.severity === 2;\n const isWarning = message.severity === 1;\n\n if (isError) {\n errors.push({\n message: message.message,\n type: \"error\",\n lineNumber: message.line || 1,\n columnNumber: message.column || 1,\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\n ruleId: message.ruleId || undefined,\n });\n } else if (isWarning) {\n warnings.push({\n message: message.message,\n type: \"warning\",\n lineNumber: message.line || 1,\n columnNumber: message.column || 1,\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\n ruleId: message.ruleId || undefined,\n });\n }\n }\n\n // Add errors and warnings to result\n if (errors.length > 0) {\n result.addErrors(errors);\n }\n\n if (warnings.length > 0) {\n result.addWarnings(warnings);\n }\n\n // If no errors or warnings, mark as healthy\n if (errors.length === 0 && warnings.length === 0) {\n result.markAsHealthy();\n } else {\n // Display results if there are errors or warnings\n this.displayResults(file, result);\n }\n } catch (error) {\n // Handle any errors during validation gracefully\n console.log(\"ESlint Error:\", error);\n result.markAsHealthy(); // Return healthy on error to avoid blocking\n }\n\n return result;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
|
|
4
|
-
//#region ../../packages/core/src/dev-server/health-checker/eslint-support.ts
|
|
5
|
-
/** Whether the app has an ESLint flat config at its root. */
|
|
6
|
-
function hasEslint(cwd) {
|
|
7
|
-
return [
|
|
8
|
-
"js",
|
|
9
|
-
"mjs",
|
|
10
|
-
"cjs",
|
|
11
|
-
"ts",
|
|
12
|
-
"mts",
|
|
13
|
-
"cts"
|
|
14
|
-
].some((extension) => existsSync(path.join(cwd, `eslint.config.${extension}`)));
|
|
15
|
-
}
|
|
16
|
-
const ESLINT_DEPRECATION = "Deprecated: ESLint + Prettier support will be removed in 5.34.0. Migrate to Oxlint + Oxfmt with npx warlock upgrade --from 5.32 --to 5.33.0; remove the ESLint opt-in afterwards.";
|
|
17
|
-
let warned = false;
|
|
18
|
-
/** One warning per process, on stderr so JSON reports stay parseable. */
|
|
19
|
-
function warnEslintDeprecation() {
|
|
20
|
-
if (warned) return;
|
|
21
|
-
warned = true;
|
|
22
|
-
console.warn(ESLINT_DEPRECATION);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
//#endregion
|
|
26
|
-
export { ESLINT_DEPRECATION, hasEslint, warnEslintDeprecation };
|
|
27
|
-
//# sourceMappingURL=eslint-support.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"eslint-support.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/eslint-support.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\n/** Whether the app has an ESLint flat config at its root. */\nexport function hasEslint(cwd: string): boolean {\n return [\"js\", \"mjs\", \"cjs\", \"ts\", \"mts\", \"cts\"].some((extension) =>\n existsSync(path.join(cwd, `eslint.config.${extension}`)),\n );\n}\n\nexport const ESLINT_DEPRECATION =\n \"Deprecated: ESLint + Prettier support will be removed in 5.34.0. Migrate to Oxlint + Oxfmt with npx warlock upgrade --from 5.32 --to 5.33.0; remove the ESLint opt-in afterwards.\";\n\nlet warned = false;\n\n/** One warning per process, on stderr so JSON reports stay parseable. */\nexport function warnEslintDeprecation(): void {\n if (warned) return;\n warned = true;\n console.warn(ESLINT_DEPRECATION);\n}\n"],"mappings":";;;;;AAIA,SAAgB,UAAU,KAAsB;CAC9C,OAAO;EAAC;EAAM;EAAO;EAAO;EAAM;EAAO;CAAK,CAAC,CAAC,MAAM,cACpD,WAAW,KAAK,KAAK,KAAK,iBAAiB,WAAW,CAAC,CACzD;AACF;AAEA,MAAa,qBACX;AAEF,IAAI,SAAS;;AAGb,SAAgB,wBAA8B;CAC5C,IAAI,QAAQ;CACZ,SAAS;CACT,QAAQ,KAAK,kBAAkB;AACjC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {}
|