Skip to content

Commit 8b8a0ed

Browse files
authored
feat!: bump devframe to v0.4.1, migrate diagnostic handles to callable API (#358)
1 parent 9789491 commit 8b8a0ed

19 files changed

Lines changed: 191 additions & 287 deletions

File tree

AGENTS.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,13 @@ Codes are sequential 4-digit numbers per prefix (e.g. `DTK0033`, `RDDT0003`). Ch
125125
import { diagnostics } from './diagnostics'
126126

127127
// For thrown errors — always prefix with `throw` for TypeScript control flow:
128-
throw diagnostics.DTK0033.throw({ name })
128+
throw diagnostics.DTK0033({ name })
129129

130-
// For reported (non-thrown) diagnostics:
131-
diagnostics.DTK0033.report({ name })
132-
diagnostics.DTK0033.report({ name, cause: error }) // attach cause via params
130+
// For reported (non-thrown) diagnostics. The default console method is `warn`;
131+
// override with the 2nd-arg reporter options when needed:
132+
diagnostics.DTK0033({ name }) // console.warn
133+
diagnostics.DTK0033({ name }, { method: 'error' }) // console.error
134+
diagnostics.DTK0033({ name, cause: error }) // attach cause via params
133135
```
134136

135137
3. **Create a docs page** at `docs/errors/DTK0033.md`:

MIGRATION.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,20 @@ These types are no longer re-exported from `@vitejs/devtools-kit`. Import them f
5050
```
5151

5252
The `@vitejs/devtools-kit/utils/when` subpath remains and re-exports these types alongside `evaluateWhen` and `resolveContextValue`.
53+
54+
#### Diagnostic handles are callable
55+
56+
`nostics` 0.2 (pulled in via devframe 0.4) drops the `.report()` / `.throw()` methods on diagnostic handles. Each handle is now a callable that builds and emits a diagnostic; prefix with `throw` to raise.
57+
58+
```diff
59+
- throw ctx.diagnostics.logger.MYP0001.throw({ name })
60+
+ throw ctx.diagnostics.logger.MYP0001({ name })
61+
62+
- ctx.diagnostics.logger.MYP0002.report()
63+
+ ctx.diagnostics.logger.MYP0002()
64+
65+
- ctx.diagnostics.logger.MYP0002.report({ name }, { method: 'error' })
66+
+ ctx.diagnostics.logger.MYP0002({ name }, { method: 'error' })
67+
```
68+
69+
The payload shape (including `cause`) and the optional reporter-options second argument are unchanged. Apply the same rewrite to typed handles returned from `ctx.diagnostics.defineDiagnostics()`.

docs/kit/diagnostics.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
interface DevToolsDiagnosticsHost {
1414
/**
1515
* Proxy-backed lookup of every registered code by name. Each entry is a
16-
* `nostics` handle with `.report()` and `.throw()` methods.
16+
* `nostics` `DiagnosticHandle` — a callable that builds a diagnostic and
17+
* routes it through registered reporters; prefix with `throw` to raise.
1718
*/
1819
readonly logger: Record<string, any>
1920

@@ -56,7 +57,7 @@ export function MyPlugin(): PluginWithDevTools {
5657
ctx.diagnostics.register(diagnostics)
5758

5859
// Emit codes through the shared lookup:
59-
ctx.diagnostics.logger.MYP0002.report()
60+
ctx.diagnostics.logger.MYP0002()
6061
},
6162
},
6263
}
@@ -80,23 +81,26 @@ Each definition supports `why` (string or function returning a string) and an op
8081

8182
## Emit a diagnostic
8283

83-
Each registered code is reachable as a property on `ctx.diagnostics.logger`. Every handle exposes `.throw(params)` and `.report(params)`.
84+
Each registered code is reachable as a property on `ctx.diagnostics.logger`. Every handle is a callable — invoke it to report (returns the `Diagnostic`), or prefix with `throw` to raise.
8485

8586
```ts
8687
// Throw — control flow stops here
87-
throw ctx.diagnostics.logger.MYP0001.throw({ name: 'foo' })
88+
throw ctx.diagnostics.logger.MYP0001({ name: 'foo' })
8889

89-
// Report without throwing (goes through the host's reporter)
90-
ctx.diagnostics.logger.MYP0002.report()
90+
// Report without throwing (default console method: `warn`)
91+
ctx.diagnostics.logger.MYP0002()
92+
93+
// Override the console method per call
94+
ctx.diagnostics.logger.MYP0002({}, { method: 'error' })
9195

9296
// Attach a `cause` via the params object
93-
ctx.diagnostics.logger.MYP0001.report({ name: 'foo', cause: error })
97+
ctx.diagnostics.logger.MYP0001({ name: 'foo', cause: error })
9498
```
9599

96-
`.throw()` is typed `never`. Prefix the call with `throw` so TypeScript narrows control flow correctly:
100+
The callable returns a `Diagnostic` (which extends `Error`). Prefix with `throw` so TypeScript narrows the lines after as unreachable:
97101

98102
```ts
99-
throw ctx.diagnostics.logger.MYP0001.throw({ name })
103+
throw ctx.diagnostics.logger.MYP0001({ name })
100104
```
101105

