@tanstack/devtools-vite 0.3.6 → 0.3.8

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/src/plugin.ts CHANGED
@@ -1,18 +1,18 @@
1
- import { exec } from 'node:child_process'
2
1
  import { devtoolsEventClient } from '@tanstack/devtools-client'
3
2
  import { ServerEventBus } from '@tanstack/devtools-event-bus/server'
4
3
  import { normalizePath } from 'vite'
5
4
  import chalk from 'chalk'
6
- import {
7
- handleDevToolsViteRequest,
8
- readPackageJson,
9
- tryParseJson,
10
- } from './utils'
5
+ import { handleDevToolsViteRequest, readPackageJson } from './utils'
11
6
  import { DEFAULT_EDITOR_CONFIG, handleOpenSource } from './editor'
12
7
  import { removeDevtools } from './remove-devtools'
13
8
  import { addSourceToJsx } from './inject-source'
14
9
  import { enhanceConsoleLog } from './enhance-logs'
15
- import type { OutdatedDeps } from '@tanstack/devtools-client'
10
+ import { detectDevtoolsFile, injectPluginIntoFile } from './inject-plugin'
11
+ import {
12
+ addPluginToDevtools,
13
+ emitOutdatedDeps,
14
+ installPackage,
15
+ } from './package-manager'
16
16
  import type { Plugin } from 'vite'
17
17
  import type { EditorConfig } from './editor'
18
18
  import type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server'
