diff --git a/packages/kit/src/client/connection.ts b/packages/kit/src/client/connection.ts index 85de75012..6546dc3cd 100644 --- a/packages/kit/src/client/connection.ts +++ b/packages/kit/src/client/connection.ts @@ -1,6 +1,23 @@ import type { DevframeRpcClient, DevframeRpcClientOptions } from '@devframes/hub/client' +import type { DevframeRpcClientFunctions } from '@devframes/hub/types' +import type { BirpcReturn } from 'devframe/rpc' +import type { DevToolsRpcServerFunctions } from '../types/rpc-augments' import { getDevframeRpcClient } from '@devframes/hub/client' +export type DevToolsRpcClientCall = BirpcReturn['$call'] +export type DevToolsRpcClientCallEvent = BirpcReturn['$callEvent'] +export type DevToolsRpcClientCallOptional = BirpcReturn['$callOptional'] +export type DevToolsRpcClientOptions = DevframeRpcClientOptions + +export interface DevToolsRpcClient extends Omit< + DevframeRpcClient, + 'call' | 'callEvent' | 'callOptional' +> { + call: DevToolsRpcClientCall + callEvent: DevToolsRpcClientCallEvent + callOptional: DevToolsRpcClientCallOptional +} + /** * The Vite DevTools flavour of devframe's {@link getDevframeRpcClient}. Kept as * a dedicated export for naming symmetry with the kit's other `DevTools*` @@ -17,10 +34,10 @@ import { getDevframeRpcClient } from '@devframes/hub/client' * devframe's native browser-prompt fallback for every kit-managed connection. */ export function getDevToolsRpcClient( - options: DevframeRpcClientOptions = {}, -): Promise { + options: DevToolsRpcClientOptions = {}, +): Promise { return getDevframeRpcClient({ ...options, simpleAuth: false, - }) + }) as Promise } diff --git a/packages/kit/src/client/index.ts b/packages/kit/src/client/index.ts index 420af4857..2de3d5110 100644 --- a/packages/kit/src/client/index.ts +++ b/packages/kit/src/client/index.ts @@ -7,12 +7,7 @@ export * from './remote' export { type DevframeClientRpcHost as DevToolsClientRpcHost, - type DevframeRpcClient as DevToolsRpcClient, - type DevframeRpcClientCall as DevToolsRpcClientCall, - type DevframeRpcClientCallEvent as DevToolsRpcClientCallEvent, - type DevframeRpcClientCallOptional as DevToolsRpcClientCallOptional, type DevframeRpcClientMode as DevToolsRpcClientMode, - type DevframeRpcClientOptions as DevToolsRpcClientOptions, type DevframeRpcContext as DevToolsRpcContext, type RpcStreamingClientHost, type StreamingSubscribeOptions, diff --git a/packages/kit/src/types/index.ts b/packages/kit/src/types/index.ts index 07098579f..89ab956eb 100644 --- a/packages/kit/src/types/index.ts +++ b/packages/kit/src/types/index.ts @@ -6,6 +6,7 @@ export * from './commands' export * from './docks' export * from './json-render' export * from './messages' +export * from './rpc-augments' export * from './settings' export * from './terminals' export * from './vite-augment' @@ -19,7 +20,6 @@ export type { DevframeHost as DevToolsHost, DevframeNodeRpcSession as DevToolsNodeRpcSession, DevframeRpcClientFunctions as DevToolsRpcClientFunctions, - DevframeRpcServerFunctions as DevToolsRpcServerFunctions, DevframeRpcSharedStates as DevToolsRpcSharedStates, DevframeViewHost as DevToolsViewHost, EventEmitter, diff --git a/packages/kit/src/types/rpc-augments.ts b/packages/kit/src/types/rpc-augments.ts new file mode 100644 index 000000000..8957ff1b2 --- /dev/null +++ b/packages/kit/src/types/rpc-augments.ts @@ -0,0 +1,8 @@ +import type { DevframeRpcServerFunctions } from '@devframes/hub/types' + +/** + * Server-side RPC functions exposed by Vite DevTools integrations. + * + * Extend this interface with module augmentation to type `rpc.call()`. + */ +export interface DevToolsRpcServerFunctions extends DevframeRpcServerFunctions {} diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts index c5032edc4..09587ea38 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts @@ -1,9 +1,24 @@ /** * Generated by tsnapi — public API snapshot of `@vitejs/devtools-kit/client` */ +// #region Interfaces +export interface DevToolsRpcClient extends Omit { + call: DevToolsRpcClientCall; + callEvent: DevToolsRpcClientCallEvent; + callOptional: DevToolsRpcClientCallOptional; +} +// #endregion + +// #region Types +export type DevToolsRpcClientCall = BirpcReturn['$call']; +export type DevToolsRpcClientCallEvent = BirpcReturn['$callEvent']; +export type DevToolsRpcClientCallOptional = BirpcReturn['$callOptional']; +export type DevToolsRpcClientOptions = DevframeRpcClientOptions; +// #endregion + // #region Functions export declare function getDevToolsClientContext(): DevToolsClientContext | undefined; -export declare function getDevToolsRpcClient(_?: DevframeRpcClientOptions): Promise; +export declare function getDevToolsRpcClient(_?: DevToolsRpcClientOptions): Promise; // #endregion // #region Variables @@ -25,12 +40,7 @@ export { DevToolsFrameNavHostMessage } export { DevToolsFrameNavHostPayload } export { DevToolsFrameNavListenTarget } export { DevToolsFrameTab } -export { DevToolsRpcClient } -export { DevToolsRpcClientCall } -export { DevToolsRpcClientCallEvent } -export { DevToolsRpcClientCallOptional } export { DevToolsRpcClientMode } -export { DevToolsRpcClientOptions } export { DevToolsRpcContext } export { DockClientScriptContext } export { DockClientType } diff --git a/test/fixtures/rpc-augmentation.ts b/test/fixtures/rpc-augmentation.ts new file mode 100644 index 000000000..d79797ee5 --- /dev/null +++ b/test/fixtures/rpc-augmentation.ts @@ -0,0 +1,20 @@ +import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client' +import '@vitejs/devtools-kit' + +declare module '@vitejs/devtools-kit' { + interface DevToolsRpcServerFunctions { + 'test:get-modules': (filter?: string) => Promise + } +} + +export async function testRpcAugmentation() { + const rpc = await getDevToolsRpcClient() + const modules = await rpc.call('test:get-modules', 'src/') + + modules satisfies string[] + + // @ts-expect-error Unknown RPC names remain rejected. + await rpc.call('test:unknown') + // @ts-expect-error Registered RPC arguments remain checked. + await rpc.call('test:get-modules', 42) +} diff --git a/test/rpc-augmentation.test.ts b/test/rpc-augmentation.test.ts new file mode 100644 index 000000000..289818bc3 --- /dev/null +++ b/test/rpc-augmentation.test.ts @@ -0,0 +1,32 @@ +import { resolve } from 'node:path' +import ts from 'typescript' +import { describe, expect, it } from 'vitest' + +describe('rpc module augmentation', () => { + it('types getDevToolsRpcClient calls through the kit registry', () => { + const root = resolve(import.meta.dirname, '..') + const fixture = resolve(import.meta.dirname, 'fixtures/rpc-augmentation.ts') + const program = ts.createProgram([fixture], { + baseUrl: root, + ignoreDeprecations: '6.0', + module: ts.ModuleKind.ESNext, + moduleResolution: ts.ModuleResolutionKind.Bundler, + noEmit: true, + paths: { + '@vitejs/devtools-kit': ['packages/kit/src/index.ts'], + '@vitejs/devtools-kit/client': ['packages/kit/src/client/index.ts'], + }, + skipLibCheck: true, + strict: true, + target: ts.ScriptTarget.ESNext, + }) + const diagnostics = ts.getPreEmitDiagnostics(program) + const output = ts.formatDiagnosticsWithColorAndContext(diagnostics, { + getCanonicalFileName: file => file, + getCurrentDirectory: () => root, + getNewLine: () => '\n', + }) + + expect(output).toBe('') + }) +})