From 0599030b49d379de0ba0c7628ef38495b9c076e7 Mon Sep 17 00:00:00 2001 From: Peter Lewis Date: Fri, 7 Nov 2025 13:06:08 -0500 Subject: [PATCH 1/6] remove dependency to git-url-parse --- package.json | 3 +- pnpm-lock.yaml | 145 +++++++-- src/context.ts | 2 +- src/utils/git-url-parse.ts | 615 +++++++++++++++++++++++++++++++++++++ 4 files changed, 737 insertions(+), 28 deletions(-) create mode 100644 src/utils/git-url-parse.ts diff --git a/package.json b/package.json index dd9df51c..02e2d16e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@nuxt/telemetry", "packageManager": "pnpm@10.20.0", - "version": "2.6.6", + "version": "2.6.7", "repository": "nuxt/telemetry", "license": "MIT", "type": "module", @@ -49,7 +49,6 @@ "consola": "^3.4.2", "destr": "^2.0.5", "dotenv": "^17.2.3", - "git-url-parse": "^16.1.0", "is-docker": "^3.0.0", "ofetch": "^1.5.1", "package-manager-detector": "^1.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7016a2d1..7a44d0aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,9 +26,6 @@ importers: dotenv: specifier: ^17.2.3 version: 17.2.3 - git-url-parse: - specifier: ^16.1.0 - version: 16.1.0 is-docker: specifier: ^3.0.0 version: 3.0.0 @@ -53,7 +50,7 @@ importers: version: 1.10.0(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.23)(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) '@nuxt/module-builder': specifier: ^1.0.2 - version: 1.0.2(@nuxt/cli@3.30.0(magicast@0.3.5))(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)) + version: 1.0.2(@nuxt/cli@3.30.0(magicast@0.3.5))(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)) '@nuxt/schema': specifier: ^3.20.1 version: 3.20.1 @@ -86,13 +83,13 @@ importers: version: 5.67.1(@types/node@24.10.0)(typescript@5.9.3) nuxt: specifier: ^3.20.1 - version: 3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1) + version: 3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1) typescript: specifier: ^5.9.3 version: 5.9.3 unbuild: specifier: ^3.6.1 - version: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)) + version: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)) vitest: specifier: ^4.0.6 version: 4.0.6(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) @@ -5069,6 +5066,14 @@ snapshots: '@nuxt/devalue@2.0.2': {} + '@nuxt/devtools-kit@3.0.1(magicast@0.5.1)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))': + dependencies: + '@nuxt/kit': 4.2.0(magicast@0.5.1) + execa: 8.0.1 + vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) + transitivePeerDependencies: + - magicast + '@nuxt/devtools-kit@3.0.1(magicast@0.5.1)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))': dependencies: '@nuxt/kit': 4.2.0(magicast@0.5.1) @@ -5088,6 +5093,47 @@ snapshots: prompts: 2.4.2 semver: 7.7.3 + '@nuxt/devtools@3.0.1(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3))': + dependencies: + '@nuxt/devtools-kit': 3.0.1(magicast@0.5.1)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) + '@nuxt/devtools-wizard': 3.0.1 + '@nuxt/kit': 4.2.0(magicast@0.5.1) + '@vue/devtools-core': 7.7.7(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3)) + '@vue/devtools-kit': 7.7.7 + birpc: 2.7.0 + consola: 3.4.2 + destr: 2.0.5 + error-stack-parser-es: 1.0.5 + execa: 8.0.1 + fast-npm-meta: 0.4.7 + get-port-please: 3.2.0 + hookable: 5.5.3 + image-meta: 0.2.2 + is-installed-globally: 1.0.0 + launch-editor: 2.12.0 + local-pkg: 1.1.2 + magicast: 0.5.1 + nypm: 0.6.2 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.0.0 + pkg-types: 2.3.0 + semver: 7.7.3 + simple-git: 3.30.0 + sirv: 3.0.2 + structured-clone-es: 1.0.0 + tinyglobby: 0.2.15 + vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) + vite-plugin-inspect: 11.3.3(@nuxt/kit@4.2.0(magicast@0.5.1))(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) + vite-plugin-vue-tracer: 1.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3)) + which: 5.0.0 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + - vue + '@nuxt/devtools@3.0.1(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3))': dependencies: '@nuxt/devtools-kit': 3.0.1(magicast@0.5.1)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) @@ -5271,7 +5317,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/module-builder@1.0.2(@nuxt/cli@3.30.0(magicast@0.3.5))(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3))': + '@nuxt/module-builder@1.0.2(@nuxt/cli@3.30.0(magicast@0.3.5))(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3))': dependencies: '@nuxt/cli': 3.30.0(magicast@0.3.5) citty: 0.1.6 @@ -5279,14 +5325,14 @@ snapshots: defu: 6.1.4 jiti: 2.6.1 magic-regexp: 0.10.0 - mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)) + mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)) mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 tsconfck: 3.1.6(typescript@5.9.3) typescript: 5.9.3 - unbuild: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)) - vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)) + unbuild: 3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)) + vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)) transitivePeerDependencies: - '@vue/compiler-core' - esbuild @@ -5294,7 +5340,7 @@ snapshots: - vue - vue-tsc - '@nuxt/nitro-server@3.20.1(db0@0.3.4)(ioredis@5.8.2)(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(typescript@5.9.3)': + '@nuxt/nitro-server@3.20.1(db0@0.3.4)(ioredis@5.8.2)(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(typescript@5.9.3)': dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/kit': 3.20.1(magicast@0.3.5) @@ -5312,7 +5358,7 @@ snapshots: klona: 2.0.6 mocked-exports: 0.1.1 nitropack: 2.12.9 - nuxt: 3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1) + nuxt: 3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1) pathe: 2.0.3 pkg-types: 2.3.0 radix3: 1.1.2 @@ -5462,7 +5508,7 @@ snapshots: - magicast - typescript - '@nuxt/vite-builder@3.20.1(@types/node@24.10.0)(eslint@9.39.1(jiti@2.6.1))(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3))(yaml@2.8.1)': + '@nuxt/vite-builder@3.20.1(@types/node@24.10.0)(eslint@9.39.1(jiti@2.6.1))(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3))(yaml@2.8.1)': dependencies: '@nuxt/kit': 3.20.1(magicast@0.3.5) '@rollup/plugin-replace': 6.0.3(rollup@4.52.5) @@ -5483,7 +5529,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.0 mocked-exports: 0.1.1 - nuxt: 3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1) + nuxt: 3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1) ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 2.0.0 @@ -6441,6 +6487,18 @@ snapshots: '@vue/devtools-api@6.6.4': {} + '@vue/devtools-core@7.7.7(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3))': + dependencies: + '@vue/devtools-kit': 7.7.7 + '@vue/devtools-shared': 7.7.7 + mitt: 3.0.1 + nanoid: 5.1.6 + pathe: 2.0.3 + vite-hot-client: 2.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) + vue: 3.5.23(typescript@5.9.3) + transitivePeerDependencies: + - vite + '@vue/devtools-core@7.7.7(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3))': dependencies: '@vue/devtools-kit': 7.7.7 @@ -7877,7 +7935,7 @@ snapshots: mitt@3.0.1: {} - mkdist@2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)): + mkdist@2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)): dependencies: autoprefixer: 10.4.21(postcss@8.5.6) citty: 0.1.6 @@ -7894,8 +7952,8 @@ snapshots: tinyglobby: 0.2.15 optionalDependencies: typescript: 5.9.3 - vue: 3.5.23(typescript@5.9.3) - vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)) + vue: 3.5.22(typescript@5.9.3) + vue-sfc-transformer: 0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)) vue-tsc: 3.1.3(typescript@5.9.3) mlly@1.8.0: @@ -8072,16 +8130,16 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1): + nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1): dependencies: '@dxup/nuxt': 0.2.1(magicast@0.3.5) '@nuxt/cli': 3.30.0(magicast@0.3.5) - '@nuxt/devtools': 3.0.1(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3)) + '@nuxt/devtools': 3.0.1(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3)) '@nuxt/kit': 3.20.1(magicast@0.3.5) - '@nuxt/nitro-server': 3.20.1(db0@0.3.4)(ioredis@5.8.2)(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(typescript@5.9.3) + '@nuxt/nitro-server': 3.20.1(db0@0.3.4)(ioredis@5.8.2)(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(typescript@5.9.3) '@nuxt/schema': 3.20.1 '@nuxt/telemetry': 'link:' - '@nuxt/vite-builder': 3.20.1(@types/node@24.10.0)(eslint@9.39.1(jiti@2.6.1))(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3))(yaml@2.8.1) + '@nuxt/vite-builder': 3.20.1(@types/node@24.10.0)(eslint@9.39.1(jiti@2.6.1))(magicast@0.3.5)(nuxt@3.20.1(@parcel/watcher@2.5.1)(@types/node@24.10.0)(@vue/compiler-sfc@3.5.23)(db0@0.3.4)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.8.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue-tsc@3.1.3(typescript@5.9.3))(yaml@2.8.1))(optionator@0.9.4)(rollup@4.52.5)(terser@5.44.0)(typescript@5.9.3)(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3))(yaml@2.8.1) '@unhead/vue': 2.0.19(vue@3.5.23(typescript@5.9.3)) '@vue/shared': 3.5.23 c12: 3.3.1(magicast@0.3.5) @@ -9192,7 +9250,7 @@ snapshots: ultrahtml@1.6.0: {} - unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)): + unbuild@3.6.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@4.52.5) '@rollup/plugin-commonjs': 28.0.9(rollup@4.52.5) @@ -9208,7 +9266,7 @@ snapshots: hookable: 5.5.3 jiti: 2.6.1 magic-string: 0.30.21 - mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.23(typescript@5.9.3)) + mkdist: 2.4.1(typescript@5.9.3)(vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)))(vue-tsc@3.1.3(typescript@5.9.3))(vue@3.5.22(typescript@5.9.3)) mlly: 1.8.0 pathe: 2.0.3 pkg-types: 2.3.0 @@ -9391,12 +9449,22 @@ snapshots: version-guard@1.1.3: {} + vite-dev-rpc@1.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)): + dependencies: + birpc: 2.7.0 + vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) + vite-hot-client: 2.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) + vite-dev-rpc@1.1.0(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)): dependencies: birpc: 2.7.0 vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) vite-hot-client: 2.1.0(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) + vite-hot-client@2.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)): + dependencies: + vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) + vite-hot-client@2.1.0(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)): dependencies: vite: 7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) @@ -9439,6 +9507,23 @@ snapshots: typescript: 5.9.3 vue-tsc: 3.1.3(typescript@5.9.3) + vite-plugin-inspect@11.3.3(@nuxt/kit@4.2.0(magicast@0.5.1))(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)): + dependencies: + ansis: 4.2.0 + debug: 4.4.3 + error-stack-parser-es: 1.0.5 + ohash: 2.0.11 + open: 10.2.0 + perfect-debounce: 2.0.0 + sirv: 3.0.2 + unplugin-utils: 0.3.1 + vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) + vite-dev-rpc: 1.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) + optionalDependencies: + '@nuxt/kit': 4.2.0(magicast@0.5.1) + transitivePeerDependencies: + - supports-color + vite-plugin-inspect@11.3.3(@nuxt/kit@4.2.0(magicast@0.5.1))(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)): dependencies: ansis: 4.2.0 @@ -9456,6 +9541,16 @@ snapshots: transitivePeerDependencies: - supports-color + vite-plugin-vue-tracer@1.1.0(vite@7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3)): + dependencies: + estree-walker: 3.0.3 + exsolve: 1.0.7 + magic-string: 0.30.21 + pathe: 2.0.3 + source-map-js: 1.2.1 + vite: 7.1.12(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1) + vue: 3.5.23(typescript@5.9.3) + vite-plugin-vue-tracer@1.1.0(vite@7.2.1(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.23(typescript@5.9.3)): dependencies: estree-walker: 3.0.3 @@ -9576,12 +9671,12 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.23(typescript@5.9.3) - vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.23(typescript@5.9.3)): + vue-sfc-transformer@0.1.17(@vue/compiler-core@3.5.23)(esbuild@0.25.12)(vue@3.5.22(typescript@5.9.3)): dependencies: '@babel/parser': 7.28.5 '@vue/compiler-core': 3.5.23 esbuild: 0.25.12 - vue: 3.5.23(typescript@5.9.3) + vue: 3.5.22(typescript@5.9.3) vue-tsc@3.1.3(typescript@5.9.3): dependencies: diff --git a/src/context.ts b/src/context.ts index afed8824..9aed7a47 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,6 +1,5 @@ import os from 'node:os' import { execSync } from 'node:child_process' -import gitUrlParse from 'git-url-parse' import { getNuxtVersion, isNuxt3 } from '@nuxt/kit' import isDocker from 'is-docker' import { provider } from 'std-env' @@ -8,6 +7,7 @@ import type { Nuxt } from '@nuxt/schema' import { detect } from 'package-manager-detector' import type { Context, GitData, TelemetryOptions } from './types' import { hash } from './utils/hash' +import gitUrlParse from './utils/git-url-parse' export async function createContext(nuxt: Nuxt, options: Required): Promise { const rootDir = nuxt.options.rootDir || process.cwd() diff --git a/src/utils/git-url-parse.ts b/src/utils/git-url-parse.ts new file mode 100644 index 00000000..51ec3726 --- /dev/null +++ b/src/utils/git-url-parse.ts @@ -0,0 +1,615 @@ +/* +This is a fork of the original git-url-parse package (https://github.com/IonicaBizau/git-url-parse). +This has been migrated to be included in the package to avoid the dependency on the original package. +*/ + +/** + * protocols + * Returns the protocols of an input url. + * + * @param input The input url (string or `URL` instance) + * @param first If `true`, the first protocol will be returned. If number, it will represent the zero-based index of the protocols array. + * @return The array of protocols or the specified protocol. + */ +function protocols(input: string | URL, first?: boolean | number): string[] | string { + if (first === true) { + first = 0 + } + + let prots = '' + if (typeof input === 'string') { + try { + prots = new URL(input).protocol + } + catch (e) { + // ignore + } + } + else if (input && input.constructor === URL) { + prots = input.protocol + } + + const splits = prots.split(/[:+]/).filter(Boolean) + if (typeof first === 'number') { + return splits[first] + } + return splits +} + +/** + * isSsh + * Checks if an input value is a ssh url or not. + * + * @param input The input url or an array of protocols. + * @return `true` if the input is a ssh url, `false` otherwise. + */ +function isSsh(input: string | string[]): boolean { + if (Array.isArray(input)) { + return input.includes('ssh') || input.includes('rsync') + } + + if (typeof input !== 'string') { + return false + } + + const prots = protocols(input) as string[] + input = input.substring(input.indexOf('://') + 3) + if (isSsh(prots)) { + return true + } + + // TODO This probably could be improved :) + const urlPortPattern = /\.([a-zA-Z\d]+):(\d+)\// + return !input.match(urlPortPattern) && input.indexOf('@') < input.indexOf(':') +} + +interface ParsePathOutput { + protocols: string[] + protocol: string | null + port: string | null + resource: string + host: string + user: string + password: string + pathname: string + hash: string + search: string + href: string + query: Record + parse_failed: boolean +} + +/** + * parsePath + * Parses the input url. + * + * @param url The input url. + * @return An object containing the parsed url fields. + */ +function parsePath(url: string): ParsePathOutput { + const output: ParsePathOutput = { + protocols: [], + protocol: null, + port: null, + resource: '', + host: '', + user: '', + password: '', + pathname: '', + hash: '', + search: '', + href: url, + query: {}, + parse_failed: false, + } + + try { + const parsed = new URL(url) + + output.protocols = protocols(parsed) as string[] + output.protocol = output.protocols[0] + output.port = parsed.port + output.resource = parsed.hostname + output.host = parsed.host + output.user = parsed.username || '' + output.password = parsed.password || '' + output.pathname = parsed.pathname + output.hash = parsed.hash.slice(1) + output.search = parsed.search.slice(1) + output.href = parsed.href + output.query = Object.fromEntries(parsed.searchParams) + } + catch (e) { + // TODO Maybe check if it is a valid local file path + // In any case, these will be parsed by higher + // level parsers such as parse-url, git-url-parse, git-up + output.protocols = ['file'] + output.protocol = output.protocols[0] + output.port = '' + output.resource = '' + output.user = '' + output.pathname = '' + output.hash = '' + output.search = '' + output.href = url + output.query = {} + output.parse_failed = true + } + + return output +} + +/** + * Normalize URL options + */ +interface NormalizeOptions { + stripHash?: boolean + [key: string]: any +} + +/** + * parseUrl + * Parses the input url. + * + * **Note**: This *throws* if invalid urls are provided. + * + * @param url The input url. + * @param normalize Whether to normalize the url or not. + * Default is `false`. If `true`, the url will be normalized. If an object, + * it will be the options object sent to normalize-url. For SSH urls, normalize won't work. + * + * @return An object containing the parsed url fields. + */ +function parseUrl(url: string, normalize: boolean | NormalizeOptions = false): ParsePathOutput { + // Constants + /** + * ([a-zA-Z_][a-zA-Z0-9_-]{0,31}) Try to match the user + * ([\w\.\-@]+) Match the host/resource + * (([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?) Match the path, allowing spaces/white + */ + const GIT_RE = /^(?:([a-zA-Z_][a-zA-Z0-9_-]{0,31})@|https?:\/\/)([\w.\-@]+)[/:](([~,.\w,\-,_,/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/ + + const throwErr = (msg: string) => { + const err = new TypeError(msg) as TypeError & { subject_url?: string } + err.subject_url = url + throw err + } + + if (typeof url !== 'string' || !url.trim()) { + throwErr('Invalid url.') + } + + if (url.length > parseUrl.MAX_INPUT_LENGTH) { + throwErr('Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.') + } + + if (normalize) { + // Dynamic import for normalize-url to avoid requiring it if not needed + // For now, we'll skip normalization if normalize-url is not available + // In a real implementation, you'd want to add normalize-url as a dependency + if (typeof normalize !== 'object') { + normalize = { + stripHash: false, + } + } + // Note: normalize-url would be used here, but we'll skip for now + // url = normalizeUrl(url, normalize) + } + + const parsed = parsePath(url) + + // Potential git-ssh urls + if (parsed.parse_failed) { + const matched = parsed.href.match(GIT_RE) + if (matched) { + parsed.protocols = ['ssh'] + parsed.protocol = 'ssh' + parsed.resource = matched[2] + parsed.host = matched[2] + parsed.user = matched[1] || '' + parsed.pathname = `/${matched[3]}` + parsed.parse_failed = false + } + else { + throwErr('URL parsing failed.') + } + } + + return parsed +} + +parseUrl.MAX_INPUT_LENGTH = 2048 + +interface GitUpOutput extends ParsePathOutput { + token: string +} + +/** + * gitUp + * Parses the input url. + * + * @param input The input url. + * @return An object containing the parsed git url fields. + */ +function gitUp(input: string): GitUpOutput { + const output = parseUrl(input) as GitUpOutput + + output.token = '' + if (output.password === 'x-oauth-basic') { + output.token = output.user + } + else if (output.user === 'x-token-auth') { + output.token = output.password + } + + if (isSsh(output.protocols) || (output.protocols.length === 0 && isSsh(input))) { + output.protocol = 'ssh' + } + else if (output.protocols.length) { + output.protocol = output.protocols[0] + } + else { + output.protocol = 'file' + output.protocols = ['file'] + } + + output.href = output.href.replace(/\/$/, '') + return output +} + +export interface GitUrl extends GitUpOutput { + source: string + owner: string + name: string + ref: string + filepath: string + filepathtype: string + full_name: string + organization?: string + git_suffix: boolean + commit?: string + toString: (type?: string) => string +} + +/** + * gitUrlParse + * Parses a Git url. + * + * @param url The Git url to parse. + * @param refs An array of strings representing the refs. This is + * helpful in the context of the URLs that contain branches with slashes. + * If user wants to identify the branch, he should pass all branch names + * of the project as part of refs parameter + * @return The `GitUrl` object containing parsed git url information. + */ +function gitUrlParse(url: string, refs: string[] = []): GitUrl { + if (typeof url !== 'string') { + throw new TypeError('The url must be a string.') + } + + if (!refs.every(item => typeof item === 'string')) { + throw new TypeError('The refs should contain only strings') + } + + const shorthandRe = /^([a-z\d-]{1,39})\/([-.\w]{1,100})$/i + if (shorthandRe.test(url)) { + url = `https://github.com/${url}` + } + + const urlInfo = gitUp(url) as GitUrl + const sourceParts = urlInfo.resource.split('.') + let splits: string[] | null = null + + urlInfo.toString = function (type?: string) { + return gitUrlParse.stringify(this, type) + } + + urlInfo.source = sourceParts.length > 2 + ? sourceParts.slice(1 - sourceParts.length).join('.') + : (urlInfo.source = urlInfo.resource) + + // Note: Some hosting services (e.g. Visual Studio Team Services) allow whitespace characters + // in the repository and owner names so we decode the URL pieces to get the correct result + urlInfo.git_suffix = /\.git$/.test(urlInfo.pathname) + urlInfo.name = decodeURIComponent((urlInfo.pathname || urlInfo.href).replace(/(^\/)|(\/$)/g, '').replace(/\.git$/, '')) + urlInfo.owner = decodeURIComponent(urlInfo.user) + + switch (urlInfo.source) { + case 'git.cloudforge.com': { + urlInfo.owner = urlInfo.user + urlInfo.organization = sourceParts[0] + urlInfo.source = 'cloudforge.com' + break + } + + case 'visualstudio.com': { + // Handle VSTS SSH URLs + if (urlInfo.resource === 'vs-ssh.visualstudio.com') { + splits = urlInfo.name.split('/') + if (splits.length === 4) { + urlInfo.organization = splits[1] + urlInfo.owner = splits[2] + urlInfo.name = splits[3] + urlInfo.full_name = `${splits[2]}/${splits[3]}` + } + break + } + else { + splits = urlInfo.name.split('/') + if (splits.length === 2) { + urlInfo.owner = splits[1] + urlInfo.name = splits[1] + urlInfo.full_name = `_git/${urlInfo.name}` + } + else if (splits.length === 3) { + urlInfo.name = splits[2] + if (splits[0] === 'DefaultCollection') { + urlInfo.owner = splits[2] + urlInfo.organization = splits[0] + urlInfo.full_name = `${urlInfo.organization}/_git/${urlInfo.name}` + } + else { + urlInfo.owner = splits[0] + urlInfo.full_name = `${urlInfo.owner}/_git/${urlInfo.name}` + } + } + else if (splits.length === 4) { + urlInfo.organization = splits[0] + urlInfo.owner = splits[1] + urlInfo.name = splits[3] + urlInfo.full_name = `${urlInfo.organization}/${urlInfo.owner}/_git/${urlInfo.name}` + } + break + } + } + + // Azure DevOps (formerly Visual Studio Team Services) + case 'dev.azure.com': + case 'azure.com': { + if (urlInfo.resource === 'ssh.dev.azure.com') { + splits = urlInfo.name.split('/') + if (splits.length === 4) { + urlInfo.organization = splits[1] + urlInfo.owner = splits[2] + urlInfo.name = splits[3] + } + break + } + else { + splits = urlInfo.name.split('/') + if (splits.length === 5) { + urlInfo.organization = splits[0] + urlInfo.owner = splits[1] + urlInfo.name = splits[4] + urlInfo.full_name = `_git/${urlInfo.name}` + } + else if (splits.length === 3) { + urlInfo.name = splits[2] + if (splits[0] === 'DefaultCollection') { + urlInfo.owner = splits[2] + urlInfo.organization = splits[0] + urlInfo.full_name = `${urlInfo.organization}/_git/${urlInfo.name}` + } + else { + urlInfo.owner = splits[0] + urlInfo.full_name = `${urlInfo.owner}/_git/${urlInfo.name}` + } + } + else if (splits.length === 4) { + urlInfo.organization = splits[0] + urlInfo.owner = splits[1] + urlInfo.name = splits[3] + urlInfo.full_name = `${urlInfo.organization}/${urlInfo.owner}/_git/${urlInfo.name}` + } + + if (urlInfo.query && urlInfo.query.path) { + urlInfo.filepath = urlInfo.query.path.replace(/^\/+/g, '') // Strip leading slash (/) + } + if (urlInfo.query && urlInfo.query.version) { // version=GB + urlInfo.ref = urlInfo.query.version.replace(/^GB/, '') // remove GB + } + break + } + } + + default: { + splits = urlInfo.name.split('/') + let nameIndex = splits.length - 1 + if (splits.length >= 2) { + const dashIndex = splits.indexOf('-', 2) + const blobIndex = splits.indexOf('blob', 2) + const treeIndex = splits.indexOf('tree', 2) + const commitIndex = splits.indexOf('commit', 2) + const issuesIndex = splits.indexOf('issues', 2) + const srcIndex = splits.indexOf('src', 2) + const rawIndex = splits.indexOf('raw', 2) + const editIndex = splits.indexOf('edit', 2) + nameIndex = dashIndex > 0 + ? dashIndex - 1 + : blobIndex > 0 && treeIndex > 0 + ? Math.min(blobIndex - 1, treeIndex - 1) + : blobIndex > 0 + ? blobIndex - 1 + : issuesIndex > 0 + ? issuesIndex - 1 + : treeIndex > 0 + ? treeIndex - 1 + : commitIndex > 0 + ? commitIndex - 1 + : srcIndex > 0 + ? srcIndex - 1 + : rawIndex > 0 + ? rawIndex - 1 + : editIndex > 0 + ? editIndex - 1 + : nameIndex + urlInfo.owner = splits.slice(0, nameIndex).join('/') + urlInfo.name = splits[nameIndex] + if (commitIndex && issuesIndex < 0) { + urlInfo.commit = splits[nameIndex + 2] + } + } + urlInfo.ref = '' + urlInfo.filepathtype = '' + urlInfo.filepath = '' + const offsetNameIndex = splits.length > nameIndex && splits[nameIndex + 1] === '-' ? nameIndex + 1 : nameIndex + if ((splits.length > offsetNameIndex + 2) && (['raw', 'src', 'blob', 'tree', 'edit'].includes(splits[offsetNameIndex + 1]))) { + urlInfo.filepathtype = splits[offsetNameIndex + 1] + urlInfo.ref = splits[offsetNameIndex + 2] + if (splits.length > offsetNameIndex + 3) { + urlInfo.filepath = splits.slice(offsetNameIndex + 3).join('/') + } + } + urlInfo.organization = urlInfo.owner + break + } + } + + if (!urlInfo.full_name) { + urlInfo.full_name = urlInfo.owner + if (urlInfo.name) { + urlInfo.full_name && (urlInfo.full_name += '/') + urlInfo.full_name += urlInfo.name + } + } + + // Bitbucket Server + if (urlInfo.owner.startsWith('scm/')) { + urlInfo.source = 'bitbucket-server' + urlInfo.owner = urlInfo.owner.replace('scm/', '') + urlInfo.organization = urlInfo.owner + urlInfo.full_name = `${urlInfo.owner}/${urlInfo.name}` + } + + const bitbucket = /(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/ + const matches = bitbucket.exec(urlInfo.pathname) + if (matches != null) { + urlInfo.source = 'bitbucket-server' + if (matches[1] === 'users') { + urlInfo.owner = `~${matches[2]}` + } + else { + urlInfo.owner = matches[2] + } + urlInfo.organization = urlInfo.owner + urlInfo.name = matches[3] + splits = matches[4].split('/') + if (splits.length > 1) { + if (['raw', 'browse'].includes(splits[1])) { + urlInfo.filepathtype = splits[1] + if (splits.length > 2) { + urlInfo.filepath = splits.slice(2).join('/') + } + } + else if (splits[1] === 'commits' && splits.length > 2) { + urlInfo.commit = splits[2] + } + } + urlInfo.full_name = `${urlInfo.owner}/${urlInfo.name}` + if (urlInfo.query.at) { + urlInfo.ref = urlInfo.query.at + } + else { + urlInfo.ref = '' + } + } + + if (refs.length !== 0 && urlInfo.ref) { + urlInfo.ref = findLongestMatchingSubstring(urlInfo.href, refs) || urlInfo.ref + urlInfo.filepath = urlInfo.href.split(`${urlInfo.ref}/`)[1] + } + + return urlInfo +} + +/** + * stringify + * Stringifies a `GitUrl` object. + * + * @param obj The parsed Git url object. + * @param type The type of the stringified url (default `obj.protocol`). + * @return The stringified url. + */ +gitUrlParse.stringify = function (obj: GitUrl, type?: string): string { + type = type || ((obj.protocols && obj.protocols.length) ? obj.protocols.join('+') : obj.protocol || '') + + const port = obj.port ? `:${obj.port}` : '' + const user = obj.user || 'git' + const maybeGitSuffix = obj.git_suffix ? '.git' : '' + + switch (type) { + case 'ssh': { + if (port) + return `ssh://${user}@${obj.resource}${port}/${obj.full_name}${maybeGitSuffix}` + else + return `${user}@${obj.resource}:${obj.full_name}${maybeGitSuffix}` + } + + case 'git+ssh': + case 'ssh+git': + case 'ftp': + case 'ftps': { + return `${type}://${user}@${obj.resource}${port}/${obj.full_name}${maybeGitSuffix}` + } + + case 'http': + case 'https': { + const auth = obj.token + ? buildToken(obj) + : obj.user && (obj.protocols.includes('http') || obj.protocols.includes('https')) + ? `${obj.user}@` + : '' + return `${type}://${auth}${obj.resource}${port}/${buildPath(obj)}${maybeGitSuffix}` + } + + default: { + return obj.href + } + } +} + +/** + * buildToken + * Builds OAuth token prefix (helper function) + * + * @param obj The parsed Git url object. + * @return token prefix + */ +function buildToken(obj: GitUrl): string { + switch (obj.source) { + case 'bitbucket.org': { + return `x-token-auth:${obj.token}@` + } + default: { + return `${obj.token}@` + } + } +} + +function buildPath(obj: GitUrl): string { + switch (obj.source) { + case 'bitbucket-server': { + return `scm/${obj.full_name}` + } + default: { + // Note: Re-encode the repository and owner names for hosting services that allow whitespace characters + const encoded_full_name = obj.full_name + .split('/') + .map(x => encodeURIComponent(x)) + .join('/') + return encoded_full_name + } + } +} + +function findLongestMatchingSubstring(string: string, array: string[]): string { + let longestMatch = '' + array.forEach((item) => { + if (string.includes(item) && item.length > longestMatch.length) { + longestMatch = item + } + }) + return longestMatch +} + +export default gitUrlParse From 14fa304160664671df0a323ee0a8ee6b9b1fcad2 Mon Sep 17 00:00:00 2001 From: Peter Lewis Date: Fri, 7 Nov 2025 13:06:08 -0500 Subject: [PATCH 2/6] fix: remove dependency to git-url-parse --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 02e2d16e..d7fe54c5 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "@nuxt/module-builder": "^1.0.2", "@nuxt/schema": "^3.20.1", "@nuxt/test-utils": "^3.20.1", - "@types/git-url-parse": "^16.0.2", "@vitest/coverage-v8": "^4.0.6", "changelogen": "^0.6.2", "eslint": "^9.39.1", From 9165951c8b3dcfb1e772f75ae316057619689455 Mon Sep 17 00:00:00 2001 From: Peter Lewis Date: Fri, 7 Nov 2025 13:06:08 -0500 Subject: [PATCH 3/6] fix: remove dependency to git-url-parse --- pnpm-lock.yaml | 62 -------------------------------------------------- 1 file changed, 62 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a44d0aa..b509f7dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,9 +57,6 @@ importers: '@nuxt/test-utils': specifier: ^3.20.1 version: 3.20.1(magicast@0.3.5)(typescript@5.9.3)(vitest@4.0.6(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) - '@types/git-url-parse': - specifier: ^16.0.2 - version: 16.0.2 '@vitest/coverage-v8': specifier: ^4.0.6 version: 4.0.6(vitest@4.0.6(@types/node@24.10.0)(jiti@2.6.1)(terser@5.44.0)(yaml@2.8.1)) @@ -1375,10 +1372,6 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/git-url-parse@16.0.2': - resolution: {integrity: sha512-STa+QaJtPbqwtioDIncRyft1xXrsTIYW0KkS6RS6l++NiDaQxqgsIkNp2Jf9nJ1KnCGPOvWaR1iO+B7LkM8+ew==} - deprecated: This is a stub types definition. git-url-parse provides its own type definitions, so you do not need this installed. - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -1388,10 +1381,6 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/parse-path@7.1.0': - resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} - deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. - '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -2567,12 +2556,6 @@ packages: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true - git-up@8.1.1: - resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} - - git-url-parse@16.1.0: - resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2767,9 +2750,6 @@ packages: is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - is-ssh@1.4.1: - resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} - is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -3274,16 +3254,9 @@ packages: resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} engines: {node: '>=18'} - parse-path@7.1.0: - resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} - parse-statements@1.0.11: resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} - parse-url@9.2.0: - resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} - engines: {node: '>=14.13.0'} - parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -3553,9 +3526,6 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} - protocols@2.0.2: - resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -6095,10 +6065,6 @@ snapshots: '@types/estree@1.0.8': {} - '@types/git-url-parse@16.0.2': - dependencies: - git-url-parse: 16.1.0 - '@types/json-schema@7.0.15': {} '@types/node@24.10.0': @@ -6107,10 +6073,6 @@ snapshots: '@types/normalize-package-data@2.4.4': {} - '@types/parse-path@7.1.0': - dependencies: - parse-path: 7.1.0 - '@types/resolve@1.20.2': {} '@typescript-eslint/eslint-plugin@8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': @@ -7457,15 +7419,6 @@ snapshots: nypm: 0.6.2 pathe: 2.0.3 - git-up@8.1.1: - dependencies: - is-ssh: 1.4.1 - parse-url: 9.2.0 - - git-url-parse@16.1.0: - dependencies: - git-up: 8.1.1 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -7664,10 +7617,6 @@ snapshots: dependencies: '@types/estree': 1.0.8 - is-ssh@1.4.1: - dependencies: - protocols: 2.0.2 - is-stream@2.0.1: {} is-stream@3.0.0: {} @@ -8531,17 +8480,8 @@ snapshots: index-to-position: 1.2.0 type-fest: 4.41.0 - parse-path@7.1.0: - dependencies: - protocols: 2.0.2 - parse-statements@1.0.11: {} - parse-url@9.2.0: - dependencies: - '@types/parse-path': 7.1.0 - parse-path: 7.1.0 - parseurl@1.3.3: {} path-browserify@1.0.1: {} @@ -8776,8 +8716,6 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 - protocols@2.0.2: {} - punycode@2.3.1: {} quansync@0.2.11: {} From 92cfe69e22f7d8b90c9cc124994be4fc3f137618 Mon Sep 17 00:00:00 2001 From: Peter Lewis Date: Fri, 7 Nov 2025 13:06:08 -0500 Subject: [PATCH 4/6] fix: remove dependency to git-url-parse --- src/utils/git-url-parse.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/utils/git-url-parse.ts b/src/utils/git-url-parse.ts index 51ec3726..f606a4d4 100644 --- a/src/utils/git-url-parse.ts +++ b/src/utils/git-url-parse.ts @@ -21,7 +21,7 @@ function protocols(input: string | URL, first?: boolean | number): string[] | st try { prots = new URL(input).protocol } - catch (e) { + catch { // ignore } } @@ -59,7 +59,7 @@ function isSsh(input: string | string[]): boolean { } // TODO This probably could be improved :) - const urlPortPattern = /\.([a-zA-Z\d]+):(\d+)\// + const urlPortPattern = /\.([a-z\d]+):(\d+)\//i return !input.match(urlPortPattern) && input.indexOf('@') < input.indexOf(':') } @@ -119,7 +119,7 @@ function parsePath(url: string): ParsePathOutput { output.href = parsed.href output.query = Object.fromEntries(parsed.searchParams) } - catch (e) { + catch { // TODO Maybe check if it is a valid local file path // In any case, these will be parsed by higher // level parsers such as parse-url, git-url-parse, git-up @@ -167,7 +167,7 @@ function parseUrl(url: string, normalize: boolean | NormalizeOptions = false): P * ([\w\.\-@]+) Match the host/resource * (([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?) Match the path, allowing spaces/white */ - const GIT_RE = /^(?:([a-zA-Z_][a-zA-Z0-9_-]{0,31})@|https?:\/\/)([\w.\-@]+)[/:](([~,.\w,\-,_,/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/ + const GIT_RE = /^(?:([a-zA-Z_][\w-]{0,31})@|https?:\/\/)([\w.\-@]+)[/:](([~,.\w\-/\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/ const throwErr = (msg: string) => { const err = new TypeError(msg) as TypeError & { subject_url?: string } @@ -291,7 +291,7 @@ function gitUrlParse(url: string, refs: string[] = []): GitUrl { throw new TypeError('The refs should contain only strings') } - const shorthandRe = /^([a-z\d-]{1,39})\/([-.\w]{1,100})$/i + const shorthandRe = /^[\w-]{1,39}\/[-.\w]{1,100}$/ if (shorthandRe.test(url)) { url = `https://github.com/${url}` } @@ -468,7 +468,9 @@ function gitUrlParse(url: string, refs: string[] = []): GitUrl { if (!urlInfo.full_name) { urlInfo.full_name = urlInfo.owner if (urlInfo.name) { - urlInfo.full_name && (urlInfo.full_name += '/') + if (urlInfo.full_name) { + urlInfo.full_name += '/' + } urlInfo.full_name += urlInfo.name } } @@ -481,7 +483,7 @@ function gitUrlParse(url: string, refs: string[] = []): GitUrl { urlInfo.full_name = `${urlInfo.owner}/${urlInfo.name}` } - const bitbucket = /(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/ + const bitbucket = /(projects|users)\/([^/]+)\/repos\/([^/]+)((\/.*$)|$)/ const matches = bitbucket.exec(urlInfo.pathname) if (matches != null) { urlInfo.source = 'bitbucket-server' From db66558a143b8ea4539e493b015b48ec5e450304 Mon Sep 17 00:00:00 2001 From: Peter Lewis Date: Fri, 7 Nov 2025 13:06:08 -0500 Subject: [PATCH 5/6] fix: remove dependency to git-url-parse --- src/utils/git-url-parse.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/git-url-parse.ts b/src/utils/git-url-parse.ts index f606a4d4..409ba6ea 100644 --- a/src/utils/git-url-parse.ts +++ b/src/utils/git-url-parse.ts @@ -257,7 +257,7 @@ function gitUp(input: string): GitUpOutput { return output } -export interface GitUrl extends GitUpOutput { +interface GitUrl extends GitUpOutput { source: string owner: string name: string From 79cd3c3812596c9bc7b26150b258a0f6784caab6 Mon Sep 17 00:00:00 2001 From: Peter Lewis Date: Fri, 7 Nov 2025 13:06:08 -0500 Subject: [PATCH 6/6] fix: remove dependency to git-url-parse --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7fe54c5..a1ba1968 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@nuxt/telemetry", "packageManager": "pnpm@10.20.0", - "version": "2.6.7", + "version": "2.6.6", "repository": "nuxt/telemetry", "license": "MIT", "type": "module",