···11import type { CachedFetchResult } from '#shared/utils/fetch-cache-config'
2233/**
44- * Type for the cachedFetch function attached to event context.
55- */
66-export type CachedFetchFunction = <T = unknown>(
77- url: string,
88- options?: {
99- method?: string
1010- body?: unknown
1111- headers?: Record<string, string>
1212- },
1313- ttl?: number,
1414-) => Promise<CachedFetchResult<T>>
1515-1616-/**
174 * Get the cachedFetch function from the current request context.
185 *
196 * IMPORTANT: This must be called in the composable setup context (outside of
+1-1
app/composables/useNpmRegistry.ts
···1212import { maxSatisfying, prerelease, major, minor, diff, gt, compare } from 'semver'
1313import { isExactVersion } from '~/utils/versions'
1414import { extractInstallScriptsInfo } from '~/utils/install-scripts'
1515-import type { CachedFetchFunction } from '~/composables/useCachedFetch'
1515+import type { CachedFetchFunction } from '#shared/utils/fetch-cache-config'
16161717const NPM_REGISTRY = 'https://registry.npmjs.org'
1818const NPM_API = 'https://api.npmjs.org'
+3-21
app/composables/useRepoMeta.ts
···11import type { ProviderId, RepoRef } from '#shared/utils/git-providers'
22import { parseRepoUrl, GITLAB_HOSTS } from '#shared/utils/git-providers'
33-import type { CachedFetchFunction } from '~/composables/useCachedFetch'
4354// TTL for git repo metadata (10 minutes - repo stats don't change frequently)
65const REPO_META_TTL = 60 * 10
···8483 delegates?: Array<{ id: string; alias?: string }>
8584 patches?: { open: number; draft: number; archived: number; merged: number }
8685 issues?: { open: number; closed: number }
8787-}
8888-8989-/** microcosm's constellation API response for /links/all to get tangled.org stats */
9090-type ConstellationAllLinksResponse = {
9191- links: Record<
9292- string,
9393- Record<
9494- string,
9595- {
9696- records: number
9797- distinct_dids: number
9898- }
9999- >
100100- >
10186}
1028710388type ProviderAdapter = {
···597582 let forks = 0
598583 const atUri = atUriMatch?.[1]
599584600600- if (atUriMatch) {
585585+ if (atUri) {
601586 try {
587587+ const constellation = new Constellation(cachedFetch)
602588 //Get counts of records that reference this repo in the atmosphere using constellation
603603- const { data: allLinks } = await cachedFetch<ConstellationAllLinksResponse>(
604604- `https://constellation.microcosm.blue/links/all?target=${atUri}`,
605605- { headers: { 'User-Agent': 'npmx' } },
606606- REPO_META_TTL,
607607- )
589589+ const { data: allLinks } = await constellation.getAllLinks(atUri)
608590 stars = allLinks.links['sh.tangled.feed.star']?.['.subject']?.distinct_dids ?? stars
609591 forks = allLinks.links['sh.tangled.repo']?.['.source']?.distinct_dids ?? stars
610592 } catch {
+31
lexicons/dev/npmx/feed/like.json
···11+{
22+ "defs": {
33+ "main": {
44+ "description": "A like of a package on npmx",
55+ "key": "tid",
66+ "record": {
77+ "properties": {
88+ "createdAt": {
99+ "format": "datetime",
1010+ "type": "string"
1111+ },
1212+ "subject": {
1313+ "description": "A strong reference to the dev.npmx.package record. If the package does not have a record in an atproto repo, this is not included.",
1414+ "type": "ref",
1515+ "ref": "com.atproto.repo.strongRef"
1616+ },
1717+ "subjectRef": {
1818+ "description": "The npmx URL to the package to allow for counting of packages that do not have a record in an atproto repo.",
1919+ "type": "string",
2020+ "format": "uri"
2121+ }
2222+ },
2323+ "required": ["createdAt", "subjectRef"],
2424+ "type": "object"
2525+ },
2626+ "type": "record"
2727+ }
2828+ },
2929+ "id": "dev.npmx.feed.like",
3030+ "lexicon": 1
3131+}
+2-2
server/api/auth/atproto.get.ts
···22import { NodeOAuthClient } from '@atproto/oauth-client-node'
33import { createError, getQuery, sendRedirect } from 'h3'
44import { useOAuthStorage } from '#server/utils/atproto/storage'
55-import { SLINGSHOT_ENDPOINT } from '#shared/utils/constants'
55+import { SLINGSHOT_HOST } from '#shared/utils/constants'
66import type { UserSession } from '#shared/schemas/userSession'
7788export default defineEventHandler(async event => {
···5353 })
54545555 const response = await fetch(
5656- `${SLINGSHOT_ENDPOINT}/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${agent.did}`,
5656+ `https://${SLINGSHOT_HOST}/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=${agent.did}`,
5757 { headers: { 'User-Agent': 'npmx' } },
5858 )
5959 const miniDoc = (await response.json()) as UserSession
-10
server/plugins/fetch-cache.ts
···4141 return parts.join(':')
4242}
43434444-export type CachedFetchFunction = <T = unknown>(
4545- url: string,
4646- options?: {
4747- method?: string
4848- body?: unknown
4949- headers?: Record<string, string>
5050- },
5151- ttl?: number,
5252-) => Promise<CachedFetchResult<T>>
5353-5444/**
5545 * Server plugin that attaches a cachedFetch function to the event context.
5646 * This allows app composables to access the cached fetch via useRequestEvent().