@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
package/llms-full.txt
CHANGED
|
@@ -1879,8 +1879,8 @@ await warmupProductCache();
|
|
|
1879
1879
|
|
|
1880
1880
|
## Verify generated imports
|
|
1881
1881
|
|
|
1882
|
-
Generated web starter files match the scaffold’s
|
|
1883
|
-
|
|
1882
|
+
Generated web starter files match the scaffold’s Oxfmt configuration and its
|
|
1883
|
+
built-in import sorting.
|
|
1884
1884
|
After editing generated code, run `npm run format` and `npm run lint:check`.
|
|
1885
1885
|
Formatting retains unused imports; the linter reports them.
|
|
1886
1886
|
|
|
@@ -4580,7 +4580,7 @@ export default defineConfig({
|
|
|
4580
4580
|
|
|
4581
4581
|
- **`watch.include` / `watch.exclude`** — globs piped into the file watcher. Override when you have non-`.ts(x)` files driving reloads (e.g. SQL fixtures), or to exclude a generated folder.
|
|
4582
4582
|
- **`generateTypings`** — turn off if you're committing generated typings and don't want them rewritten on every boot. The `--skip-typings` flag is the per-run version.
|
|
4583
|
-
- **`healthCheckers`** — built-in switches (`{ typescript?,
|
|
4583
|
+
- **`healthCheckers`** — built-in switches (`{ typescript?, oxlint? }`), custom checker arrays, or `false`. TypeScript and installed/configured Oxlint run by default. `--skip-health` disables checks for one run. ESLint support was removed in 5.34.0; use `npx warlock upgrade --from 5.33 --to 5.34.0` to remove stale options.
|
|
4584
4584
|
- **`transpileCacheDebug`** — diagnostic only. Names `.warlock/transpile/*.js` files `<slug>.<hash>.js` and appends `// @source <path>` markers so you can eyeball which cache entry came from which source. Leave off in normal use.
|
|
4585
4585
|
- **`checkForUpdates`** — on `warlock dev` start, check npm for a newer `@warlock.js/core` and print a one-line notice if one exists. Best-effort and non-blocking; auto-skipped in CI and non-TTY shells. In an interactive terminal the notice arms a **`u` shortcut** that updates every `@warlock.js/*` package, installs, and restarts the server; elsewhere it prints `npx warlock update` instead. The registry answer is cached for 24h in `.warlock/update-check.json`, so a day of restarts costs one lookup. See the `update-packages` topic.
|
|
4586
4586
|
- **`restartOnConfigChange`** — restart the dev server when `warlock.config.ts` or any `.env*` changes (default `true`). Set `false` to get a warning instead and restart by hand. Neither file can be hot-reloaded, so without a restart the running services keep the old values.
|
|
@@ -4603,12 +4603,12 @@ import { defineConfig } from "@warlock.js/core";
|
|
|
4603
4603
|
|
|
4604
4604
|
export default defineConfig({
|
|
4605
4605
|
devServer: {
|
|
4606
|
-
healthCheckers: { typescript: true,
|
|
4606
|
+
healthCheckers: { typescript: true, oxlint: true },
|
|
4607
4607
|
},
|
|
4608
4608
|
});
|
|
4609
4609
|
```
|
|
4610
4610
|
|
|
4611
|
-
Omit
|
|
4611
|
+
Omit switches to run TypeScript and installed/configured Oxlint. Set `oxlint: false` to disable only Oxlint. A custom checker array replaces the built-in list. JSON/JSONC configs work on Node 22.15; current Oxlint TypeScript configs require Node 22.18 or newer.
|
|
4612
4612
|
|
|
4613
4613
|
## `warlock build` — production bundle
|
|
4614
4614
|
|
|
@@ -6588,10 +6588,172 @@ Options also allow a `directory` and `encryptionKey` (string or lazy callback);
|
|
|
6588
6588
|
|
|
6589
6589
|
## Error and logging contract
|
|
6590
6590
|
|
|
6591
|
-
`SecretStoreError.code` is `INVALID_NAME`, `INVALID_VALUE`, `INVALID_NAMESPACE`, `READ_ONLY`, `KEY_REQUIRED`, `UNAVAILABLE`, `UNSAFE_FILE` or `CORRUPT_FILE`. Errors never include names, values, paths or vendor causes. `KEY_REQUIRED` means provision/fix the app encryption key; `CORRUPT_FILE` means wrong key, invalid format or failed authentication. Never replace an unreadable store with an empty one.
|
|
6591
|
+
`SecretStoreError.code` is `INVALID_DRIVER`, `MEMORY_IN_PRODUCTION`, `INVALID_NAME`, `INVALID_VALUE`, `INVALID_NAMESPACE`, `READ_ONLY`, `KEY_REQUIRED`, `UNAVAILABLE`, `UNSAFE_FILE` or `CORRUPT_FILE`. Errors never include names, values, paths or vendor causes. `KEY_REQUIRED` means provision/fix the app encryption key; `CORRUPT_FILE` means wrong key, invalid format or failed authentication. Never replace an unreadable store with an empty one.
|
|
6592
6592
|
|
|
6593
6593
|
The store never logs credentials. It registers encountered names and literal values with `@warlock.js/logger` for process-lifetime masking, including old/removed/failed-write values, interpolated messages, Error text/causes, and channel error reports. Keys and exact values stay protected even with permissive custom censors. Registration retains values in memory. It cannot mask direct console/third-party logging, earlier logs, transformed/encoded values, or credentials never encountered by the store. Keep secrets out of logs even with masking enabled. Fake assertion errors do not print values.
|
|
6594
6594
|
|
|
6595
|
+
## Built-app tests with the memory driver
|
|
6596
|
+
|
|
6597
|
+
Run the built server with `SECRETS_DRIVER=memory`, or select the driver in
|
|
6598
|
+
`src/config/secrets.ts`. Explicit config takes precedence over the environment;
|
|
6599
|
+
`"auto"` (the default) keeps keychain/environment/file behavior. Unknown driver
|
|
6600
|
+
names fail with `SecretStoreError.code === "INVALID_DRIVER"`.
|
|
6601
|
+
|
|
6602
|
+
```ts title="src/config/secrets.ts"
|
|
6603
|
+
import type { SecretsConfigurations } from "@warlock.js/core";
|
|
6604
|
+
|
|
6605
|
+
export default {
|
|
6606
|
+
namespace: "browser-test-server",
|
|
6607
|
+
driver: "memory",
|
|
6608
|
+
allowMemoryInProduction: true,
|
|
6609
|
+
} satisfies SecretsConfigurations;
|
|
6610
|
+
```
|
|
6611
|
+
|
|
6612
|
+
`allowMemoryInProduction: true` is required only when the test server runs with
|
|
6613
|
+
`NODE_ENV=production`. Without it, memory selection fails closed with
|
|
6614
|
+
`MEMORY_IN_PRODUCTION`; a built bundle does not bypass this check. Set this
|
|
6615
|
+
option explicitly in the test deployment configuration. `SecretStore` accepts
|
|
6616
|
+
the same `driver` and `allowMemoryInProduction` options for standalone stores.
|
|
6617
|
+
|
|
6618
|
+
The selected memory driver bypasses keychain, scoped environment secrets and
|
|
6619
|
+
files, and still registers values for log masking. Values are isolated by app
|
|
6620
|
+
namespace, lost on process exit, and never shared across workers or with a
|
|
6621
|
+
separate browser-test process. Seed fixtures through application startup or a
|
|
6622
|
+
test-only endpoint in the server process using the normal `secrets.set()` API:
|
|
6623
|
+
|
|
6624
|
+
```ts
|
|
6625
|
+
import { secrets } from "@warlock.js/core";
|
|
6626
|
+
|
|
6627
|
+
await secrets.set("vendor-token", "browser-test-credential");
|
|
6628
|
+
const token = await secrets.get("vendor-token");
|
|
6629
|
+
```
|
|
6630
|
+
|
|
6631
|
+
The normal test harness still installs `secretsFake`; explicit `backend`
|
|
6632
|
+
instances and that fake continue to bypass configured backend selection.
|
|
6633
|
+
|
|
6634
|
+
|
|
6635
|
+
## test-browser `@warlock.js/core/test-browser/SKILL.md`
|
|
6636
|
+
|
|
6637
|
+
---
|
|
6638
|
+
name: test-browser
|
|
6639
|
+
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.
|
|
6640
|
+
---
|
|
6641
|
+
|
|
6642
|
+
# Browser e2e
|
|
6643
|
+
|
|
6644
|
+
Use `@warlock.js/core/e2e`, a Node-only subpath, and default-export `defineE2E` from
|
|
6645
|
+
`e2e/*.e2e.ts`. Run `npx warlock e2e`. The CLI loads TypeScript itself; no Vitest
|
|
6646
|
+
bootstrap, Playwright, Puppeteer or external browser server is needed.
|
|
6647
|
+
|
|
6648
|
+
Every run copies the app into a temporary directory, excludes dotenv files and
|
|
6649
|
+
symlinks, links installed dependencies for reads, seeds its own environment and
|
|
6650
|
+
owns the app/browser process groups. Keep foreground commands in the fixture;
|
|
6651
|
+
never use a shared dev server or daemonize. Map the disposable `dataRoot` into the
|
|
6652
|
+
app's actual storage/database config. The harness cannot infer that mapping.
|
|
6653
|
+
`prepare` is where seeds and fake executables belong; `app.path` is relative to the
|
|
6654
|
+
copied app. Do not install dependencies through the shared `node_modules` link.
|
|
6655
|
+
|
|
6656
|
+
## Complete standalone spec
|
|
6657
|
+
|
|
6658
|
+
This spec creates its own small app; it can be pasted into an existing project
|
|
6659
|
+
with core installed and run with `npx warlock e2e`.
|
|
6660
|
+
|
|
6661
|
+
```ts
|
|
6662
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
6663
|
+
import { join } from "node:path";
|
|
6664
|
+
import { defineE2E } from "@warlock.js/core/e2e";
|
|
6665
|
+
|
|
6666
|
+
export default defineE2E({
|
|
6667
|
+
app: {
|
|
6668
|
+
start: [process.execPath, "form-fixture.mjs"],
|
|
6669
|
+
portFromFile: true,
|
|
6670
|
+
path: ["fake-bin"],
|
|
6671
|
+
env: ({ dataRoot }) => ({ FORM_DATA: dataRoot }),
|
|
6672
|
+
prepare: async ({ directory, dataRoot }) => {
|
|
6673
|
+
await mkdir(join(directory, "fake-bin"));
|
|
6674
|
+
await writeFile(join(dataRoot, "prefix.txt"), "Saved");
|
|
6675
|
+
await writeFile(
|
|
6676
|
+
join(directory, "form-fixture.mjs"),
|
|
6677
|
+
`
|
|
6678
|
+
import { createServer } from 'node:http';
|
|
6679
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
6680
|
+
import { join } from 'node:path';
|
|
6681
|
+
const prefix = readFileSync(join(process.env.FORM_DATA, 'prefix.txt'), 'utf8');
|
|
6682
|
+
const server = createServer((request, response) => {
|
|
6683
|
+
if (request.url === '/favicon.ico') { response.writeHead(204); response.end(); return; }
|
|
6684
|
+
response.setHeader('Content-Type', 'text/html');
|
|
6685
|
+
response.end('<!doctype html><meta name="viewport" content="width=device-width,initial-scale=1">'
|
|
6686
|
+
+ '<input id="name"><button id="save"><span>Save</span></button><h1 id="result">Ready</h1>'
|
|
6687
|
+
+ '<script>document.querySelector("#save").onclick=()=>{history.pushState({},"","/saved");document.querySelector("#result").textContent='
|
|
6688
|
+
+ JSON.stringify(prefix) + '+" "+document.querySelector("#name").value}</script>');
|
|
6689
|
+
});
|
|
6690
|
+
server.listen(0, '127.0.0.1', () => writeFileSync(process.env.WARLOCK_E2E_PORT_FILE, String(server.address().port)));
|
|
6691
|
+
`,
|
|
6692
|
+
);
|
|
6693
|
+
},
|
|
6694
|
+
},
|
|
6695
|
+
run: async ({ page, step }) => {
|
|
6696
|
+
await page.goto("/");
|
|
6697
|
+
await step("save the form", async () => {
|
|
6698
|
+
await page.fill("#name", "Ada");
|
|
6699
|
+
await page.type("#name", " Lovelace");
|
|
6700
|
+
await page.waitForNavigation(() => page.click("#save"), { url: "/saved" });
|
|
6701
|
+
await page.waitFor({ selector: "#result", text: "Saved Ada Lovelace" });
|
|
6702
|
+
});
|
|
6703
|
+
await page.captureViewports("saved");
|
|
6704
|
+
},
|
|
6705
|
+
});
|
|
6706
|
+
```
|
|
6707
|
+
|
|
6708
|
+
For an existing app, replace `prepare` and `start`; default start is
|
|
6709
|
+
`[process.execPath, "dist/app.js"]`. Optional
|
|
6710
|
+
`build: [process.execPath, "node_modules/@warlock.js/core/bin/warlock.js", "build"]`
|
|
6711
|
+
builds inside the copy. Supply app-specific test service variables via `env` and
|
|
6712
|
+
exclude production data directories with `exclude: ["storage", "data"]`.
|
|
6713
|
+
By default the fixture supplies an OS-assigned `PORT`/`HTTP_PORT`. Prefer the
|
|
6714
|
+
port-file handshake above when the app supports binding `0` itself.
|
|
6715
|
+
|
|
6716
|
+
## Interaction and evidence
|
|
6717
|
+
|
|
6718
|
+
- Use `page.click` for scrolling, settled boxes and hit testing, including a fresh
|
|
6719
|
+
check after hover. Do not replace it with `element.click()` or fixed sleeps.
|
|
6720
|
+
- `fill` clears editable content, then sends CDP text input; `type` appends Unicode
|
|
6721
|
+
text. Values do not appear in step names. `type` does not simulate shortcuts.
|
|
6722
|
+
- `waitFor({ selector, text, url, timeoutMs })` combines conditions. Arm navigation
|
|
6723
|
+
**before** clicking with `waitForNavigation(() => page.click(...))`.
|
|
6724
|
+
- `setViewport({ name, width, height, mobile })`, `assertViewport()` and
|
|
6725
|
+
`screenshot(name)` are available independently. `captureViewports(name)` checks
|
|
6726
|
+
and captures 1280×800 desktop and 390×844 phone by default, restoring the
|
|
6727
|
+
original viewport. `viewports` overrides the list. Final captures are automatic.
|
|
6728
|
+
- Overflow compares document/body scrollWidth **and innerWidth** against the
|
|
6729
|
+
requested width, so a phone that expands to 448 px fails. Keep the viewport meta
|
|
6730
|
+
tag; inspect the reported widest element IDs, classes and dimensions.
|
|
6731
|
+
- Health requires zero console errors, exceptions, HTTP statuses >=400 and failed
|
|
6732
|
+
loads (including cancellation). Narrow exceptions use
|
|
6733
|
+
`allowConsoleErrors: [/^Expected warning$/]` and
|
|
6734
|
+
`allowNetworkFailures: [{ url: "/missing", status: 404 }]`. Canceled-request rules
|
|
6735
|
+
can match `errorText`. Strings match substrings; regexps are also accepted.
|
|
6736
|
+
- `allowPendingRequests: ["/events"]` exempts an intentional stream from network
|
|
6737
|
+
idle, without allowing its errors. `waitForNetworkIdle()` remains available.
|
|
6738
|
+
- `page.evaluate<T>(expression)` is an escape hatch for assertions in the main
|
|
6739
|
+
document. Selector helpers do not enter frames or closed shadow roots.
|
|
6740
|
+
|
|
6741
|
+
Use `--browser /path/to/chrome` or `WARLOCK_E2E_BROWSER` if discovery fails.
|
|
6742
|
+
`browser: { args: ["--no-sandbox"] }` is an explicit option for controlled root
|
|
6743
|
+
containers; it is not a default. On Windows, command arrays should invoke JS tools
|
|
6744
|
+
through `process.execPath`, avoiding `.cmd` executables that require a shell.
|
|
6745
|
+
|
|
6746
|
+
Read `.warlock/e2e/run-*/evidence.json` and the PNGs/logs on failure. Evidence keeps
|
|
6747
|
+
allowed errors, step timings, viewport dimensions and recorded process identities.
|
|
6748
|
+
`--out` changes the evidence parent; `--path ./fake-bin,./engine-bin` prepends fake
|
|
6749
|
+
binary paths. `runE2E(spec, { outputDirectory, browser, path, signal })` is the
|
|
6750
|
+
programmatic runner; `E2ERunError.result` exposes evidence on failure.
|
|
6751
|
+
|
|
6752
|
+
Cleanup verifies the unique supervisor command line before stopping only its
|
|
6753
|
+
recorded process group (Windows: verified PID tree). It retains disposable files
|
|
6754
|
+
if ownership verification fails and reports the failure in evidence. Do not add
|
|
6755
|
+
process-name or port-based kills to a spec.
|
|
6756
|
+
|
|
6595
6757
|
|
|
6596
6758
|
## test-fakes `@warlock.js/core/test-fakes/SKILL.md`
|
|
6597
6759
|
|
|
@@ -8229,48 +8391,40 @@ The CLI preserves incremental state and changed-file filtering. Development
|
|
|
8229
8391
|
health checks keep one native compiler session and update its snapshots. Syntax
|
|
8230
8392
|
analysis uses OXC. `warlock upgrade` still parses/transforms with ts-morph's own
|
|
8231
8393
|
bundled TypeScript, without using it as the app's compiler. New scaffolds default
|
|
8232
|
-
to Oxlint/Oxfmt (`--lint=oxc`)
|
|
8233
|
-
|
|
8234
|
-
and supports `>=4.8.4 <6.1.0`. Keep ESLint apps on 6.0.3 until switching tools:
|
|
8235
|
-
|
|
8236
|
-
```bash
|
|
8237
|
-
npm install --save-dev --save-exact typescript@6.0.3
|
|
8238
|
-
npx tsc --noEmit
|
|
8239
|
-
```
|
|
8240
|
-
|
|
8241
|
-
The same tsconfig cleanups work with TS6. Starting in 5.33, ESLint mode prints
|
|
8242
|
-
a deprecation warning naming removal in 5.34.0 and the Oxc migration command.
|
|
8394
|
+
to Oxlint/Oxfmt (`--lint=oxc`) with TypeScript 7.0.2. ESLint support was
|
|
8395
|
+
removed in 5.34.0; migrate legacy apps using the steps below.
|
|
8243
8396
|
|
|
8244
8397
|
## 5.32 to 5.33
|
|
8245
8398
|
|
|
8246
|
-
|
|
8247
|
-
in `warlock check` are disabled by default. Oxlint/Oxfmt replace ESLint/Prettier
|
|
8248
|
-
as the default toolchain. Legacy support is deprecated now and removed in
|
|
8249
|
-
5.34.0. Temporary opt-ins are `devServer.healthCheckers: { eslint: true }`,
|
|
8250
|
-
`warlock check --lint eslint`, and `create-warlock --lint=eslint`; each warns
|
|
8251
|
-
about removal and migration. The legacy scaffold stays on TypeScript 6.0.3;
|
|
8252
|
-
Oxc apps use TypeScript 7.0.2.
|
|
8253
|
-
|
|
8254
|
-
ESLint + Prettier are deprecated in 5.33.0 and will be removed in **5.34.0**.
|
|
8255
|
-
New apps should use `--lint=oxc`. To migrate an existing app, install the new
|
|
8256
|
-
core release and `ts-morph`, then run:
|
|
8399
|
+
The original `oxc-toolchain` codemod remains available:
|
|
8257
8400
|
|
|
8258
8401
|
```bash
|
|
8259
8402
|
npx warlock upgrade --from 5.32 --to 5.33.0 --dry-run
|
|
8260
8403
|
npx warlock upgrade --from 5.32 --to 5.33.0
|
|
8404
|
+
```
|
|
8405
|
+
|
|
8406
|
+
## 5.33 to 5.34 toolchain removal
|
|
8407
|
+
|
|
8408
|
+
**BREAKING:** ESLint and Prettier support was removed in **5.34.0**. Oxlint/Oxfmt is the only
|
|
8409
|
+
supported toolchain. `--lint eslint` and `healthCheckers.eslint` are removed.
|
|
8410
|
+
Install the new core release and `ts-morph`, then migrate an existing app:
|
|
8411
|
+
|
|
8412
|
+
```bash
|
|
8413
|
+
npm install --save-dev ts-morph
|
|
8414
|
+
npx warlock upgrade --from 5.33 --to 5.34.0 --dry-run
|
|
8415
|
+
npx warlock upgrade --from 5.33 --to 5.34.0
|
|
8261
8416
|
npm install
|
|
8262
8417
|
npm run format
|
|
8263
8418
|
npm run lint:check
|
|
8264
8419
|
npx warlock check
|
|
8265
8420
|
```
|
|
8266
8421
|
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
without writing files.
|
|
8422
|
+
The `oxc-toolchain-removal` step reapplies the preserved 5.33 `oxc-toolchain`
|
|
8423
|
+
migration when legacy configs, scripts or dependencies remain. Apps upgrading
|
|
8424
|
+
from 5.32 can still use `npx warlock upgrade --from 5.32 --to 5.33.0` first.
|
|
8425
|
+
It replaces standard scripts/dependencies, pins TypeScript 7.0.2, updates generated
|
|
8426
|
+
editor settings, removes `healthCheckers.eslint` and selects Oxlint. A generated
|
|
8427
|
+
`.prettierignore` becomes `.oxfmtignore`; Oxfmt scripts read it explicitly.
|
|
8274
8428
|
|
|
8275
8429
|
The `oxc-toolchain` codemod also updates generated VS Code settings and literal
|
|
8276
8430
|
ESLint/Oxlint health-check switches. Custom editor settings, checker arrays,
|
|
@@ -8278,6 +8432,55 @@ computed options and nonstandard scripts require review. Oxc diagnostics keep
|
|
|
8278
8432
|
framework conventions in `warlock check`. Re-run the migration after addressing
|
|
8279
8433
|
manual findings if needed; an app with only Oxc tooling is a no-op for this codemod.
|
|
8280
8434
|
|
|
8435
|
+
## 5.33 to 5.34 plain object validation
|
|
8436
|
+
|
|
8437
|
+
**BREAKING:** Seal `v.object()` rejects arrays, dates, maps, sets, class instances
|
|
8438
|
+
and objects with custom prototypes, including under `.allowUnknown()` and
|
|
8439
|
+
`.stripUnknown()`. Plain and null-prototype dictionaries remain accepted. There
|
|
8440
|
+
is no permissive opt-in: choose an array/instance validator or construct a plain
|
|
8441
|
+
DTO explicitly before validation.
|
|
8442
|
+
|
|
8443
|
+
```ts
|
|
8444
|
+
import { v } from "@warlock.js/seal";
|
|
8445
|
+
|
|
8446
|
+
class User {
|
|
8447
|
+
name = "Ada";
|
|
8448
|
+
}
|
|
8449
|
+
const instance = new User();
|
|
8450
|
+
const user = v.object({ name: v.string() });
|
|
8451
|
+
await v.validate(user, { name: instance.name });
|
|
8452
|
+
const names = v.array(v.string());
|
|
8453
|
+
await v.validate(names, ["Ada"]);
|
|
8454
|
+
```
|
|
8455
|
+
|
|
8456
|
+
`v.record(valueValidator)` remains supported. To validate dictionary keys, use
|
|
8457
|
+
`v.record(keyValidator, valueValidator)`; malformed arguments now fail while
|
|
8458
|
+
defining the schema. Literal-key records infer partial dictionaries because
|
|
8459
|
+
only present keys are checked.
|
|
8460
|
+
Literal custom rules are translated without executing the config. Per-folder
|
|
8461
|
+
`no-restricted-imports` and `no-restricted-exports` become Oxlint overrides with
|
|
8462
|
+
file/exclusion patterns. Supported `@typescript-eslint/*` rules become native
|
|
8463
|
+
`typescript/*` rules (or native base rules). Options are checked against the
|
|
8464
|
+
pinned Oxlint 1.88.0 schema. Type-aware equivalents enable `options.typeAware`
|
|
8465
|
+
and add `oxlint-tsgolint@7.0.2004` to the app's dev dependencies.
|
|
8466
|
+
`unused-imports/no-unused-imports` uses `no-unused-vars` with safe import fixes;
|
|
8467
|
+
Oxlint shares the severity for imports and variables, so differing active
|
|
8468
|
+
severities are reported for review.
|
|
8469
|
+
|
|
8470
|
+
Only unsupported rules/options, computed or imported settings, selectors such
|
|
8471
|
+
as `no-restricted-syntax`, and conflicting existing Oxc rules need manual review.
|
|
8472
|
+
Each finding names its source `file:line`, rule and affected file patterns.
|
|
8473
|
+
Fully ported lint configs are removed; configs with findings remain for reference
|
|
8474
|
+
until those findings are addressed. Existing Oxc rules are kept on conflict.
|
|
8475
|
+
`--dry-run --json` reports the same plan without writes. Customized formatting,
|
|
8476
|
+
editor settings and nonstandard scripts can also require review.
|
|
8477
|
+
|
|
8478
|
+
**Upgrading:** new and migrated template configs enable
|
|
8479
|
+
`"categories": { "correctness": "error" }`. Address the additional diagnostics;
|
|
8480
|
+
existing Oxc configs retain their categories. A real lockfile beside a workspace
|
|
8481
|
+
marker determines the installer: `package-lock.json` plus `pnpm-workspace.yaml`
|
|
8482
|
+
without `pnpm-lock.yaml` now produces `npm install`.
|
|
8483
|
+
|
|
8281
8484
|
|
|
8282
8485
|
## upload-file `@warlock.js/core/upload-file/SKILL.md`
|
|
8283
8486
|
|
|
@@ -10970,7 +11173,7 @@ const { messages } = await watchBoard({ agent: "implementer", timeoutMs: 30 * 60
|
|
|
10970
11173
|
|
|
10971
11174
|
---
|
|
10972
11175
|
name: warlock-check
|
|
10973
|
-
description: 'Verify a change with one command: `warlock check [--changed] [--json]` runs an incremental typecheck, the app''s
|
|
11176
|
+
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.'
|
|
10974
11177
|
---
|
|
10975
11178
|
|
|
10976
11179
|
# Warlock — `warlock check`, `typecheck`, `explain`
|
|
@@ -11090,10 +11293,10 @@ const types = runTypecheck({ files: ["src/app/posts/services/publish.service.ts"
|
|
|
11090
11293
|
## Gotchas
|
|
11091
11294
|
|
|
11092
11295
|
- `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`.
|
|
11093
|
-
- Lint defaults to Oxlint (an app-root config + the app-installed package). No Oxlint config skips lint. A missing package reports `WL8002`. ESLint
|
|
11296
|
+
- 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`.
|
|
11094
11297
|
- Tests use the app's own vitest (`vitest run`, or `vitest related <files> --run` with `--changed`). Test files without vitest installed → `WL8002`.
|
|
11095
11298
|
- The typecheck runs in a child `warlock typecheck` process; running out of memory is reported as `WL8007` instead of ending the run.
|
|
11096
|
-
- The convention checks are the framework's own and run the same with
|
|
11299
|
+
- 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).
|
|
11097
11300
|
|
|
11098
11301
|
## See also
|
|
11099
11302
|
|
|
@@ -11541,9 +11744,8 @@ A `⚠ routes: 0 routes registered` line is the tell that a route module threw o
|
|
|
11541
11744
|
|
|
11542
11745
|
`warlock doctor` checks application wiring and HTTP health probes. Use
|
|
11543
11746
|
`npx warlock check` for source lint diagnostics and `npm run format:check` for
|
|
11544
|
-
formatting.
|
|
11545
|
-
`
|
|
11546
|
-
background checks. ESLint/Prettier are deprecated and removed in 5.34.0.
|
|
11747
|
+
formatting. Oxlint/Oxfmt are the only supported tools in 5.34.0. Use the
|
|
11748
|
+
`oxc-toolchain-removal` upgrade step to migrate remaining legacy configs.
|
|
11547
11749
|
Migrate with `npx warlock upgrade --from 5.32 --to 5.33.0` (preview with `--dry-run`).
|
|
11548
11750
|
|
|
11549
11751
|
|
package/llms.txt
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
- [send-response](@warlock.js/core/send-response/SKILL.md): Send HTTP responses via @warlock.js/core's Response helpers — success/error variants, status helpers, redirects, files, streams, and SSE. Picking the right helper carries the HTTP semantic without manual status codes. Triggers: `response.success`, `response.successCreate`, `response.notFound`, `response.forbidden`, `response.badRequest`, `response.sendFile`, `response.stream`, `response.sse`, `response.replay`, `retainEvents`, `retainChunks`, `backpressure`, `@warlock.js/core/errors`, `ResourceNotFoundError`, `ForbiddenError`, `request.cookie`, `request.hasCookie`, `CookieJarUnavailableError`; "return a 201 from a controller", "send a file", "stream Server-Sent Events", "throw HTTP-shaped errors from services"; typical import `import type { RequestHandler, Response } from "@warlock.js/core"`. Skip: controller shape — the `create-controller` topic; route registration — the `register-route` topic; competing patterns: hand-rolled status codes via `reply.code(404).send(...)`, raw Fastify reply.
|
|
33
33
|
- [store-file](@warlock.js/core/store-file/SKILL.md): Read/write/delete files via the `storage` singleton — disks, drivers (local/S3/R2/DO Spaces), `storage.use(name)`, `StorageFile` handles, presigned URLs. Triggers: `storage.put`, `storage.get`, `storage.use`, `StorageFile`, `storageConfigurations`, `getPresignedUrl`, `getPresignedUploadUrl`; "save an uploaded file", "switch between local and S3", "generate a presigned URL", "read file metadata"; typical import `import { storage } from "@warlock.js/core"`. Skip: multipart parsing + image chain — the `upload-file` topic; image transforms — the `process-image` topic; storage config shape — the `configure-app` topic; competing libs `@aws-sdk/client-s3`, `multer`, `formidable`.
|
|
34
34
|
- [store-secrets](@warlock.js/core/store-secrets/SKILL.md): Store app credentials with secrets.get/set/remove/has and environmentName; lazy optional OS keychain, read-only scoped environment variables, encrypted file fallback, typed SecretStoreError and memory-backed secretsFake. Use for provider keys and OAuth credentials the app must read back. Skip user passwords (hash-password) and encrypted database columns (encrypt-data).
|
|
35
|
+
- [test-browser](@warlock.js/core/test-browser/SKILL.md): 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.
|
|
35
36
|
- [test-fakes](@warlock.js/core/test-fakes/SKILL.md): The test fakes Warlock installs by default in the test environment — `mailFake`, `queueFake`, `cacheFake`, `storageFake`, `clockFake`, `idsFake`, `secretsFake` — and their assertions (`assertSent`, `assertPushed`, `assertHas`, `assertExists`, `travel`), plus how to opt out (`tests.fakes`, `setupTest({ fakes })`). Triggers: `mailFake`, `queueFake`, `cacheFake`, `storageFake`, `clockFake`, `idsFake`, `secretsFake`, `installTestFakes`, `restoreTestFakes`, `tests.fakes`, `FakeAssertionError`, `clock.now`, `ids.uuid`, `setDispatchInterceptor`; "assert an email was sent", "assert a job was dispatched", "freeze time in a test", "deterministic ids", "tests without Redis", "keep the real cache driver in tests". Typical import `import { mailFake, queueFake } from "@warlock.js/core/tests"`. Skip: HTTP request helpers — the `test-http` topic; fixtures — the `model-factories` topic.
|
|
36
37
|
- [test-http](@warlock.js/core/test-http/SKILL.md): Integration tests against a real HTTP server — `startHttpTestServer()` boots one shared server in globalSetup, then `testGet` / `testPost` / `expectJson` make typed requests against it. Triggers: `startHttpTestServer`, `startHttpTestServer({ port })`, `startHttpTestServer({ port: 0 })`, `stopHttpTestServer`, `createTestHttpServer`, `TestHttpServer`, `createTestRequestClient`, `snapshotResponse`, `actingAs`, `AuthenticatedTestClient`, `testGet`, `testPost`, `testPut`, `testPatch`, `testDelete`, `expectJson`, `getTestServerUrl`, `testRequest`, `PortInUseError`, `assertPortIsAvailable`, `isPortAvailable`; "integration-test a controller", "end-to-end HTTP test", "globalSetup HTTP server", "assert status and body shape", "test server port already in use", "EADDRINUSE while running tests", "run tests while the dev server is up", "ephemeral test port", "test with the real Fastify plugins", "assert mail sent by a request", "response snapshot"; typical import `import { testGet, testPost, expectJson } from "@warlock.js/core/tests"`. Skip: pure unit tests — the `test-service` topic; controller shape — the `create-controller` topic; competing libs `supertest`, `light-my-request`, `nock`.
|
|
37
38
|
- [test-service](@warlock.js/core/test-service/SKILL.md): Pure unit tests against services, repositories, models, and use-cases — `setupTest({ connectors })` bootstraps the framework with its own DB/cache connections so you can call your code directly, and `teardownTest()` closes it. Triggers: `setupTest`, `teardownTest`, `setupTest({ fakes })`, `tests.fakes`, `src/test-setup.ts`, `tests.connectors`, `tests.setupTimeout`, `Application.setEnvironment`, `clock`, `ids`, `warlock test --changed`; "unit-test a service", "test a repository query", "vitest setupFiles", "skip connectors for pure-logic tests", "run only the tests my change affects", "deterministic time in a test"; typical import `import { setupTest, teardownTest } from "@warlock.js/core/tests"`. Skip: HTTP integration — the `test-http` topic; warlock add test scaffold — the `write-cli-command` topic; competing tooling: jest direct, `supertest`, `nock`.
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
- [validate-input](@warlock.js/core/validate-input/SKILL.md): Author seal schemas, attach them to controllers via `controller.validation = { schema }`, infer types via `Infer<typeof schema>`, and layer DB-aware (`unique`/`exists`) and file validators on top. Triggers: `v.object`, `v.string`, `v.email`, `Infer`, `controller.validation`, `.unique`, `.exists`, `uniqueExceptCurrentId`, `request.validated`; "validate a request body", "attach a schema to a controller", "DB-aware unique rule", "infer schema types"; typical import `import { v, type Infer } from "@warlock.js/seal"`. Skip: schema authoring foundations — the `seal-basics` topic of the `warlock-js-seal` skill; controller wiring — the `create-controller` topic; file rules deep-dive — the `upload-file` topic; competing libs `zod`, `joi`, `yup`, `class-validator`.
|
|
48
49
|
- [warlock-agents-md](@warlock.js/core/warlock-agents-md/SKILL.md): Generate the app-specific section of AGENTS.md from the booted app with `warlock agents-md [--write] [--json]` — modules, a routes summary with unguarded writes flagged, models, the conventions `warlock check` enforces, the installed skills and the verify commands — between `<!-- warlock:generated:start -->` / `<!-- warlock:generated:end -->` markers so hand-written content is never touched; `warlock dev` refreshes it (opt out with `devServer.agentsMd: false`). Triggers: `warlock agents-md`, `AGENTS.md`, `warlock:generated:start`, `renderAgentsMdSection`, `writeAgentsMd`, `upsertGeneratedSection`, `listInstalledSkills`, `createAgentsMdRefresher`, `devServer.agentsMd`, `WL7501`; "give agents the app facts", "keep AGENTS.md up to date", "which skills apply to this app". Skip: the full machine-readable report — the `warlock-inspect` topic; verifying a change — the `warlock-check` topic.
|
|
49
50
|
- [warlock-board](@warlock.js/core/warlock-board/SKILL.md): Coordinate two coding agents (an implementer and a reviewer) through `warlock board`: work items with a review state machine (todo, in-progress, ready-for-review, changes-requested, approved, blocked), append-only numbered messages per recipient in the git-ignored `.warlock/board/`, `VERDICT: APPROVED` / `VERDICT: CHANGES REQUESTED` lines that move the item, and a blocking `watch` with a timeout; `--json` on every action. Triggers: `warlock board`, `board init`, `board add`, `board status`, `board send`, `board watch`, `--verdict`, `WARLOCK_AGENT`, `.warlock/board`, `to-reviewer/`, `initBoard`, `addBoardItem`, `moveBoardItem`, `sendBoardMessage`, `watchBoard`, `readBoardStatus`, `WL7401`, `WL7402`, `WL7403`, `WL7404`; "hand this to the reviewer agent", "wait for the review", "two agents working together", "request changes", "approve the item". Skip: verifying the code itself — the `warlock-check` topic; app facts — the `warlock-inspect` topic.
|
|
50
|
-
- [warlock-check](@warlock.js/core/warlock-check/SKILL.md): Verify a change with one command: `warlock check [--changed] [--json]` runs an incremental typecheck, the app's
|
|
51
|
+
- [warlock-check](@warlock.js/core/warlock-check/SKILL.md): 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.
|
|
51
52
|
- [warlock-conventions](@warlock.js/core/warlock-conventions/SKILL.md): Framework-wide invariants for projects built on @warlock.js/core — module layout, canonical imports, layered flow, file naming, and the non-negotiable rules every other warlock skill assumes. Triggers: `src/app/<module>`, `routes.ts`, `main.ts`, `Request<TSchema>`, `RequestHandler`, `GuardedRequestHandler`, `app/<module>/...`; "where do files go in this project", "canonical Warlock imports", "module layout rules", "controller-service-repository layering"; typical import `import { router, type RequestHandler } from "@warlock.js/core"`. Skip: scaffold a new module — the `create-module` topic; route shape — the `register-route` topic; controller shape — the `create-controller` topic; competing patterns: `express` ad-hoc layouts, `@nestjs/common` decorator-driven structure.
|
|
52
53
|
- [warlock-doctor](@warlock.js/core/warlock-doctor/SKILL.md): Run `warlock doctor` — a read-only diagnostics command that checks routes / config / connectors / optional-peers / health endpoints / release hygiene and prints a pass/warn/fail report, exiting non-zero on any failure. Add your own probe with the `DoctorCheck` contract and `runChecks` / `formatReportLines`. Triggers: `warlock doctor`, `warlock doctor --json`, `toDoctorJson`, `WL1001`, `doctorCommand`, `DoctorCheck`, `CheckResult`, `CheckStatus`, `DoctorReport`, `runChecks`, `formatReportLines`, `printReport`, `defaultDoctorChecks`; "diagnose my app", "preflight / preflight check", "is the app healthy", "why are there 0 routes", "pre-release sanity check", "CI smoke check"; run as `npx warlock doctor`. Skip: the live `/health` + `/ready` HTTP probes — the `health-checks` topic; authoring a general CLI command — the `write-cli-command` topic; releasing the package — `releasing-warlock-monorepo`; competing tools `npm doctor`, `nest info`, hand-rolled preflight scripts.
|
|
53
54
|
- [warlock-inspect](@warlock.js/core/warlock-inspect/SKILL.md): Ask the app instead of grepping it: `warlock inspect --json` prints the facts of the booted app — routes (middleware chain, auth guard, CSRF, rate limit, logging, request/response JSON Schema), models (table, columns, relations, resource), resources, config keys and types, event listeners, pages (layouts, loaders, actions), queue jobs, scheduled tasks and installed @warlock.js versions — as a versioned report (`schemaVersion: 1`) with a published JSON Schema; `inspectApp()` returns the same object. Triggers: `warlock inspect`, `--section`, `inspect_routes`, `inspectApp`, `bootForInspect`, `InspectReport`, `INSPECT_REPORT_JSON_SCHEMA`, `inspect-report.schema.json`, `@warlock.js/core/tooling`; "which routes are unguarded", "what does this app expose", "what models and columns exist", "which config keys are set", "list event listeners", "app facts as JSON for an agent". Skip: a route table for humans — the `warlock-routes` topic; health diagnostics — the `warlock-doctor` topic; verifying a change — the `warlock-check` topic; an OpenAPI file — the `generate-openapi` topic.
|
package/package.json
CHANGED
|
@@ -25,18 +25,17 @@
|
|
|
25
25
|
"@mongez/slug": "^1.0.7",
|
|
26
26
|
"@mongez/supportive-is": "^3.0.0",
|
|
27
27
|
"@mongez/time-wizard": "^1.0.6",
|
|
28
|
-
"@warlock.js/cache": "5.
|
|
29
|
-
"@warlock.js/cascade": "5.
|
|
30
|
-
"@warlock.js/context": "5.
|
|
31
|
-
"@warlock.js/fs": "5.
|
|
32
|
-
"@warlock.js/logger": "5.
|
|
33
|
-
"@warlock.js/seal": "5.
|
|
28
|
+
"@warlock.js/cache": "5.34.0",
|
|
29
|
+
"@warlock.js/cascade": "5.34.0",
|
|
30
|
+
"@warlock.js/context": "5.34.0",
|
|
31
|
+
"@warlock.js/fs": "5.34.0",
|
|
32
|
+
"@warlock.js/logger": "5.34.0",
|
|
33
|
+
"@warlock.js/seal": "5.34.0",
|
|
34
34
|
"bcryptjs": "^3.0.3",
|
|
35
35
|
"chokidar": "^5.0.0",
|
|
36
36
|
"dayjs": "^1.11.19",
|
|
37
37
|
"es-module-lexer": "^2.0.0",
|
|
38
38
|
"esbuild": "^0.28.2",
|
|
39
|
-
"eslint": "^9.18.0",
|
|
40
39
|
"fast-glob": "^3.3.3",
|
|
41
40
|
"fastify": "^5.12.5",
|
|
42
41
|
"find-my-way": "^9.9.0",
|
|
@@ -56,12 +55,12 @@
|
|
|
56
55
|
"@aws-sdk/lib-storage": "^3.955.0",
|
|
57
56
|
"@aws-sdk/s3-request-presigner": "^3.955.0",
|
|
58
57
|
"@react-email/render": "^2.0.5",
|
|
59
|
-
"@warlock.js/access": "5.
|
|
60
|
-
"@warlock.js/ai": "5.
|
|
61
|
-
"@warlock.js/ai-tools": "5.
|
|
62
|
-
"@warlock.js/devtools": "5.
|
|
63
|
-
"@warlock.js/herald": "5.
|
|
64
|
-
"@warlock.js/notifications": "5.
|
|
58
|
+
"@warlock.js/access": "5.34.0",
|
|
59
|
+
"@warlock.js/ai": "5.34.0",
|
|
60
|
+
"@warlock.js/ai-tools": "5.34.0",
|
|
61
|
+
"@warlock.js/devtools": "5.34.0",
|
|
62
|
+
"@warlock.js/herald": "5.34.0",
|
|
63
|
+
"@warlock.js/notifications": "5.34.0",
|
|
65
64
|
"nodemailer": "^8.0.5",
|
|
66
65
|
"react": "^19.2.3",
|
|
67
66
|
"react-dom": "^19.2.3",
|
|
@@ -146,7 +145,7 @@
|
|
|
146
145
|
"engines": {
|
|
147
146
|
"node": ">=22.15"
|
|
148
147
|
},
|
|
149
|
-
"version": "5.
|
|
148
|
+
"version": "5.34.0",
|
|
150
149
|
"type": "module",
|
|
151
150
|
"main": "./esm/index.mjs",
|
|
152
151
|
"module": "./esm/index.mjs",
|
|
@@ -170,6 +169,12 @@
|
|
|
170
169
|
"default": "./esm/tests/index.mjs"
|
|
171
170
|
}
|
|
172
171
|
},
|
|
172
|
+
"./e2e": {
|
|
173
|
+
"import": {
|
|
174
|
+
"types": "./esm/e2e/index.d.mts",
|
|
175
|
+
"default": "./esm/e2e/index.mjs"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
173
178
|
"./vite": {
|
|
174
179
|
"import": {
|
|
175
180
|
"types": "./esm/vite/index.d.mts",
|
|
@@ -206,12 +211,6 @@
|
|
|
206
211
|
"default": "./esm/production/route-registration-child.mjs"
|
|
207
212
|
}
|
|
208
213
|
},
|
|
209
|
-
"./dev-server/health-checker/workers/eslint-health.worker": {
|
|
210
|
-
"import": {
|
|
211
|
-
"types": "./esm/dev-server/health-checker/workers/eslint-health.worker.d.mts",
|
|
212
|
-
"default": "./esm/dev-server/health-checker/workers/eslint-health.worker.mjs"
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
214
|
"./dev-server/health-checker/workers/oxlint-health.worker": {
|
|
216
215
|
"import": {
|
|
217
216
|
"types": "./esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts",
|
|
@@ -191,7 +191,7 @@ await warmupProductCache();
|
|
|
191
191
|
|
|
192
192
|
## Verify generated imports
|
|
193
193
|
|
|
194
|
-
Generated web starter files match the scaffold’s
|
|
195
|
-
|
|
194
|
+
Generated web starter files match the scaffold’s Oxfmt configuration and its
|
|
195
|
+
built-in import sorting.
|
|
196
196
|
After editing generated code, run `npm run format` and `npm run lint:check`.
|
|
197
197
|
Formatting retains unused imports; the linter reports them.
|
package/skills/run-app/SKILL.md
CHANGED
|
@@ -150,7 +150,7 @@ export default defineConfig({
|
|
|
150
150
|
|
|
151
151
|
- **`watch.include` / `watch.exclude`** — globs piped into the file watcher. Override when you have non-`.ts(x)` files driving reloads (e.g. SQL fixtures), or to exclude a generated folder.
|
|
152
152
|
- **`generateTypings`** — turn off if you're committing generated typings and don't want them rewritten on every boot. The `--skip-typings` flag is the per-run version.
|
|
153
|
-
- **`healthCheckers`** — built-in switches (`{ typescript?,
|
|
153
|
+
- **`healthCheckers`** — built-in switches (`{ typescript?, oxlint? }`), custom checker arrays, or `false`. TypeScript and installed/configured Oxlint run by default. `--skip-health` disables checks for one run. ESLint support was removed in 5.34.0; use `npx warlock upgrade --from 5.33 --to 5.34.0` to remove stale options.
|
|
154
154
|
- **`transpileCacheDebug`** — diagnostic only. Names `.warlock/transpile/*.js` files `<slug>.<hash>.js` and appends `// @source <path>` markers so you can eyeball which cache entry came from which source. Leave off in normal use.
|
|
155
155
|
- **`checkForUpdates`** — on `warlock dev` start, check npm for a newer `@warlock.js/core` and print a one-line notice if one exists. Best-effort and non-blocking; auto-skipped in CI and non-TTY shells. In an interactive terminal the notice arms a **`u` shortcut** that updates every `@warlock.js/*` package, installs, and restarts the server; elsewhere it prints `npx warlock update` instead. The registry answer is cached for 24h in `.warlock/update-check.json`, so a day of restarts costs one lookup. See the `update-packages` topic.
|
|
156
156
|
- **`restartOnConfigChange`** — restart the dev server when `warlock.config.ts` or any `.env*` changes (default `true`). Set `false` to get a warning instead and restart by hand. Neither file can be hot-reloaded, so without a restart the running services keep the old values.
|
|
@@ -173,12 +173,12 @@ import { defineConfig } from "@warlock.js/core";
|
|
|
173
173
|
|
|
174
174
|
export default defineConfig({
|
|
175
175
|
devServer: {
|
|
176
|
-
healthCheckers: { typescript: true,
|
|
176
|
+
healthCheckers: { typescript: true, oxlint: true },
|
|
177
177
|
},
|
|
178
178
|
});
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
Omit
|
|
181
|
+
Omit switches to run TypeScript and installed/configured Oxlint. Set `oxlint: false` to disable only Oxlint. A custom checker array replaces the built-in list. JSON/JSONC configs work on Node 22.15; current Oxlint TypeScript configs require Node 22.18 or newer.
|
|
182
182
|
|
|
183
183
|
## `warlock build` — production bundle
|
|
184
184
|
|
|
@@ -97,6 +97,45 @@ Options also allow a `directory` and `encryptionKey` (string or lazy callback);
|
|
|
97
97
|
|
|
98
98
|
## Error and logging contract
|
|
99
99
|
|
|
100
|
-
`SecretStoreError.code` is `INVALID_NAME`, `INVALID_VALUE`, `INVALID_NAMESPACE`, `READ_ONLY`, `KEY_REQUIRED`, `UNAVAILABLE`, `UNSAFE_FILE` or `CORRUPT_FILE`. Errors never include names, values, paths or vendor causes. `KEY_REQUIRED` means provision/fix the app encryption key; `CORRUPT_FILE` means wrong key, invalid format or failed authentication. Never replace an unreadable store with an empty one.
|
|
100
|
+
`SecretStoreError.code` is `INVALID_DRIVER`, `MEMORY_IN_PRODUCTION`, `INVALID_NAME`, `INVALID_VALUE`, `INVALID_NAMESPACE`, `READ_ONLY`, `KEY_REQUIRED`, `UNAVAILABLE`, `UNSAFE_FILE` or `CORRUPT_FILE`. Errors never include names, values, paths or vendor causes. `KEY_REQUIRED` means provision/fix the app encryption key; `CORRUPT_FILE` means wrong key, invalid format or failed authentication. Never replace an unreadable store with an empty one.
|
|
101
101
|
|
|
102
102
|
The store never logs credentials. It registers encountered names and literal values with `@warlock.js/logger` for process-lifetime masking, including old/removed/failed-write values, interpolated messages, Error text/causes, and channel error reports. Keys and exact values stay protected even with permissive custom censors. Registration retains values in memory. It cannot mask direct console/third-party logging, earlier logs, transformed/encoded values, or credentials never encountered by the store. Keep secrets out of logs even with masking enabled. Fake assertion errors do not print values.
|
|
103
|
+
|
|
104
|
+
## Built-app tests with the memory driver
|
|
105
|
+
|
|
106
|
+
Run the built server with `SECRETS_DRIVER=memory`, or select the driver in
|
|
107
|
+
`src/config/secrets.ts`. Explicit config takes precedence over the environment;
|
|
108
|
+
`"auto"` (the default) keeps keychain/environment/file behavior. Unknown driver
|
|
109
|
+
names fail with `SecretStoreError.code === "INVALID_DRIVER"`.
|
|
110
|
+
|
|
111
|
+
```ts title="src/config/secrets.ts"
|
|
112
|
+
import type { SecretsConfigurations } from "@warlock.js/core";
|
|
113
|
+
|
|
114
|
+
export default {
|
|
115
|
+
namespace: "browser-test-server",
|
|
116
|
+
driver: "memory",
|
|
117
|
+
allowMemoryInProduction: true,
|
|
118
|
+
} satisfies SecretsConfigurations;
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`allowMemoryInProduction: true` is required only when the test server runs with
|
|
122
|
+
`NODE_ENV=production`. Without it, memory selection fails closed with
|
|
123
|
+
`MEMORY_IN_PRODUCTION`; a built bundle does not bypass this check. Set this
|
|
124
|
+
option explicitly in the test deployment configuration. `SecretStore` accepts
|
|
125
|
+
the same `driver` and `allowMemoryInProduction` options for standalone stores.
|
|
126
|
+
|
|
127
|
+
The selected memory driver bypasses keychain, scoped environment secrets and
|
|
128
|
+
files, and still registers values for log masking. Values are isolated by app
|
|
129
|
+
namespace, lost on process exit, and never shared across workers or with a
|
|
130
|
+
separate browser-test process. Seed fixtures through application startup or a
|
|
131
|
+
test-only endpoint in the server process using the normal `secrets.set()` API:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { secrets } from "@warlock.js/core";
|
|
135
|
+
|
|
136
|
+
await secrets.set("vendor-token", "browser-test-credential");
|
|
137
|
+
const token = await secrets.get("vendor-token");
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The normal test harness still installs `secretsFake`; explicit `backend`
|
|
141
|
+
instances and that fake continue to bypass configured backend selection.
|