@@ -68,24 +68,6 @@ export type TanStackDevtoolsViteConfig = {
68
68
  export const defineDevtoolsConfig = (config: TanStackDevtoolsViteConfig) =>
69
69
  config
70
70
 
71
- const emitOutdatedDeps = async () => {
72
- return await new Promise<OutdatedDeps | null>((resolve) => {
73
- exec('npm outdated --json', (_, stdout) => {
74
- // npm outdated exits with code 1 if there are outdated packages, but still outputs valid JSON
75
- if (stdout) {
76
- const newOutdatedDeps = tryParseJson<OutdatedDeps>(stdout)
77
- if (!newOutdatedDeps) {
78
- return
79
- }
80
- devtoolsEventClient.emit('outdated-deps-read', {
81
- outdatedDeps: newOutdatedDeps,
82
- })
83
- resolve(newOutdatedDeps)
84
- }
85
- })
86
- })
87
- }
88
-
89
71
  export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
90
72
  let port = 5173
91
73
  const logging = args?.logging ?? true
@@ -95,6 +77,8 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
95
77
  const serverBusEnabled = args?.eventBusConfig?.enabled ?? true
96
78
  const bus = new ServerEventBus(args?.eventBusConfig)
97
79
 
80
+ let devtoolsFileId: string | null = null
81
+
98
82
  return [
99
83
  {
100
84
  enforce: 'pre',
@@ -194,18 +178,18 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
194
178
  },
195
179
  {
196
180
  name: '@tanstack/devtools:remove-devtools-on-build',
197
- apply(_, { command }) {
198
- return command === 'build' && removeDevtoolsOnBuild
181
+ apply(config, { command }) {
182
+ // Check both command and mode to support various hosting providers
183
+ // Some providers (Cloudflare, Netlify, Heroku) might not use 'build' command
184
+ // but will always set mode to 'production' for production builds
185
+ return (
186
+ (command !== 'serve' || config.mode === 'production') &&
187
+ removeDevtoolsOnBuild
188
+ )
199
189
  },
200
190
  enforce: 'pre',
201
191
  transform(code, id) {
202
- if (
203
- id.includes('node_modules') ||
204
- id.includes('?raw') ||
205
- id.includes('dist') ||
206
- id.includes('build')
207
- )
208
- return
192
+ if (id.includes('node_modules') || id.includes('?raw')) return
209
193
  const transform = removeDevtools(code, id)
210
194
  if (!transform) return
211
195
  if (logging) {
@@ -231,6 +215,174 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
231
215
  const packageJson = await readPackageJson()
232
216
  const outdatedDeps = emitOutdatedDeps().then((deps) => deps)
233
217
 
218
+ // Listen for package installation requests
219
+ devtoolsEventClient.on('install-devtools', async (event) => {
220
+ const result = await installPackage(event.payload.packageName)
221
+ devtoolsEventClient.emit('devtools-installed', {
222
+ packageName: event.payload.packageName,
223
+ success: result.success,
224
+ error: result.error,
225
+ })
226
+
227
+ // If installation was successful, automatically add the plugin to devtools
228
+ if (result.success) {
229
+ const { packageName, pluginName, pluginImport } = event.payload
230
+
231
+ console.log(
232
+ chalk.blueBright(
233
+ `[@tanstack/devtools-vite] Auto-adding ${packageName} to devtools...`,
234
+ ),
235
+ )
236
+
237
+ const injectResult = addPluginToDevtools(
238
+ devtoolsFileId,
239
+ packageName,
240
+ pluginName,
241
+ pluginImport,
242
+ )
243
+
244
+ if (injectResult.success) {
245
+ // Emit plugin-added event so the UI updates
246
+ devtoolsEventClient.emit('plugin-added', {
247
+ packageName,
248
+ success: true,
249
+ })
250
+
251
+ // Also re-read package.json to update the UI with the newly installed package
252
+ const updatedPackageJson = await readPackageJson()
253
+ devtoolsEventClient.emit('package-json-read', {
254
+ packageJson: updatedPackageJson,
255
+ })
256
+ }
257
+ }
258
+ })
259
+
260
+ // Listen for add plugin to devtools requests
261
+ devtoolsEventClient.on('add-plugin-to-devtools', (event) => {
262
+ const { packageName, pluginName, pluginImport } = event.payload
263
+
264
+ console.log(
265
+ chalk.blueBright(
266
+ `[@tanstack/devtools-vite] Adding ${packageName} to devtools...`,
267
+ ),
268
+ )
269
+
270
+ const result = addPluginToDevtools(
271
+ devtoolsFileId,
272
+ packageName,
273
+ pluginName,
274
+ pluginImport,
275
+ )
276
+
277
+ devtoolsEventClient.emit('plugin-added', {
278
+ packageName,
279
+ success: result.success,
280
+ error: result.error,
281
+ })
282
+ })
283
+
284
+ // Handle bump-package-version event
285
+ devtoolsEventClient.on('bump-package-version', async (event) => {
286
+ const {
287
+ packageName,
288
+ devtoolsPackage,
289
+ pluginName,
290
+ minVersion,
291
+ pluginImport,
292
+ } = event.payload
293
+
294
+ console.log(
295
+ chalk.blueBright(
296
+ `[@tanstack/devtools-vite] Bumping ${packageName} to version ${minVersion}...`,
297
+ ),
298
+ )
299
+
300
+ // Install the package with the minimum version
301
+ const packageWithVersion = minVersion
302
+ ? `${packageName}@^${minVersion}`
303
+ : packageName
304
+
305
+ const result = await installPackage(packageWithVersion)
306
+
307
+ if (!result.success) {
308
+ console.log(
309
+ chalk.redBright(
310
+ `[@tanstack/devtools-vite] Failed to bump ${packageName}: ${result.error}`,
311
+ ),
312
+ )
313
+ devtoolsEventClient.emit('devtools-installed', {
314
+ packageName: devtoolsPackage,
315
+ success: false,
316
+ error: result.error,
317
+ })
318
+ return
319
+ }
320
+
321
+ console.log(
322
+ chalk.greenBright(
323
+ `[@tanstack/devtools-vite] Successfully bumped ${packageName} to ${minVersion}!`,
324
+ ),
325
+ )
326
+
327
+ // Check if we found the devtools file
328
+ if (!devtoolsFileId) {
329
+ console.log(
330
+ chalk.yellowBright(
331
+ `[@tanstack/devtools-vite] Devtools file not found. Skipping auto-injection.`,
332
+ ),
333
+ )
334
+ devtoolsEventClient.emit('devtools-installed', {
335
+ packageName: devtoolsPackage,
336
+ success: true,
337
+ })
338
+ return
339
+ }
340
+
341
+ // Now inject the devtools plugin
342
+ console.log(
343
+ chalk.blueBright(
344
+ `[@tanstack/devtools-vite] Adding ${devtoolsPackage} to devtools...`,
345
+ ),
346
+ )
347
+
348
+ const injectResult = injectPluginIntoFile(devtoolsFileId, {
349
+ packageName: devtoolsPackage,
350
+ pluginName,
351
+ pluginImport,
352
+ })
353
+
354
+ if (injectResult.success) {
355
+ console.log(
356
+ chalk.greenBright(
357
+ `[@tanstack/devtools-vite] Successfully added ${devtoolsPackage} to devtools!`,
358
+ ),
359
+ )
360
+
361
+ devtoolsEventClient.emit('plugin-added', {
362
+ packageName: devtoolsPackage,
363
+ success: true,
364
+ })
365
+
366
+ // Re-read package.json to update the UI
367
+ const updatedPackageJson = await readPackageJson()
368
+ devtoolsEventClient.emit('package-json-read', {
369
+ packageJson: updatedPackageJson,
370
+ })
371
+ } else {
372
+ console.log(
373
+ chalk.redBright(
374
+ `[@tanstack/devtools-vite] Failed to add ${devtoolsPackage} to devtools: ${injectResult.error}`,
375
+ ),
376
+ )
377
+
378
+ devtoolsEventClient.emit('plugin-added', {
379
+ packageName: devtoolsPackage,
380
+ success: false,
381
+ error: injectResult.error,
382
+ })
383
+ }
384
+ })
385
+
234
386
  // whenever a client mounts we send all the current info to the subscribers
235
387
  devtoolsEventClient.on('mounted', async () => {
236
388
  devtoolsEventClient.emit('outdated-deps-read', {
@@ -271,5 +423,23 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
271
423
  return enhanceConsoleLog(code, id, port)
272
424
  },
273
425
  },
426
+ {
427
+ name: '@tanstack/devtools:inject-plugin',
428
+ apply(config, { command }) {
429
+ return config.mode === 'development' && command === 'serve'
430
+ },
431
+ transform(code, id) {
432
+ // First pass: find where TanStackDevtools is imported
433
+ if (!devtoolsFileId && detectDevtoolsFile(code)) {
434
+ // Extract actual file path (remove query params)
435
+ const [filePath] = id.split('?')
436
+ if (filePath) {
437
+ devtoolsFileId = filePath
438
+ }
439
+ }
440
+
441
+ return undefined
442
+ },
443
+ },
274
444
  ]
275
445
  }