102106
## Typed handle reference
@@ -115,7 +119,7 @@ const myDiagnostics = ctx.diagnostics.defineDiagnostics({
115119
ctx.diagnostics.register(myDiagnostics)
116120

117121
// Use the typed handle directly at emit sites
118-
myDiagnostics.MYP0001.report({ name: 'foo' })
122+
myDiagnostics.MYP0001({ name: 'foo' })
119123
```
120124

121125
Both paths share the formatter and reporter defaults set by the host (ANSI console output).
@@ -135,7 +139,7 @@ Each page covers the message, cause, example, and fix; see any [DTK code page](/
135139

136140
## When to use what
137141

138-
- **`ctx.diagnostics`** — coded conditions worth looking up: misconfiguration, deprecations, validation failures, internal invariants. Always docs-backed. Often `.throw()`.
142+
- **`ctx.diagnostics`** — coded conditions worth looking up: misconfiguration, deprecations, validation failures, internal invariants. Always docs-backed. Often `throw`-prefixed.
139143
- **[`ctx.messages`](./messages)** — user-facing activity surfaces in the DevTools UI: progress indicators, audit results, "URL copied" toasts. Just a message and a level.
140144

141145
Diagnostics target tool authors and CI; messages target the human in front of the DevTools panel.

packages/core/src/node/cli-commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,5 @@ export async function build(options: BuildOptions) {
8989
outDir,
9090
})
9191

92-
diagnostics.DTK0010.report()
92+
diagnostics.DTK0010()
9393
}

packages/core/src/node/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export async function createDevToolsContext(
7878
await plugin.devtools?.setup?.(context)
7979
}
8080
catch (error) {
81-
throw diagnostics.DTK0014.throw({ name: plugin.name, cause: error })
81+
throw diagnostics.DTK0014({ name: plugin.name, cause: error })
8282
}
8383
}
8484

packages/core/src/node/rpc/internal/docks-on-launch.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ export const docksOnLaunch = defineRpcFunction({
1414

1515
const entry = context.docks.values().find(entry => entry.id === entryId)
1616
if (!entry) {
17-
throw diagnostics.DTK0030.throw({ id: entryId })
17+
throw diagnostics.DTK0030({ id: entryId })
1818
}
1919
if (entry.type !== 'launcher') {
20-
throw diagnostics.DTK0031.throw({ id: entryId })
20+
throw diagnostics.DTK0031({ id: entryId })
2121
}
2222
try {
2323
context.docks.update({
@@ -43,7 +43,7 @@ export const docksOnLaunch = defineRpcFunction({
4343
return result
4444
}
4545
catch (error) {
46-
diagnostics.DTK0032.report({ id: entryId, cause: error })
46+
diagnostics.DTK0032({ id: entryId, cause: error })
4747
context.docks.update({
4848
...entry,
4949
launcher: {

packages/core/src/node/rpc/public/open-in-editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const openInEditor = defineRpcFunction({
1515

1616
// Prevent escaping the workspace root
1717
if (rel.startsWith('..') || rel.includes('\0')) {
18-
throw diagnostics.DTK0028.throw()
18+
throw diagnostics.DTK0028()
1919
}
2020

2121
launchEditor(resolved)

packages/core/src/node/rpc/public/open-in-finder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const openInFinder = defineRpcFunction({
1515

1616
// Ensure the path stays within workspace root
1717
if (rel.startsWith('..') || rel.includes('\0')) {
18-
throw diagnostics.DTK0029.throw()
18+
throw diagnostics.DTK0029()
1919
}
2020

2121
await open(resolved)

packages/core/src/node/ws.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export async function createWsServer(options: CreateWsServerOptions) {
5050

5151
const isClientAuthDisabled = context.mode === 'build' || context.viteConfig.devtools?.config?.clientAuth === false || process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH === 'true'
5252
if (isClientAuthDisabled) {
53-
diagnostics.DTK0008.report()
53+
diagnostics.DTK0008()
5454
}
5555

5656
contextInternal.wsEndpoint = {
@@ -74,10 +74,10 @@ export async function createWsServer(options: CreateWsServerOptions) {
7474
{
7575
rpcOptions: {
7676
onFunctionError(error, name) {
77-
diagnostics.DTK0011.report({ name, cause: error })
77+
diagnostics.DTK0011({ name, cause: error })
7878
},
7979
onGeneralError(error) {
80-
diagnostics.DTK0012.report({ cause: error })
80+
diagnostics.DTK0012({ cause: error })
8181
},
8282
resolver(name, fn) {
8383
// eslint-disable-next-line ts/no-this-alias
@@ -86,7 +86,7 @@ export async function createWsServer(options: CreateWsServerOptions) {
8686
// Block unauthorized access to non-anonymous methods
8787
if (!name.startsWith(ANONYMOUS_SCOPE) && !rpc.$meta.isTrusted) {
8888
return () => {
89-
throw diagnostics.DTK0013.throw({ name, clientId: rpc.$meta.id })
89+
throw diagnostics.DTK0013({ name, clientId: rpc.$meta.id })
9090
}
9191
}
9292

0 commit comments

Comments
 (0)