Skip to content

Commit 61432b3

Browse files
committed
moved license change logic to server side, to an api, changed nested translation to simpler, removed version number from change record as it is not necessary for current/last version check
1 parent a5b4e09 commit 61432b3

File tree

6 files changed

+119
-99
lines changed

6 files changed

+119
-99
lines changed

app/components/LicenseChangeWarning.vue

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,16 @@ const props = defineProps<{
77
resolvedVersion: string | null | undefined
88
}>()
99
10-
const licenseChanges = useLicenseChanges(
10+
const { data: licenseData } = useLicenseChanges(
1111
() => props.packageName,
1212
() => props.resolvedVersion,
1313
)
14-
15-
const changes = computed(() => licenseChanges.data.value?.changes ?? [])
16-
17-
const licenseChangeText = computed(() =>
18-
changes.value
19-
.map(item =>
20-
$t('package.versions.license_change_item', {
21-
from: item.from,
22-
to: item.to,
23-
version: item.version,
24-
}),
25-
)
26-
.join('; '),
27-
)
14+
const licenseChangeRecord = computed(() => licenseData?.value?.change ?? null)
2815
</script>
2916

3017
<template>
3118
<div
32-
v-if="changes && changes.length > 0"
19+
v-if="licenseChangeRecord"
3320
class="border border-amber-600/40 bg-amber-500/10 rounded-lg mt-1 gap-x-1 py-2 px-3"
3421
:aria-label="$t('package.versions.license_change_help')"
3522
>
@@ -42,9 +29,12 @@ const licenseChangeText = computed(() =>
4229
{{ $t('package.versions.license_change_warning') }}
4330
</p>
4431
<p class="text-md text-amber-800 dark:text-amber-400 mt-1">
45-
<i18n-t keypath="package.versions.changed_license" tag="span">
46-
<template #license_change>{{ licenseChangeText }}</template>
47-
</i18n-t>
32+
{{
33+
$t('package.versions.license_change_record', {
34+
from: licenseChangeRecord?.from,
35+
to: licenseChangeRecord?.to,
36+
})
37+
}}
4838
</p>
4939
</div>
5040
</template>
Lines changed: 13 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
import type { MaybeRefOrGetter } from 'vue'
22
import { toValue } from 'vue'
3-
4-
export interface LicenseChange {
5-
from: string
6-
to: string
7-
version: string
8-
}
9-
10-
export interface LicenseChangesResult {
11-
changes: LicenseChange[]
12-
}
13-
14-
// Type definitions for npm registry response
15-
interface NpmRegistryVersion {
16-
version: string
17-
license?: string
18-
}
19-
20-
// for registry responses of $fetch function, the type includes the key versions as well as many others too.
21-
interface NpmRegistryResponse {
22-
time: Record<string, string>
23-
versions: Record<string, NpmRegistryVersion>
3+
interface LicenseChangeResponse {
4+
change: { from: string; to: string } | null
245
}
256

267
/**
@@ -30,59 +11,19 @@ export function useLicenseChanges(
3011
packageName: MaybeRefOrGetter<string | null | undefined>,
3112
resolvedVersion: MaybeRefOrGetter<string | null | undefined> = () => undefined,
3213
) {
33-
return useAsyncData<LicenseChangesResult>(
34-
() => {
35-
const name = toValue(packageName)
36-
const version = toValue(resolvedVersion) ?? 'latest'
37-
return `license-changes:${name}:${version}`
38-
},
39-
async () => {
40-
const name = toValue(packageName)
41-
const resolvedVer = toValue(resolvedVersion)
42-
if (!name) return { changes: [] }
43-
44-
// Fetch full package metadata from npm registry
45-
const url = `https://registry.npmjs.org/${name}`
46-
const data = await $fetch<NpmRegistryResponse>(url)
47-
48-
const changes: LicenseChange[] = []
49-
50-
// `data.versions` is an object with version keys
51-
const versions = Object.values(data.versions) as NpmRegistryVersion[]
52-
53-
// Sort versions ascending to compare chronologically
54-
versions.sort((a, b) => {
55-
const dateA = new Date(data.time[a.version] as string).getTime()
56-
const dateB = new Date(data.time[b.version] as string).getTime()
57-
58-
// Ascending order (oldest to newest)
59-
return dateA - dateB
60-
})
14+
const name = computed(() => toValue(packageName))
15+
if (!name) return { data: null } // Don't fetch if no name
6116

62-
// When resolvedVer is not provided, check changes across all versions
63-
const targetVersion = resolvedVer ?? versions[versions.length - 1]?.version
17+
const version = computed(() => toValue(resolvedVersion) ?? 'latest')
6418

65-
if (targetVersion) {
66-
const resolvedIndex = versions.findIndex(v => v.version === targetVersion)
19+
const url = computed(() => {
20+
return name.value ? `/api/registry/license-change/${encodeURIComponent(name.value)}` : ''
21+
})
6722

68-
if (resolvedIndex > 0) {
69-
const currentLicense = (versions[resolvedIndex]?.license as string) ?? 'UNKNOWN'
70-
const previousLicense = (versions[resolvedIndex - 1]?.license as string) ?? 'UNKNOWN'
23+
const result = useFetch<LicenseChangeResponse>(url, {
24+
query: computed(() => ({ version: version.value })),
25+
watch: [url, version],
26+
})
7127

72-
if (currentLicense !== previousLicense) {
73-
changes.push({
74-
from: previousLicense,
75-
to: currentLicense,
76-
version: (versions[resolvedIndex]?.version as string) || 'UNKNOWN',
77-
})
78-
}
79-
}
80-
}
81-
return { changes }
82-
},
83-
{
84-
default: () => ({ changes: [] }),
85-
watch: [() => toValue(packageName), () => toValue(resolvedVersion)],
86-
},
87-
)
28+
return result
8829
}

i18n/locales/en.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,9 @@
433433
"filter_invalid": "Invalid semver range",
434434
"filter_help": "Semver range filter help",
435435
"license_change_help": "License Change Details",
436-
"license_change_item": "from {from} to {to} at version {version}",
437436
"filter_tooltip": "Filter versions using a {link}. For example, ^3.0.0 shows all 3.x versions.",
438-
"changed_license": "The license was changed {license_change}",
439437
"license_change_warning": "License change!",
438+
"license_change_record": "License changed from {from} to {to}.",
440439
"filter_tooltip_link": "semver range",
441440
"no_matches": "No versions match this range",
442441
"copy_alt": {

i18n/locales/tr-TR.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,9 @@
387387
"filter_invalid": "Geçersiz semver aralığı",
388388
"filter_help": "Semver aralığı filtresi yardımı",
389389
"license_change_help": "Lisans değişikliği yardımı",
390-
"license_change_item": "{version} sürümünde {from}'den {to}'ya",
391390
"filter_tooltip": "Sürümleri {link} kullanarak filtreleyin. Örneğin, ^3.0.0 tüm 3.x sürümlerini gösterir.",
392-
"changed_license": "Lisans değişikliği gerçekleşti: {license_change}",
393391
"license_change_warning": "Lisans değişikliği!",
392+
"license_change_record": "{from}'dan {to}'e lisans değişikliği gerçekleşti.",
394393
"filter_tooltip_link": "semver aralığı",
395394
"no_matches": "Bu aralığa uygun sürüm yok",
396395
"copy_alt": {

i18n/schema.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,13 +1303,10 @@
13031303
"license_change_help": {
13041304
"type": "string"
13051305
},
1306-
"license_change_item": {
1307-
"type": "string"
1308-
},
13091306
"filter_tooltip": {
13101307
"type": "string"
13111308
},
1312-
"changed_license": {
1309+
"license_change_record": {
13131310
"type": "string"
13141311
},
13151312
"license_change_warning": {
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
interface LicenseChangeRecord {
2+
from: string
3+
to: string
4+
}
5+
6+
interface NpmRegistryVersion {
7+
version: string
8+
license?: string
9+
}
10+
11+
interface NpmRegistryResponse {
12+
time: Record<string, string>
13+
versions: Record<string, NpmRegistryVersion>
14+
}
15+
16+
export default defineCachedEventHandler(
17+
async event => {
18+
// 1. Extract the package name from the catch-all parameter
19+
const rawPkg = getRouterParam(event, 'pkg')
20+
if (!rawPkg) {
21+
throw createError({
22+
statusCode: 400,
23+
statusMessage: 'Package name is required',
24+
})
25+
}
26+
const query = getQuery(event)
27+
const version = query.version || 'latest'
28+
29+
const packageName = decodeURIComponent(rawPkg).replace(/\/+$/, '').trim()
30+
31+
try {
32+
// 2. Fetch the "Packument" on the server
33+
// This stays on the server, so the client never downloads this massive JSON
34+
const data = await $fetch<NpmRegistryResponse>(`https://registry.npmjs.org/${packageName}`)
35+
36+
if (!data.versions || !data.time) {
37+
throw createError({
38+
statusCode: 404,
39+
statusMessage: 'Package metadata not found',
40+
})
41+
}
42+
43+
// 3. Process the logic (moved from your composable)
44+
const versions = Object.values(data.versions)
45+
46+
// Sort versions chronologically using the 'time' object
47+
versions.sort((a, b) => {
48+
const timeA = new Date(data.time[a.version] as string).getTime()
49+
const timeB = new Date(data.time[b.version] as string).getTime()
50+
return timeA - timeB
51+
})
52+
let change: LicenseChangeRecord | null = null
53+
54+
const currentVersionIndex =
55+
version === 'latest' ? versions.length - 1 : versions.findIndex(v => v.version === version)
56+
57+
const previousVersionIndex = currentVersionIndex - 1
58+
const currentLicense = versions[currentVersionIndex]?.license || 'UNKNOWN'
59+
const previousLicense = versions[previousVersionIndex]?.license || 'UNKNOWN'
60+
61+
if (currentLicense !== previousLicense) {
62+
change = {
63+
from: previousLicense as string,
64+
to: currentLicense as string,
65+
}
66+
}
67+
return { change }
68+
} catch (error: any) {
69+
throw createError({
70+
statusCode: error.statusCode || 500,
71+
statusMessage: `Failed to fetch license data: ${error.message}`,
72+
})
73+
}
74+
},
75+
{
76+
// 5. Cache Configuration
77+
maxAge: 60 * 60, // time in seconds
78+
swr: true,
79+
getKey: event => {
80+
const pkg = getRouterParam(event, 'pkg') ?? ''
81+
const query = getQuery(event)
82+
83+
// 1. remove the /'s from the package name
84+
const cleanPkg = pkg.replace(/\/+$/, '').trim()
85+
86+
// 2. Get the version (default to 'latest' if not provided)
87+
const version = query.version || 'latest'
88+
89+
// 3. Create a unique string including the version
90+
// Result: "license-change:v1:lodash:4.17.21"
91+
return `license-change:v2:${cleanPkg}:${version}`
92+
},
93+
},
94+
)

0 commit comments

Comments
 (0)