From e7d92c26a33a74f46dde874fa8a4dfa79fe1ffb1 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Thu, 16 Mar 2023 19:26:13 +0100 Subject: [PATCH 1/6] feat: able to upgrade package --- package.json | 7 +- .../devtools-kit/src/_types/integrations.ts | 8 +- packages/devtools-kit/src/_types/rpc.ts | 10 +- packages/devtools-kit/src/_types/terminals.ts | 7 + packages/devtools-kit/src/index.ts | 12 +- packages/devtools-ui-kit/package.json | 14 +- .../devtools/client/components/ModuleItem.vue | 22 +- .../client/components/NpmVersionCheck.vue | 57 + .../client/components/TerminalView.vue | 2 +- packages/devtools/client/composables/state.ts | 4 - .../client/pages/modules/overview.vue | 23 +- packages/devtools/package.json | 14 +- packages/devtools/src/npm/index.ts | 42 +- packages/devtools/src/server-rpc/npm.ts | 25 +- packages/devtools/src/server-rpc/terminal.ts | 7 + pnpm-lock.yaml | 1361 +++++++++++------ 16 files changed, 1026 insertions(+), 589 deletions(-) create mode 100644 packages/devtools/client/components/NpmVersionCheck.vue diff --git a/package.json b/package.json index 982e851039..06660e0837 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,7 @@ "test": "pnpm lint", "docs": "nuxi dev docs", "typecheck": "vue-tsc --noEmit", - "postinstall": "npx simple-git-hooks", - "prepare": "pnpm -r run dev:prepare" + "postinstall": "npx simple-git-hooks && pnpm -r run dev:prepare" }, "devDependencies": { "@antfu/eslint-config": "^0.36.0", @@ -28,7 +27,7 @@ "@types/wait-on": "^5.3.1", "@types/which": "^2.0.2", "@types/ws": "^8.5.4", - "@unocss/eslint-config": "^0.50.5", + "@unocss/eslint-config": "^0.50.6", "bumpp": "^9.0.0", "conventional-changelog-cli": "^2.2.2", "eslint": "^8.36.0", @@ -40,7 +39,7 @@ "pathe": "^1.1.0", "simple-git-hooks": "^2.8.1", "typescript": "^4.9.5", - "unocss": "^0.50.5", + "unocss": "^0.50.6", "vue-tsc": "^1.2.0" }, "simple-git-hooks": { diff --git a/packages/devtools-kit/src/_types/integrations.ts b/packages/devtools-kit/src/_types/integrations.ts index b7355e4f3a..3c36f3712c 100644 --- a/packages/devtools-kit/src/_types/integrations.ts +++ b/packages/devtools-kit/src/_types/integrations.ts @@ -18,13 +18,15 @@ export interface ImageMeta { mimeType?: string } -export interface UpdateInfo { +export interface PackageUpdateInfo { name: string current: string - latest?: string - needsUpdate?: boolean + latest: string + needsUpdate: boolean } +export type PackageManagerName = 'npm' | 'yarn' | 'pnpm' + export interface AutoImportsWithMetadata { imports: Import[] metadata?: UnimportMeta diff --git a/packages/devtools-kit/src/_types/rpc.ts b/packages/devtools-kit/src/_types/rpc.ts index 2eb5952975..f16187942e 100644 --- a/packages/devtools-kit/src/_types/rpc.ts +++ b/packages/devtools-kit/src/_types/rpc.ts @@ -3,8 +3,8 @@ import type { StorageMounts } from 'nitropack' import type { StorageValue } from 'unstorage' import type { Component } from 'vue' import type { ModuleCustomTab } from './custom-tabs' -import type { AssetInfo, AutoImportsWithMetadata, ComponentRelationship, HookInfo, ImageMeta, UpdateInfo } from './integrations' -import type { TerminalAction, TerminalInfo } from './terminals' +import type { AssetInfo, AutoImportsWithMetadata, ComponentRelationship, HookInfo, ImageMeta, PackageManagerName, PackageUpdateInfo } from './integrations' +import type { SubprocessOptions, TerminalAction, TerminalInfo, TerminalState } from './terminals' import type { GetWizardArgs, WizardActions } from './wizard' export interface ServerFunctions { @@ -18,12 +18,16 @@ export interface ServerFunctions { getServerHooks(): HookInfo[] getServerLayouts(): NuxtLayout[] getStaticAssets(): Promise - getPackageVersions(): UpdateInfo[] + + // Updates + checkForUpdateFor(name: string): Promise + getPackageManager(): Promise // Terminal getTerminals(): TerminalInfo[] getTerminalDetail(id: string): TerminalInfo | undefined runTerminalAction(id: string, action: TerminalAction): Promise + executeBashCommand(execaOptions: SubprocessOptions, tabOptions: TerminalState,): Promise // Storage getStorageMounts(): Promise diff --git a/packages/devtools-kit/src/_types/terminals.ts b/packages/devtools-kit/src/_types/terminals.ts index 0318c434d3..bff0e68d28 100644 --- a/packages/devtools-kit/src/_types/terminals.ts +++ b/packages/devtools-kit/src/_types/terminals.ts @@ -1,3 +1,5 @@ +import type { Options as ExecaOptions } from 'execa' + export interface TerminalBase { id: string name: string @@ -7,6 +9,11 @@ export interface TerminalBase { export type TerminalAction = 'restart' | 'terminate' | 'clear' +export interface SubprocessOptions extends ExecaOptions { + command: string + args?: string[] +} + export interface TerminalInfo extends TerminalBase { restartable?: boolean terminatable?: boolean diff --git a/packages/devtools-kit/src/index.ts b/packages/devtools-kit/src/index.ts index b26c50c232..a5e9fa1ec3 100644 --- a/packages/devtools-kit/src/index.ts +++ b/packages/devtools-kit/src/index.ts @@ -1,8 +1,7 @@ import { useNuxt } from '@nuxt/kit' import type { BirpcGroup } from 'birpc' -import type { Options as ExecaOptions } from 'execa' import { execa } from 'execa' -import type { ModuleCustomTab, NuxtDevtoolsServerContext, TerminalState } from './types' +import type { ModuleCustomTab, NuxtDevtoolsServerContext, SubprocessOptions, TerminalState } from './types' /** * Hooks to extend a custom tab in devtools. @@ -24,11 +23,6 @@ export function refreshCustomTabs(nuxt = useNuxt()) { return nuxt.callHook('devtools:customTabs:refresh') } -export interface SubprocessOptions extends ExecaOptions { - command: string - args?: string[] -} - /** * Create a subprocess that handled by the DevTools. */ @@ -53,6 +47,8 @@ export function startSubprocess( }, ) + nuxt.callHook('devtools:terminal:write', id, `> ${[execaOptions.command, ...execaOptions.args || []].join(' ')}\n\n`) + process.stdout!.on('data', (data) => { nuxt.callHook('devtools:terminal:write', id, data) }) @@ -60,7 +56,7 @@ export function startSubprocess( nuxt.callHook('devtools:terminal:write', id, data) }) process.on('exit', (code) => { - nuxt.callHook('devtools:terminal:write', id, `\nprocess terminalated with ${code}\n`) + nuxt.callHook('devtools:terminal:write', id, `\n> process terminalated with ${code}\n`) }) return process diff --git a/packages/devtools-ui-kit/package.json b/packages/devtools-ui-kit/package.json index f7881e6962..de7dba530a 100644 --- a/packages/devtools-ui-kit/package.json +++ b/packages/devtools-ui-kit/package.json @@ -38,18 +38,18 @@ "@nuxt/devtools-kit": "workspace:*", "@nuxt/kit": "^3.3.1", "@nuxtjs/color-mode": "^3.2.0", - "@unocss/core": "^0.50.5", - "@unocss/nuxt": "^0.50.5", - "@unocss/preset-attributify": "^0.50.5", - "@unocss/preset-icons": "^0.50.5", - "@unocss/preset-mini": "^0.50.5", - "@unocss/reset": "^0.50.5", + "@unocss/core": "^0.50.6", + "@unocss/nuxt": "^0.50.6", + "@unocss/preset-attributify": "^0.50.6", + "@unocss/preset-icons": "^0.50.6", + "@unocss/preset-mini": "^0.50.6", + "@unocss/reset": "^0.50.6", "@vueuse/core": "^9.13.0", "@vueuse/integrations": "^9.13.0", "@vueuse/nuxt": "^9.13.0", "defu": "^6.1.2", "focus-trap": "^7.4.0", - "unocss": "^0.50.5" + "unocss": "^0.50.6" }, "devDependencies": { "nuxt": "^3.3.1" diff --git a/packages/devtools/client/components/ModuleItem.vue b/packages/devtools/client/components/ModuleItem.vue index 92986d420f..fc45bb996a 100644 --- a/packages/devtools/client/components/ModuleItem.vue +++ b/packages/devtools/client/components/ModuleItem.vue @@ -36,7 +36,7 @@ const npmBase = 'https://www.npmjs.com/package/'
+ + +
+import { nanoid } from 'nanoid' +const props = defineProps<{ + packageName: string + flags?: string[] +}>() + +const info = useAsyncData(`npm:check:${props.packageName}`, () => rpc.checkForUpdateFor(props.packageName)).data +const agent = (await useAsyncData('npm:agent', () => rpc.getPackageManager())).data.value || 'npm' +const args = computed(() => [ + agent === 'yarn' ? 'add' : 'install', + `${props.packageName}@latest`, + ...props.flags || [], + '--ignore-scripts', +]) + +const router = useRouter() + +async function update() { + const command = [agent, ...args.value].join(' ') + if (!confirm(`Going to run "${command}", are you sure?`)) + return + + const id = `npm:${nanoid()}` + + await rpc.executeBashCommand({ + command: agent, + args: args.value, + }, { + id, + name: `Updating ${props.packageName}`, + icon: 'i-mdi-npm-variant-outline text-red', + }) + + router.push(`/modules/terminals?id=${encodeURIComponent(id)}`) +} + + + diff --git a/packages/devtools/client/components/TerminalView.vue b/packages/devtools/client/components/TerminalView.vue index deda969306..9ab197101b 100644 --- a/packages/devtools/client/components/TerminalView.vue +++ b/packages/devtools/client/components/TerminalView.vue @@ -33,7 +33,7 @@ onMounted(async () => { term.write(info.value.buffer) // @ts-expect-error missing hooks type - nuxt.hook('devtools:terminal:data', (id: string, data: string) => { + nuxt.hook('devtools:terminal:data', ({ id, data }) => { if (id === props.id) term.write(data) }) diff --git a/packages/devtools/client/composables/state.ts b/packages/devtools/client/composables/state.ts index bf867c79d5..e07fdec07b 100644 --- a/packages/devtools/client/composables/state.ts +++ b/packages/devtools/client/composables/state.ts @@ -37,10 +37,6 @@ export function useComponents() { ].sort((a: any, b: any) => a.pascalName.localeCompare(b.pascalName))) } -export function getPackageVersions() { - return useAsyncState('getPackageVersions', () => rpc.getPackageVersions()) -} - export function useServerPages() { return useAsyncState('getServerPages', () => rpc.getServerPages()) } diff --git a/packages/devtools/client/pages/modules/overview.vue b/packages/devtools/client/pages/modules/overview.vue index ad13421609..6203165ad9 100644 --- a/packages/devtools/client/pages/modules/overview.vue +++ b/packages/devtools/client/pages/modules/overview.vue @@ -9,14 +9,11 @@ definePageMeta({ const client = useClient() const config = useServerConfig() -const versions = getPackageVersions() const components = useComponents() const autoImports = useAutoImports() const routes = useAllRoutes() const isMacOS = getIsMacOS() -const nuxtVersion = computed(() => versions.value?.find(v => v.name === 'nuxt')) - const router = useRouter() function goIntro() { isFirstVisit.value = true @@ -44,30 +41,16 @@ function goIntro() { />
-
+
Nuxt DevTools v{{ version }}
-
+
- {{ `v${nuxtVersion.current}` }} - +