diff --git a/docs/errors/DTK0013.md b/docs/errors/DTK0013.md index 7c9b08be9..9721d1d5a 100644 --- a/docs/errors/DTK0013.md +++ b/docs/errors/DTK0013.md @@ -40,14 +40,10 @@ Authorize the browser. When an untrusted client connects, the dev-server termina For automated setups (CI, shared machines), configure static trusted tokens instead — a client presenting one via the `devframe_auth_token` connection parameter is trusted without the interactive step: ```ts -import { DevTools } from '@vitejs/devtools' // vite.config.ts import { defineConfig } from 'vite' export default defineConfig({ - plugins: [ - DevTools(), - ], devtools: { enabled: true, clientAuthTokens: ['your-trusted-token'], diff --git a/docs/guide/index.md b/docs/guide/index.md index f2f2ab55c..de0610a3c 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -70,22 +70,17 @@ export default defineConfig({ ### Customize the embedded UI -Vite adds the embedded dock automatically during `vite dev`. To customize it, add the `DevTools()` plugin manually. The examples keep the automatic integration enabled only for build to avoid mounting the dock twice. +Vite adds the embedded dock automatically during `vite dev`. Configure its UI through the core `devtools` option. `embeddedVisibility` controls when the dock appears. The default `'normal'` shows it immediately. `'passive'` hides it until Shift + Alt + D ( D on macOS) and remembers when it has been revealed. `'hidden'` uses the same shortcut without remembering the choice. ```ts [vite.config.ts] twoslash -import { DevTools } from '@vitejs/devtools' import { defineConfig } from 'vite' export default defineConfig({ - plugins: [ - DevTools({ - embeddedVisibility: 'passive', - }), - ], devtools: { - apply: 'build', + apply: 'serve', + embeddedVisibility: 'passive', }, }) ``` @@ -93,20 +88,15 @@ export default defineConfig({ Use `dockPreferences` to set the initial dock layout. Users can still change these settings in DevTools. ```ts [vite.config.ts] twoslash -import { DevTools } from '@vitejs/devtools' import { defineConfig } from 'vite' export default defineConfig({ - plugins: [ - DevTools({ - dockPreferences: { - defaultMode: 'edge', - defaultPosition: 'bottom', - }, - }), - ], devtools: { - apply: 'build', + apply: 'serve', + dockPreferences: { + defaultMode: 'edge', + defaultPosition: 'bottom', + }, }, }) ``` @@ -137,21 +127,16 @@ See [Client Script & Context](/kit/client-context#client-script-not-injected) fo Set `build.withApp` to write the static DevTools files alongside the app build: ```ts [vite.config.ts] twoslash -import { DevTools } from '@vitejs/devtools' import { defineConfig } from 'vite' export default defineConfig({ - plugins: [ - DevTools({ - build: { - withApp: true, // generate DevTools output during `vite build` - // outDir: 'custom-dir', // optional, defaults to Vite's build.outDir - }, - }), - ], devtools: { apply: 'build', - } + build: { + withApp: true, // generate DevTools output during `vite build` + // outDir: 'custom-dir', // optional, defaults to Vite's build.outDir + }, + }, }) ``` diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index 7aac62feb..8f2cc75a3 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -1,3 +1,4 @@ +import type { DevToolsIntegrationConfig } from './node/plugins/integration' import { DevToolsIntegration as _DevToolsIntegration, runDevTools as _runDevTools, @@ -5,12 +6,18 @@ import { export interface DevToolsIntegrationOptions { config: unknown + devtools: DevToolsIntegrationConfig } export function DevToolsIntegration(options: DevToolsIntegrationOptions): Promise<{ name: string }[]> { return _DevToolsIntegration(options as Parameters[0]) } -export function runDevTools(builder: unknown): Promise { - return _runDevTools(builder) +export function runDevTools( + builder: unknown, + devtools: DevToolsIntegrationConfig, +): Promise { + return _runDevTools(builder, devtools) } + +export type { DevToolsIntegrationConfig } diff --git a/packages/core/src/node/__tests__/auth-handler.test.ts b/packages/core/src/node/__tests__/auth-handler.test.ts index 2f6867d8b..a973c8a72 100644 --- a/packages/core/src/node/__tests__/auth-handler.test.ts +++ b/packages/core/src/node/__tests__/auth-handler.test.ts @@ -1,25 +1,28 @@ import type { ResolvedConfig } from 'vite' -import type { DevToolsConfig } from '../config' import process from 'node:process' import { describe, expect, it, vi } from 'vitest' import { getAuthHandler } from '../auth-handler' +import { normalizeDevToolsConfig } from '../config' import { createDevToolsContext } from '../context' import '@vitejs/devtools-kit' -function createConfig(config?: Partial): ResolvedConfig { +function createConfig(): ResolvedConfig { return { root: process.cwd(), command: 'serve', plugins: [], server: { port: 5173 }, - devtools: config === undefined ? undefined : { config }, } as unknown as ResolvedConfig } describe('getAuthHandler banner', () => { it('forwards a configured banner to the interactive auth handler', async () => { const banner = vi.fn() - const ctx = await createDevToolsContext(createConfig({ banner })) + const ctx = await createDevToolsContext( + createConfig(), + undefined, + normalizeDevToolsConfig({ banner }, 'localhost'), + ) getAuthHandler(ctx).printBanner() @@ -31,7 +34,11 @@ describe('getAuthHandler banner', () => { it('falls back to the default stdout banner when unset', async () => { const log = vi.spyOn(console, 'log').mockImplementation(() => {}) - const ctx = await createDevToolsContext(createConfig()) + const ctx = await createDevToolsContext( + createConfig(), + undefined, + normalizeDevToolsConfig(true, 'localhost'), + ) try { getAuthHandler(ctx).printBanner() diff --git a/packages/core/src/node/__tests__/context-auth.test.ts b/packages/core/src/node/__tests__/context-auth.test.ts index d2882a14e..f9ec39b6a 100644 --- a/packages/core/src/node/__tests__/context-auth.test.ts +++ b/packages/core/src/node/__tests__/context-auth.test.ts @@ -1,6 +1,7 @@ import type { ResolvedConfig } from 'vite' import process from 'node:process' import { afterEach, describe, expect, it } from 'vitest' +import { normalizeDevToolsConfig } from '../config' import { createDevToolsContext } from '../context' import '@vitejs/devtools-kit' @@ -12,25 +13,37 @@ function createConfig(options: { root: process.cwd(), command: options.command ?? 'serve', plugins: [], - devtools: options.clientAuth === undefined - ? undefined - : { config: { clientAuth: options.clientAuth } }, } as unknown as ResolvedConfig } +function createDevToolsConfig(clientAuth?: boolean) { + return normalizeDevToolsConfig( + clientAuth === undefined ? true : { clientAuth }, + 'localhost', + ) +} + describe('createDevToolsContext auth registration', () => { afterEach(() => { delete process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH }) it('registers the interactive-auth handshake when client auth is enabled', async () => { - const ctx = await createDevToolsContext(createConfig()) + const ctx = await createDevToolsContext( + createConfig(), + undefined, + createDevToolsConfig(), + ) expect(ctx.rpc.definitions.has('anonymous:devframe:auth')).toBe(true) }) it('skips the interactive-auth handshake in build mode (regression #539)', async () => { - const ctx = await createDevToolsContext(createConfig({ command: 'build' })) + const ctx = await createDevToolsContext( + createConfig({ command: 'build' }), + undefined, + createDevToolsConfig(), + ) // Left unregistered so devframe's `auth: false` auto-trust shim (armed // by `createDevToolsHub`) can install its own noop handler and mark the @@ -39,7 +52,11 @@ describe('createDevToolsContext auth registration', () => { }) it('skips the interactive-auth handshake when `devtools.clientAuth` is false (regression #539)', async () => { - const ctx = await createDevToolsContext(createConfig({ clientAuth: false })) + const ctx = await createDevToolsContext( + createConfig({ clientAuth: false }), + undefined, + createDevToolsConfig(false), + ) expect(ctx.rpc.definitions.has('anonymous:devframe:auth')).toBe(false) }) @@ -47,7 +64,11 @@ describe('createDevToolsContext auth registration', () => { it('skips the interactive-auth handshake when VITE_DEVTOOLS_DISABLE_CLIENT_AUTH=true (regression #539)', async () => { process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH = 'true' - const ctx = await createDevToolsContext(createConfig()) + const ctx = await createDevToolsContext( + createConfig(), + undefined, + createDevToolsConfig(), + ) expect(ctx.rpc.definitions.has('anonymous:devframe:auth')).toBe(false) }) diff --git a/packages/core/src/node/__tests__/integration.test.ts b/packages/core/src/node/__tests__/integration.test.ts index cc5ceed8c..449267ef4 100644 --- a/packages/core/src/node/__tests__/integration.test.ts +++ b/packages/core/src/node/__tests__/integration.test.ts @@ -1,22 +1,41 @@ import type { Plugin, ResolvedConfig } from 'vite' -import { describe, expect, it } from 'vitest' -import { DevToolsIntegration } from '../plugins/integration' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { DevToolsIntegration, runDevTools } from '../plugins/integration' +import { startDevTools } from '../start' -function createConfig(command: 'serve' | 'build', apply: 'serve' | 'build' | 'all' = command): ResolvedConfig { +vi.mock('../start', () => ({ + startDevTools: vi.fn(), +})) + +function createConfig( + command: 'serve' | 'build', + environments: ResolvedConfig['environments'] = {}, +): ResolvedConfig { return { command, root: '/vite-devtools-test-project', - devtools: { - apply, - config: {}, - enabled: true, - }, + environments, + plugins: [], } as unknown as ResolvedConfig } +function createDevToolsConfig(apply: 'serve' | 'build' | 'all') { + return { + host: 'localhost', + options: { apply }, + } as const +} + describe('devToolsIntegration', () => { + beforeEach(() => { + vi.mocked(startDevTools).mockClear() + }) + it('returns the existing DevTools plugins for serve', async () => { - const plugins = await DevToolsIntegration({ config: createConfig('serve') }) + const plugins = await DevToolsIntegration({ + config: createConfig('serve'), + devtools: createDevToolsConfig('serve'), + }) expect((plugins as Plugin[]).map(plugin => plugin.name)).toEqual([ 'vite:devtools:builtin', @@ -26,7 +45,10 @@ describe('devToolsIntegration', () => { }) it('returns the build integration plugin for build', async () => { - const [plugin] = await DevToolsIntegration({ config: createConfig('build') }) + const [plugin] = await DevToolsIntegration({ + config: createConfig('build'), + devtools: createDevToolsConfig('build'), + }) expect(plugin).toMatchObject({ name: 'vite:devtools:integration', @@ -34,11 +56,27 @@ describe('devToolsIntegration', () => { }) }) + it('creates the static build plugin from the core config', async () => { + const plugins = await DevToolsIntegration({ + config: createConfig('build'), + devtools: { + host: 'localhost', + options: { build: { withApp: true } }, + }, + }) + + expect(plugins.map(plugin => plugin.name)).toContain('vite:devtools:build') + expect(plugins.map(plugin => plugin.name)).not.toContain('vite:devtools') + }) + it.each([ { command: 'serve', expected: 'post' }, { command: 'build', expected: undefined }, ] as const)('uses the current $command integration when apply is all', async ({ command, expected }) => { - const plugins = await DevToolsIntegration({ config: createConfig(command, 'all') }) + const plugins = await DevToolsIntegration({ + config: createConfig(command), + devtools: createDevToolsConfig('all'), + }) const plugin = command === 'serve' ? plugins.find(plugin => plugin.name === 'vite:devtools:server') : plugins[0] @@ -47,20 +85,57 @@ describe('devToolsIntegration', () => { }) it('returns no plugins when apply excludes the current command', async () => { - const plugins = await DevToolsIntegration({ config: createConfig('serve', 'build') }) + const plugins = await DevToolsIntegration({ + config: createConfig('serve'), + devtools: createDevToolsConfig('build'), + }) expect(plugins).toEqual([]) }) + it('passes the resolved config to standalone DevTools', async () => { + const config = createConfig('build', { client: {} as never }) + + await runDevTools({ config }, { + host: 'dev.example.com', + options: { + allowedOrigins: ['https://dev.example.com'], + builtinDevTools: false, + clientAuthTokens: ['trusted-token'], + }, + }) + + const resolvedConfig = { + apply: 'all', + config: expect.objectContaining({ + allowedOrigins: ['https://dev.example.com'], + builtinDevTools: false, + clientAuth: true, + clientAuthTokens: ['trusted-token'], + host: 'dev.example.com', + }), + enabled: true, + } + expect(startDevTools).toHaveBeenCalledWith( + expect.objectContaining({ + host: 'dev.example.com', + root: '/vite-devtools-test-project', + }), + resolvedConfig, + ) + }) + it('enables Rolldown DevTools for selected build environments', async () => { - const [plugin] = await DevToolsIntegration({ config: createConfig('build') }) + const [plugin] = await DevToolsIntegration({ + config: createConfig('build'), + devtools: { + host: 'localhost', + options: { environments: ['client'] }, + }, + }) const client: { build: { rolldownOptions: { devtools?: object } } } = { build: { rolldownOptions: {} } } const ssr: { build: { rolldownOptions: { devtools?: object } } } = { build: { rolldownOptions: {} } } const config = { - devtools: { - config: { environments: ['client'] }, - enabled: true, - }, environments: { client, ssr }, } as unknown as ResolvedConfig diff --git a/packages/core/src/node/auth-handler.ts b/packages/core/src/node/auth-handler.ts index c67f1303d..376a2e0a5 100644 --- a/packages/core/src/node/auth-handler.ts +++ b/packages/core/src/node/auth-handler.ts @@ -1,7 +1,7 @@ import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' -import type { DevToolsConfig } from './config' import process from 'node:process' import { createInteractiveAuth } from 'devframe/recipes/interactive-auth' +import { getResolvedDevToolsConfig } from './resolved-config' export type DevToolsAuthHandler = ReturnType @@ -18,10 +18,10 @@ const handlers = new WeakMap() export function getAuthHandler(context: ViteDevToolsNodeContext): DevToolsAuthHandler { let handler = handlers.get(context) if (!handler) { - const config = context.viteConfig.devtools?.config as DevToolsConfig | undefined + const config = getResolvedDevToolsConfig(context).config handler = createInteractiveAuth(context, { - clientAuthTokens: config?.clientAuthTokens, - banner: config?.banner, + clientAuthTokens: config.clientAuthTokens, + banner: config.banner, }) handlers.set(context, handler) } @@ -41,6 +41,6 @@ export function getAuthHandler(context: ViteDevToolsNodeContext): DevToolsAuthHa */ export function isClientAuthDisabled(context: ViteDevToolsNodeContext): boolean { return context.mode === 'build' - || context.viteConfig.devtools?.config?.clientAuth === false + || getResolvedDevToolsConfig(context).config.clientAuth === false || process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH === 'true' } diff --git a/packages/core/src/node/cli-commands.ts b/packages/core/src/node/cli-commands.ts index 47fef5e87..50b5528ef 100644 --- a/packages/core/src/node/cli-commands.ts +++ b/packages/core/src/node/cli-commands.ts @@ -1,9 +1,6 @@ /* eslint-disable no-console */ -import { DEVTOOLS_MOUNT_PATH } from '@vitejs/devtools-kit/constants' -import { normalizeHttpServerUrl } from 'devframe/internal' import { colors as c } from 'devframe/utils/colors' -import { open } from 'devframe/utils/open' import { resolve } from 'pathe' import { MARK_NODE } from './constants' import { diagnostics } from './diagnostics' @@ -17,57 +14,8 @@ export interface StartOptions { } export async function start(options: StartOptions) { - const { host } = options - const { getPort } = await import('devframe/utils/get-port') - const port = await getPort({ - host, - port: options.port == null ? undefined : +options.port, - portRange: [9999, 15000], - }) - - const { startStandaloneDevTools } = await import('./standalone') - const { createDevToolsHub } = await import('./server') - - const devtools = await startStandaloneDevTools({ - cwd: options.root, - }) - - // Standalone has no shared HTTP server for the WS upgrade, so the hub opens - // a side-car WS server (advertised in `__connection.json`). Its middleware - // answers the whole `/__devtools/` surface — the branded hub-ui viewer, the - // connection meta, and the client bundles. - const { middleware } = await createDevToolsHub({ - context: devtools.context, - host, - }) - - const { createServer } = await import('node:http') - const { defineHandler, H3, sendRedirect } = await import('h3') - const { toNodeHandler } = await import('h3/node') - const { mountStaticHandler } = await import('devframe/utils/serve-static') - const { resolveStaticAssetsSource } = await import('devframe/utils/remote-assets') - - const app = new H3() - - const projectStorageDir = devtools.context.host.getStorageDir('project') - for (const { baseUrl, source } of devtools.context.views.buildStaticDirs) - mountStaticHandler(app, baseUrl, resolveStaticAssetsSource(source, projectStorageDir)) - - app.use('/', defineHandler(event => sendRedirect(event, DEVTOOLS_MOUNT_PATH, 302))) - - const appHandler = toNodeHandler(app) - // Hub first (owns `/__devtools/*`); anything outside its base falls through - // to the sub-frame statics + the root redirect. - const server = createServer((req, res) => { - middleware(req, res, () => appHandler(req, res)) - }) - - server.listen(port, host, async () => { - const url = normalizeHttpServerUrl(host, port) - console.log(c.green`${MARK_NODE} Vite DevTools started at`, c.green(url), '\n') - if (options.open) - await open(url) - }) + const { startDevTools } = await import('./start') + return startDevTools(options) } export interface BuildOptions { diff --git a/packages/core/src/node/config.ts b/packages/core/src/node/config.ts index bcde84845..be946b36b 100644 --- a/packages/core/src/node/config.ts +++ b/packages/core/src/node/config.ts @@ -1,9 +1,9 @@ -import type { CreateInteractiveAuthOptions } from 'devframe/recipes/interactive-auth' import type { StartOptions } from './cli-commands' +import type { DevToolsUserOptions } from './plugin-options' export type DevToolsApply = 'serve' | 'build' | 'all' -export interface DevToolsConfig extends Partial { +export interface DevToolsConfig extends Partial, DevToolsUserOptions { /** * Enable Vite DevTools. * @@ -42,7 +42,7 @@ export interface DevToolsConfig extends Partial { * The default banner is a boxed `console.log` from inside the dev server. * Supply this to surface the code in the host's own chrome instead. */ - banner?: CreateInteractiveAuthOptions['banner'] + banner?: (info: { code: string, url: string }) => void /** * Origins allowed to open the DevTools WebSocket connection, in addition to the built-in * loopback allowlist (`localhost`, `127.0.0.1`, etc). diff --git a/packages/core/src/node/context.ts b/packages/core/src/node/context.ts index 44e17928f..a7d6c3b72 100644 --- a/packages/core/src/node/context.ts +++ b/packages/core/src/node/context.ts @@ -1,11 +1,16 @@ import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import type { RpcFunctionsHost } from 'devframe/node' import type { ResolvedConfig, ViteDevServer } from 'vite' +import type { ResolvedDevToolsConfig } from './config' import { createKitContext, createViteDevToolsHost } from '@vitejs/devtools-kit/node' import { createDebug } from 'obug' import { DEVTOOLS_ASSETS_BASE, dirAssets } from '../dirs' import { getAuthHandler, isClientAuthDisabled } from './auth-handler' import { diagnostics } from './diagnostics' +import { + defaultResolvedDevToolsConfig, + setResolvedDevToolsConfig, +} from './resolved-config' import { builtinRpcDeclarations } from './rpc' const debugSetup = createDebug('vite:devtools:context:setup') @@ -29,6 +34,7 @@ function shouldSkipSetupByCapabilities( export async function createDevToolsContext( viteConfig: ResolvedConfig, viteServer?: ViteDevServer, + devtoolsConfig?: ResolvedDevToolsConfig, ): Promise { const cwd = viteConfig.root @@ -46,6 +52,11 @@ export async function createDevToolsContext( viteServer, })) as ViteDevToolsNodeContext + setResolvedDevToolsConfig( + context, + devtoolsConfig ?? defaultResolvedDevToolsConfig, + ) + // Fold the core (Vite) diagnostics into the shared host logger so plugin // setup() hooks can reference DTK codes via `ctx.diagnostics.logger`. context.diagnostics.register(diagnostics) diff --git a/packages/core/src/node/plugin-options.ts b/packages/core/src/node/plugin-options.ts new file mode 100644 index 000000000..e72e75e15 --- /dev/null +++ b/packages/core/src/node/plugin-options.ts @@ -0,0 +1,66 @@ +export type DevToolsBrandingLogo + = | string + | { light: string, dark: string } + +export interface DevToolsBranding { + productName?: string + logo?: DevToolsBrandingLogo + wordmark?: DevToolsBrandingLogo + primaryColor?: string + tagline?: string + favicon?: string + windowTitle?: string +} + +export interface DevToolsDockPreferences { + categoryOrder?: Record + maxVisibleItems?: number + defaultMode?: 'float' | 'edge' + defaultPosition?: 'left' | 'right' | 'top' | 'bottom' +} + +export interface DevToolsDockRendererRegistration { + type: string + file: string + importName?: string +} + +export type DevToolsEmbeddedVisibility = 'normal' | 'passive' | 'hidden' + +export interface ViteDevToolsUiOptions { + branding?: DevToolsBranding + embeddedVisibility?: DevToolsEmbeddedVisibility + dockPreferences?: DevToolsDockPreferences +} + +export interface DevToolsUserOptions { + /** + * Include the Vite builtin devtools UI. + * + * @default true + */ + builtinDevTools?: boolean + /** Dock renderer modules, replacing built-ins with the same type and appending new types. */ + renderers?: readonly DevToolsDockRendererRegistration[] + /** Override the branding handed to the DevTools client. */ + branding?: ViteDevToolsUiOptions['branding'] + /** Control how the embedded floating dock reveals itself. */ + embeddedVisibility?: ViteDevToolsUiOptions['embeddedVisibility'] + /** Configure the initial dock layout. */ + dockPreferences?: ViteDevToolsUiOptions['dockPreferences'] + /** Options for building static DevTools output alongside `vite build`. */ + build?: { + /** + * Automatically build DevTools when running `vite build`. + * @default false + */ + withApp?: boolean + /** Output directory relative to root. Defaults to Vite's `build.outDir`. */ + outDir?: string + } +} + +export interface DevToolsOptions extends DevToolsUserOptions { + /** Directory to search for installed integrations. */ + cwd?: string +} diff --git a/packages/core/src/node/plugins/__tests__/index.test.ts b/packages/core/src/node/plugins/__tests__/index.test.ts index 9c29df92e..48a0aaa05 100644 --- a/packages/core/src/node/plugins/__tests__/index.test.ts +++ b/packages/core/src/node/plugins/__tests__/index.test.ts @@ -1,13 +1,21 @@ import { isPackageExists } from 'local-pkg' import { resolve } from 'pathe' import { describe, expect, it, vi } from 'vitest' -import { DevTools } from '../index' +import { createDevToolsPlugins, DevTools } from '../index' vi.mock('local-pkg', () => ({ isPackageExists: vi.fn(() => false), })) describe('devTools', () => { + it('marks only the public manual plugin entry', async () => { + const manualPlugins = await DevTools({ builtinDevTools: false }) + const internalPlugins = await createDevToolsPlugins({ builtinDevTools: false }) + + expect(manualPlugins.map(plugin => plugin.name)).toContain('vite:devtools') + expect(internalPlugins.map(plugin => plugin.name)).not.toContain('vite:devtools') + }) + it('resolves optional integrations from the configured project directory', async () => { const cwd = 'project/root' const resolvedCwd = resolve(cwd) diff --git a/packages/core/src/node/plugins/build.ts b/packages/core/src/node/plugins/build.ts index 02669938e..dd00ef7b0 100644 --- a/packages/core/src/node/plugins/build.ts +++ b/packages/core/src/node/plugins/build.ts @@ -2,12 +2,14 @@ import type { DockRendererRegistration, ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import type { Plugin, ResolvedConfig } from 'vite' +import type { ResolvedDevToolsConfig } from '../config' import type { ViteDevToolsUiOptions } from '../ui' import { colors as c } from 'devframe/utils/colors' import { resolve } from 'pathe' import { MARK_NODE } from '../constants' export interface DevToolsBuildOptions { + resolvedConfig?: ResolvedDevToolsConfig outDir?: string renderers?: readonly DockRendererRegistration[] /** Reference-UI options forwarded to the static snapshot's `createUi`. */ @@ -28,7 +30,11 @@ export function DevToolsBuild(options: DevToolsBuildOptions = {}): Plugin { async buildStart() { const { createDevToolsContext } = await import('../context') - context = await createDevToolsContext(resolvedConfig) + context = await createDevToolsContext( + resolvedConfig, + undefined, + options.resolvedConfig, + ) }, async closeBundle() { diff --git a/packages/core/src/node/plugins/index.ts b/packages/core/src/node/plugins/index.ts index e2ded6f0c..10cd0131d 100644 --- a/packages/core/src/node/plugins/index.ts +++ b/packages/core/src/node/plugins/index.ts @@ -1,99 +1,71 @@ -import type { DockRendererRegistration } from '@vitejs/devtools-kit' import type { Plugin } from 'vite' -import type { ViteDevToolsUiOptions } from '../ui' +import type { ResolvedDevToolsConfig } from '../config' +import type { DevToolsOptions } from '../plugin-options' import { DevToolsBuild } from './build' import { DevToolsBuiltin } from './builtin' import { DevToolsInjection } from './injection' import { DevToolsServer } from './server' -export interface DevToolsOptions { - /** Directory to search for installed integrations. */ - cwd?: string - /** - * Include the Vite builtin devtools UI. - * - * @default true - */ - builtinDevTools?: boolean +export type { DevToolsOptions } from '../plugin-options' - /** Dock renderer modules, replacing built-ins with the same type and appending new types. */ - renderers?: readonly DockRendererRegistration[] - - /** - * Override the branding handed to the DevTools client (`@devframes/hub-ui`) - * — product name, logo, wordmark, primary color, tagline, favicon, and - * window title. - * - * Each field is merged over the built-in Vite DevTools defaults, so a host - * embedding Vite DevTools (e.g. Nuxt DevTools) can re-skin the client while - * inheriting any field it leaves unset. Asset fields - * (`logo`/`wordmark`/`favicon`) take URL strings the host is responsible for - * serving. - */ - branding?: ViteDevToolsUiOptions['branding'] - - /** - * How the embedded floating dock reveals itself on a fresh page. - * - * - `'normal'` — show the docks immediately. - * - `'passive'` — the floating docks stay hidden and a console hint invites - * the developer to reveal them with a keyboard shortcut. Revealing once - * persists per-origin, so later dev sessions on this browser start shown; - * the "Hide DevTools" command returns to passive mode. - * - `'hidden'` — always keep the docks hidden; the shortcut reveals them for - * the current session only, without remembering the choice. - * - * Seeds a user-overridable preference published as - * `ConnectionMeta.configs.ui.embeddedVisibility`. - * - * @default 'normal' - */ - embeddedVisibility?: ViteDevToolsUiOptions['embeddedVisibility'] - - /** - * Dock-bar rendering preferences — category ordering, floating-dock - * inline-item capacity, and the first-run float/edge mode and position. - * Each seeds a user-overridable preference published as - * `ConnectionMeta.configs.ui.dockPreferences`. - */ - dockPreferences?: ViteDevToolsUiOptions['dockPreferences'] +export function resolveDevToolsPluginOptions( + config: ResolvedDevToolsConfig, + cwd: string, +): DevToolsOptions { + const { + branding, + build, + builtinDevTools, + dockPreferences, + embeddedVisibility, + renderers, + } = config.config - /** - * Options for building static DevTools output alongside `vite build`. - */ - build?: { - /** - * Automatically build DevTools when running `vite build`. - * - * @default false - */ - withApp?: boolean - /** - * Output directory for the DevTools build (relative to root). - * Defaults to Vite's `build.outDir`. - */ - outDir?: string + return { + branding, + build, + builtinDevTools, + cwd, + dockPreferences, + embeddedVisibility, + renderers, } } export async function DevTools(options: DevToolsOptions = {}): Promise { + return [ + { name: 'vite:devtools' }, + ...await createDevToolsPlugins(options), + ] +} + +export async function createDevToolsPlugins( + options: DevToolsOptions = {}, + resolvedConfig?: ResolvedDevToolsConfig, +): Promise { const { builtinDevTools = true, build, branding, embeddedVisibility = 'normal', dockPreferences, + renderers, } = options const ui = { branding, embeddedVisibility, dockPreferences } const plugins = [ DevToolsInjection(), - DevToolsServer(ui, options.renderers), + DevToolsServer(ui, resolvedConfig, renderers), ] if (build?.withApp) { - plugins.push(DevToolsBuild({ outDir: build.outDir, ui, renderers: options.renderers })) + plugins.push(DevToolsBuild({ + outDir: build.outDir, + renderers, + resolvedConfig, + ui, + })) } plugins.unshift( diff --git a/packages/core/src/node/plugins/integration.ts b/packages/core/src/node/plugins/integration.ts index 332ca20bc..c83bcbb7a 100644 --- a/packages/core/src/node/plugins/integration.ts +++ b/packages/core/src/node/plugins/integration.ts @@ -1,16 +1,24 @@ import type { Plugin, ResolvedConfig, ViteBuilder } from 'vite' -import type { ResolvedDevToolsConfig } from '../config' -import { isDevToolsEnabled } from '../config' -import { DevTools } from './index' +import type { DevToolsConfig, ResolvedDevToolsConfig } from '../config' +import { isDevToolsEnabled, normalizeDevToolsConfig } from '../config' +import { createDevToolsPlugins, resolveDevToolsPluginOptions } from './index' type DevToolsEnvironment = ResolvedConfig['environments'][string] export interface DevToolsIntegrationOptions { config: ResolvedConfig + devtools: DevToolsIntegrationConfig } -function getDevToolsEnvironments(config: ResolvedConfig): DevToolsEnvironment[] { - const devToolsConfig = config.devtools as ResolvedDevToolsConfig +export interface DevToolsIntegrationConfig { + host: string + options: boolean | DevToolsConfig | undefined +} + +function getDevToolsEnvironments( + config: ResolvedConfig, + devToolsConfig: ResolvedDevToolsConfig, +): DevToolsEnvironment[] { const environmentNames = devToolsConfig.config.environments ?? Object.keys(config.environments) const environments: DevToolsEnvironment[] = [] @@ -24,14 +32,21 @@ function getDevToolsEnvironments(config: ResolvedConfig): DevToolsEnvironment[] return environments } -export async function runDevTools(builder: unknown) { +export async function runDevTools( + builder: unknown, + devtools: DevToolsIntegrationConfig, +) { const config = (builder as ViteBuilder).config - if (!isDevToolsEnabled(config.devtools as ResolvedDevToolsConfig, config.command)) + const devtoolsConfig = normalizeDevToolsConfig(devtools.options, devtools.host) + if (!isDevToolsEnabled(devtoolsConfig, config.command)) return - for (const _environment of getDevToolsEnvironments(config)) { + for (const _environment of getDevToolsEnvironments(config, devtoolsConfig)) { try { - const { start } = await import('../cli-commands') - await start(config.devtools.config) + const { startDevTools } = await import('../start') + await startDevTools({ + ...devtoolsConfig.config, + root: devtoolsConfig.config.root ?? config.root, + }, devtoolsConfig) } catch (error: any) { config.logger.error( @@ -42,7 +57,7 @@ export async function runDevTools(builder: unknown) { } } -function DevToolsBuildIntegration(): Plugin { +function DevToolsBuildIntegration(devtoolsConfig: ResolvedDevToolsConfig): Plugin { return { name: 'vite:devtools:integration', apply: 'build', @@ -50,7 +65,7 @@ function DevToolsBuildIntegration(): Plugin { order: 'post', handler(config) { // Enable `rolldownOptions.devtools` if the environment is selected, or for all environments by default. - for (const environment of getDevToolsEnvironments(config)) { + for (const environment of getDevToolsEnvironments(config, devtoolsConfig)) { environment.build.rolldownOptions.devtools ??= {} } }, @@ -59,10 +74,21 @@ function DevToolsBuildIntegration(): Plugin { } export async function DevToolsIntegration(options: DevToolsIntegrationOptions): Promise { - const config = options.config - if (!isDevToolsEnabled(config.devtools as ResolvedDevToolsConfig, config.command)) + const { config, devtools } = options + const devtoolsConfig = normalizeDevToolsConfig(devtools.options, devtools.host) + const enabled = isDevToolsEnabled(devtoolsConfig, config.command) + if (!enabled) { return [] - return options.config.command === 'serve' - ? DevTools({ cwd: options.config.root }) - : [DevToolsBuildIntegration()] + } + + const pluginOptions = resolveDevToolsPluginOptions(devtoolsConfig, config.root) + if (config.command === 'serve') { + return createDevToolsPlugins(pluginOptions, devtoolsConfig) + } + + const plugins = [DevToolsBuildIntegration(devtoolsConfig)] + if (devtoolsConfig.config.build?.withApp) { + plugins.push(...await createDevToolsPlugins(pluginOptions, devtoolsConfig)) + } + return plugins } diff --git a/packages/core/src/node/plugins/server.ts b/packages/core/src/node/plugins/server.ts index 6586062ae..6d2ee492c 100644 --- a/packages/core/src/node/plugins/server.ts +++ b/packages/core/src/node/plugins/server.ts @@ -1,6 +1,7 @@ import type { ClientScriptEntry, DevToolsDockEntry, DockRendererRegistration, ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import type { Server as NodeHttpServer } from 'node:http' import type { Plugin } from 'vite' +import type { ResolvedDevToolsConfig } from '../config' import type { ViteDevToolsUiOptions } from '../ui' import { DEVTOOLS_DOCK_IMPORTS_VIRTUAL_ID, @@ -39,6 +40,7 @@ export function renderDockImportsMap(docks: Iterable): string export function DevToolsServer( options: ViteDevToolsUiOptions = {}, + devtoolsConfig?: ResolvedDevToolsConfig, renderers?: readonly DockRendererRegistration[], ): Plugin { let context: ViteDevToolsNodeContext @@ -48,7 +50,11 @@ export function DevToolsServer( enforce: 'post', apply: 'serve', async configureServer(viteDevServer) { - context = await createDevToolsContext(viteDevServer.config, viteDevServer) + context = await createDevToolsContext( + viteDevServer.config, + viteDevServer, + devtoolsConfig, + ) const host = viteDevServer.config.server.host === true ? '0.0.0.0' diff --git a/packages/core/src/node/resolved-config.ts b/packages/core/src/node/resolved-config.ts new file mode 100644 index 000000000..862fc1f86 --- /dev/null +++ b/packages/core/src/node/resolved-config.ts @@ -0,0 +1,30 @@ +import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' +import type { ResolvedDevToolsConfig } from './config' + +const resolvedDevToolsConfigs = new WeakMap< + ViteDevToolsNodeContext, + ResolvedDevToolsConfig +>() + +export const defaultResolvedDevToolsConfig: ResolvedDevToolsConfig = { + apply: 'all', + config: { + clientAuth: true, + clientAuthTokens: [], + host: 'localhost', + }, + enabled: true, +} + +export function setResolvedDevToolsConfig( + context: ViteDevToolsNodeContext, + config: ResolvedDevToolsConfig, +): void { + resolvedDevToolsConfigs.set(context, config) +} + +export function getResolvedDevToolsConfig( + context: ViteDevToolsNodeContext, +): ResolvedDevToolsConfig { + return resolvedDevToolsConfigs.get(context) ?? defaultResolvedDevToolsConfig +} diff --git a/packages/core/src/node/server.ts b/packages/core/src/node/server.ts index 200d4e083..df699336d 100644 --- a/packages/core/src/node/server.ts +++ b/packages/core/src/node/server.ts @@ -2,12 +2,12 @@ import type { HubInstance } from '@devframes/hub/initiate' import type { ConnectionMeta, DockRendererRegistration, ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import type { ViteDevToolsHost } from '@vitejs/devtools-kit/node' import type { Server as NodeHttpServer } from 'node:http' -import type { DevToolsConfig } from './config' import type { ViteDevToolsUiOptions } from './ui' import { initHub } from '@devframes/hub/initiate' import { DEVTOOLS_MOUNT_PATH } from '@vitejs/devtools-kit/constants' import { getAuthHandler, isClientAuthDisabled } from './auth-handler' import { resolveDockRendererRegistrations } from './renderers' +import { getResolvedDevToolsConfig } from './resolved-config' import { createViteDevToolsUi } from './ui' export interface CreateDevToolsHubOptions { @@ -58,9 +58,7 @@ export async function createDevToolsHub(options: CreateDevToolsHubOptions): Prom // helper) — see `isClientAuthDisabled` for why. const authDisabled = isClientAuthDisabled(context) - // Vite's published types bundle a frozen `DevToolsConfig` snapshot, so a - // field added here isn't visible through `config` until Vite re-vendors it. - const allowedOrigins = (context.viteConfig.devtools?.config as DevToolsConfig | undefined)?.allowedOrigins + const allowedOrigins = getResolvedDevToolsConfig(context).config.allowedOrigins const hub = initHub({ base: DEVTOOLS_MOUNT_PATH, diff --git a/packages/core/src/node/standalone.ts b/packages/core/src/node/standalone.ts index aaa7017fc..3d14b3a79 100644 --- a/packages/core/src/node/standalone.ts +++ b/packages/core/src/node/standalone.ts @@ -1,8 +1,9 @@ import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import type { Plugin, ResolvedConfig } from 'vite' +import type { ResolvedDevToolsConfig } from './config' import process from 'node:process' import { createDevToolsContext } from './context' -import { DevTools } from './plugins' +import { createDevToolsPlugins, resolveDevToolsPluginOptions } from './plugins' export interface StandaloneDevToolsOptions { cwd?: string @@ -10,6 +11,7 @@ export interface StandaloneDevToolsOptions { config?: string command?: 'build' | 'serve' mode?: 'development' | 'production' + resolvedConfig?: ResolvedDevToolsConfig } export async function startStandaloneDevTools(options: StandaloneDevToolsOptions = {}): Promise<{ @@ -23,12 +25,15 @@ export async function startStandaloneDevTools(options: StandaloneDevToolsOptions } = options const { resolveConfig } = await import('vite') + const pluginOptions = options.resolvedConfig + ? resolveDevToolsPluginOptions(options.resolvedConfig, cwd) + : { cwd } const resolved = await resolveConfig( { configFile: options.config, root: cwd, plugins: [ - DevTools({ cwd }), + createDevToolsPlugins(pluginOptions, options.resolvedConfig), ], }, command, @@ -40,7 +45,11 @@ export async function startStandaloneDevTools(options: StandaloneDevToolsOptions plugin => plugin.name?.startsWith('vite:devtools'), ) - const context = await createDevToolsContext(resolved) + const context = await createDevToolsContext( + resolved, + undefined, + options.resolvedConfig, + ) return { config: resolved, diff --git a/packages/core/src/node/start.ts b/packages/core/src/node/start.ts new file mode 100644 index 000000000..8dac12e9a --- /dev/null +++ b/packages/core/src/node/start.ts @@ -0,0 +1,69 @@ +import type { StartOptions } from './cli-commands' +import type { ResolvedDevToolsConfig } from './config' +import { DEVTOOLS_MOUNT_PATH } from '@vitejs/devtools-kit/constants' +import { normalizeHttpServerUrl } from 'devframe/internal' +import { colors as c } from 'devframe/utils/colors' +import { open } from 'devframe/utils/open' +import { MARK_NODE } from './constants' + +export async function startDevTools( + options: StartOptions, + resolvedConfig?: ResolvedDevToolsConfig, +) { + const { host } = options + const { getPort } = await import('devframe/utils/get-port') + const port = await getPort({ + host, + port: options.port == null ? undefined : +options.port, + portRange: [9999, 15000], + }) + + const { startStandaloneDevTools } = await import('./standalone') + const { createDevToolsHub } = await import('./server') + + const devtools = await startStandaloneDevTools({ + config: options.config, + cwd: options.root, + resolvedConfig, + }) + + // Standalone has no shared HTTP server for the WS upgrade, so the hub opens + // a side-car WS server (advertised in `__connection.json`). Its middleware + // answers the whole `/__devtools/` surface — the branded hub-ui viewer, the + // connection meta, and the client bundles. + const { middleware } = await createDevToolsHub({ + context: devtools.context, + host, + renderers: resolvedConfig?.config.renderers, + ui: resolvedConfig?.config, + }) + + const { createServer } = await import('node:http') + const { defineHandler, H3, sendRedirect } = await import('h3') + const { toNodeHandler } = await import('h3/node') + const { mountStaticHandler } = await import('devframe/utils/serve-static') + const { resolveStaticAssetsSource } = await import('devframe/utils/remote-assets') + + const app = new H3() + + const projectStorageDir = devtools.context.host.getStorageDir('project') + for (const { baseUrl, source } of devtools.context.views.buildStaticDirs) + mountStaticHandler(app, baseUrl, resolveStaticAssetsSource(source, projectStorageDir)) + + app.use('/', defineHandler(event => sendRedirect(event, DEVTOOLS_MOUNT_PATH, 302))) + + const appHandler = toNodeHandler(app) + // Hub first (owns `/__devtools/*`); anything outside its base falls through + // to the sub-frame statics + the root redirect. + const server = createServer((req, res) => { + middleware(req, res, () => appHandler(req, res)) + }) + + server.listen(port, host, async () => { + const url = normalizeHttpServerUrl(host, port) + // eslint-disable-next-line no-console + console.log(c.green`${MARK_NODE} Vite DevTools started at`, c.green(url), '\n') + if (options.open) + await open(url) + }) +} diff --git a/packages/core/src/node/ui.ts b/packages/core/src/node/ui.ts index f7dd7f597..805c0e30c 100644 --- a/packages/core/src/node/ui.ts +++ b/packages/core/src/node/ui.ts @@ -1,37 +1,10 @@ -import type { DevframeBranding, DevframeDockPreferences, EmbeddedVisibility } from '@devframes/hub-ui' +import type { DevframeBranding } from '@devframes/hub-ui' import type { DevframeHubUi } from '@devframes/hub/initiate' +import type { DevToolsBranding, ViteDevToolsUiOptions } from './plugin-options' import { createUi } from '@devframes/hub-ui' import { DEVTOOLS_ASSETS_BASE } from '../dirs' -export interface ViteDevToolsUiOptions { - /** - * Override the Vite DevTools branding handed to `@devframes/hub-ui` - * (`ConnectionMeta.configs.ui.branding`) — product name, logo, wordmark, - * primary color, tagline, favicon, and window title. - * - * Each field is merged over the built-in Vite DevTools defaults - * ({@link viteDevToolsBranding}), so a host such as Nuxt DevTools can - * re-skin the client while inheriting any field it leaves unset. Asset - * fields (`logo`/`wordmark`/`favicon`) take URL strings; a host serving its - * own marks is responsible for hosting them. - */ - branding?: DevframeBranding - /** - * How the embedded floating dock reveals itself on a fresh page. Seeds a - * user-overridable preference published as - * `ConnectionMeta.configs.ui.embeddedVisibility`. - * - * @default 'normal' - */ - embeddedVisibility?: EmbeddedVisibility - /** - * Dock-bar rendering preferences — category ordering, floating-dock - * inline-item capacity, and the first-run float/edge mode and position. - * Each seeds a user-overridable preference published as - * `ConnectionMeta.configs.ui.dockPreferences`. - */ - dockPreferences?: DevframeDockPreferences -} +export type { ViteDevToolsUiOptions } from './plugin-options' export function viteDevToolsBranding(): DevframeBranding { return { @@ -71,7 +44,7 @@ export function createViteDevToolsUi(options: ViteDevToolsUiOptions = {}): Devfr * the host actually sets win; an explicit `undefined` is ignored so a partial * override never clobbers a default with a hole. */ -function resolveBranding(overrides?: DevframeBranding): DevframeBranding { +function resolveBranding(overrides?: DevToolsBranding): DevframeBranding { const branding = viteDevToolsBranding() if (!overrides) { return branding diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/cli-commands.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools/cli-commands.snapshot.d.ts index 5fc89c50b..221b6d9df 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/cli-commands.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/cli-commands.snapshot.d.ts @@ -1,23 +1,9 @@ /** * Generated by tsnapi — public API snapshot of `@vitejs/devtools/cli-commands` */ -// #region Interfaces -export interface BuildOptions { - root: string; - config?: string; - outDir: string; - base: string; -} -export interface StartOptions { - root?: string; - config?: string; - host: string; - port?: string | number; - open?: boolean; -} -// #endregion - -// #region Functions -export declare function build(_: BuildOptions): Promise; -export declare function start(_: StartOptions): Promise; +// #region Other +export { build } +export { BuildOptions } +export { start } +export { StartOptions } // #endregion \ No newline at end of file diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts index 58e68b9c3..17d54e781 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts @@ -1,30 +1,10 @@ /** * Generated by tsnapi — public API snapshot of `@vitejs/devtools/config` */ -// #region Interfaces -export interface DevToolsConfig extends Partial { - enabled?: boolean; - apply?: DevToolsApply; - environments?: string[]; - clientAuth?: boolean; - clientAuthTokens?: string[]; - banner?: CreateInteractiveAuthOptions['banner']; - allowedOrigins?: string[]; -} -export interface ResolvedDevToolsConfig { - config: Omit & { - host: string; - }; - enabled: boolean; - apply: DevToolsApply; -} -// #endregion - -// #region Types -export type DevToolsApply = 'serve' | 'build' | 'all'; -// #endregion - -// #region Functions -export declare function isDevToolsEnabled(_: ResolvedDevToolsConfig, _: 'serve' | 'build'): boolean; -export declare function normalizeDevToolsConfig(_: DevToolsConfig | boolean | undefined, _: string): ResolvedDevToolsConfig; +// #region Other +export { DevToolsApply } +export { DevToolsConfig } +export { isDevToolsEnabled } +export { normalizeDevToolsConfig } +export { ResolvedDevToolsConfig } // #endregion \ No newline at end of file diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.d.ts index 47292c348..c0b4b2cae 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.d.ts @@ -23,31 +23,11 @@ export type BuiltinServerFunctions = RpcDefinitionsToFunctions; +export declare function createDevToolsContext(_: ResolvedConfig, _?: ViteDevServer, _?: ResolvedDevToolsConfig): Promise; export declare function createDevToolsHub(_: CreateDevToolsHubOptions): Promise; export declare function DevTools(_?: DevToolsOptions): Promise; // #endregion -// #region Referenced (internal) -interface DevToolsOptions { - cwd?: string; - builtinDevTools?: boolean; - renderers?: readonly DockRendererRegistration[]; - branding?: ViteDevToolsUiOptions['branding']; - embeddedVisibility?: ViteDevToolsUiOptions['embeddedVisibility']; - dockPreferences?: ViteDevToolsUiOptions['dockPreferences']; - build?: { - withApp?: boolean; - outDir?: string; - }; -} -interface ViteDevToolsUiOptions { - branding?: DevframeBranding; - embeddedVisibility?: EmbeddedVisibility; - dockPreferences?: DevframeDockPreferences; -} -// #endregion - // #region Other export { DevToolsInternalContext } export { InternalAnonymousAuthStorage } diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.js index 56da853b6..b0c91366a 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.js +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/index.snapshot.js @@ -2,7 +2,7 @@ * Generated by tsnapi — public API snapshot of `@vitejs/devtools` */ // #region Functions -export async function createDevToolsContext(_, _) {} +export async function createDevToolsContext(_, _, _) {} export async function createDevToolsHub(_) {} export async function DevTools(_) {} // #endregion \ No newline at end of file diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts index 2c342bf84..514f0e173 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts @@ -2,8 +2,13 @@ * Generated by tsnapi — public API snapshot of `@vitejs/devtools/integration` */ // #region Interfaces +export interface DevToolsIntegrationConfig { + host: string; + options: boolean | DevToolsConfig | undefined; +} export interface DevToolsIntegrationOptions { config: unknown; + devtools: DevToolsIntegrationConfig; } // #endregion @@ -11,5 +16,5 @@ export interface DevToolsIntegrationOptions { export declare function DevToolsIntegration(_: DevToolsIntegrationOptions): Promise<{ name: string; }[]>; -export declare function runDevTools(_: unknown): Promise; +export declare function runDevTools(_: unknown, _: DevToolsIntegrationConfig): Promise; // #endregion \ No newline at end of file diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js index 9948b4afc..3ff08e495 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js @@ -3,5 +3,5 @@ */ // #region Functions export function DevToolsIntegration(_) {} -export function runDevTools(_) {} +export function runDevTools(_, _) {} // #endregion \ No newline at end of file