@agntn/registries 0.2.0 → 0.3.0
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/dist/_chunks/errors.d.mts.map +1 -1
- package/dist/_chunks/purl.mjs +9 -1
- package/dist/_chunks/purl.mjs.map +1 -1
- package/dist/ai.d.mts +1 -7
- package/dist/ai.d.mts.map +1 -1
- package/dist/cache/cached-registry.d.mts +35 -4
- package/dist/cache/index.d.mts +22 -7
- package/dist/cache/index.d.mts.map +1 -0
- package/dist/cache/lockfile.d.mts +50 -2
- package/dist/cache/paths.d.mts +11 -2
- package/dist/cache/storage.d.mts +22 -2
- package/dist/commands/deps.mjs +1 -1
- package/dist/commands/deps.mjs.map +1 -1
- package/dist/index.d.mts +53 -7
- package/dist/index.d.mts.map +1 -0
- package/package.json +1 -1
- package/dist/_chunks/cached-registry.d.mts +0 -35
- package/dist/_chunks/index2.d.mts +0 -50
- package/dist/_chunks/index2.d.mts.map +0 -1
- package/dist/_chunks/index3.d.mts +0 -18
- package/dist/_chunks/index3.d.mts.map +0 -1
- package/dist/_chunks/lockfile.d.mts +0 -50
- package/dist/_chunks/paths.d.mts +0 -11
- package/dist/_chunks/storage.d.mts +0 -22
- /package/dist/{_chunks → cache}/cached-registry.d.mts.map +0 -0
- /package/dist/{_chunks → cache}/lockfile.d.mts.map +0 -0
- /package/dist/{_chunks → cache}/paths.d.mts.map +0 -0
- /package/dist/{_chunks → cache}/storage.d.mts.map +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../src/core/purl.ts","../../src/core/license.ts","../../src/core/repository.ts","../../src/core/errors.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../src/core/purl.ts","../../src/core/license.ts","../../src/core/repository.ts","../../src/core/errors.ts"],"mappings":";;;;;AAuBA;;;;;AA4FA;iBA5FgB,SAAA,CAAU,OAAA,WAAkB,UAAA;;iBA4F5B,QAAA,CAAS,MAAA,EAAQ,UAAA;;iBAQjB,cAAA,CAAe,OAAA,UAAiB,MAAA,GAAS,MAAA,IAAU,QAAA;;iBAQnD,SAAA,CAAU,KAAA;EACxB,IAAA;EACA,IAAA;EACA,OAAA;EACA,SAAA;EACA,UAAA,GAAa,MAAA;EACb,OAAA;AAAA;;;;;;;AAlHF;;iBCjBgB,gBAAA,CAAiB,GAAA;;;AD6GjC;;;;iBCpDgB,eAAA,CACd,QAAA,iCACA,QAAA;;;;;;;AD1CF;;;;;AA4FA;iBEzGgB,sBAAA,CAAuB,GAAA;;;;cCR1B,SAAA,SAAkB,KAAA;cACjB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;AAAA,cAM5B,SAAA,SAAkB,SAAA;EAAA,SACpB,UAAA;EAAA,SACA,GAAA;EAAA,SACA,IAAA;cAEG,UAAA,UAAoB,GAAA,UAAa,IAAA;EAQ7C,UAAA,CAAA;EAIA,WAAA,CAAA;EAIA,aAAA,CAAA;AAAA;AAAA,cAKW,aAAA,SAAsB,SAAA;EAAA,SACxB,SAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA;cAEG,SAAA,UAAmB,WAAA,UAAqB,OAAA;AAAA;AAAA,cAUzC,cAAA,SAAuB,SAAA;EAAA,SACzB,UAAA;cAEG,UAAA;AAAA;AAAA,cAOD,qBAAA,SAA8B,SAAA;EAAA,SAChC,SAAA;cAEG,SAAA;AAAA;AAAA,cAOD,gBAAA,SAAyB,SAAA;EAAA,SAC3B,IAAA;cAEG,IAAA,UAAc,MAAA;AAAA"}
|
package/dist/_chunks/purl.mjs
CHANGED
|
@@ -94,6 +94,7 @@ function normalizeRepositoryURL(raw) {
|
|
|
94
94
|
if (url.endsWith(".git")) url = url.slice(0, -4);
|
|
95
95
|
return url;
|
|
96
96
|
}
|
|
97
|
+
const QUALIFIER_KEY_PATTERN = /^[a-z][a-z0-9._-]*$/;
|
|
97
98
|
/** Decode a percent-encoded PURL component, throwing InvalidPURLError on malformed sequences. */
|
|
98
99
|
function decodePURLComponent(purlStr, value) {
|
|
99
100
|
try {
|
|
@@ -181,7 +182,14 @@ function buildPURL(parts) {
|
|
|
181
182
|
purl += encodeURIComponent(parts.name);
|
|
182
183
|
if (parts.version) purl += `@${encodeURIComponent(parts.version)}`;
|
|
183
184
|
if (parts.qualifiers && Object.keys(parts.qualifiers).length > 0) {
|
|
184
|
-
const
|
|
185
|
+
const qualifiers = /* @__PURE__ */ new Map();
|
|
186
|
+
for (const [key, value] of Object.entries(parts.qualifiers)) {
|
|
187
|
+
const canonicalKey = key.toLowerCase();
|
|
188
|
+
if (!QUALIFIER_KEY_PATTERN.test(canonicalKey)) throw new InvalidPURLError(purl, `invalid qualifier key "${key}"`);
|
|
189
|
+
if (qualifiers.has(canonicalKey)) throw new InvalidPURLError(purl, `duplicate qualifier key "${canonicalKey}"`);
|
|
190
|
+
qualifiers.set(canonicalKey, value);
|
|
191
|
+
}
|
|
192
|
+
const qs = [...qualifiers].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&");
|
|
185
193
|
purl += `?${qs}`;
|
|
186
194
|
}
|
|
187
195
|
if (parts.subpath) purl += `#${parts.subpath.split("/").map((s) => encodeURIComponent(s)).join("/")}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"purl.mjs","names":[],"sources":["../../src/core/license.ts","../../src/core/repository.ts","../../src/core/purl.ts"],"sourcesContent":["/**\n * Normalize a license string to SPDX expression.\n *\n * Handles common variations: \"MIT License\" → \"MIT\", \"Apache 2.0\" → \"Apache-2.0\".\n * Passes through already-valid SPDX identifiers unchanged.\n */\nexport function normalizeLicense(raw: string | null | undefined): string {\n if (!raw) return \"\";\n\n const trimmed = raw.trim();\n if (!trimmed) return \"\";\n\n // Common mappings\n const lower = trimmed.toLowerCase();\n const known = LICENSE_MAP.get(lower);\n if (known) return known;\n\n // Already looks like SPDX — return as-is\n return trimmed;\n}\n\nconst LICENSE_MAP = new Map<string, string>([\n [\"mit license\", \"MIT\"],\n [\"mit\", \"MIT\"],\n [\"apache license 2.0\", \"Apache-2.0\"],\n [\"apache 2.0\", \"Apache-2.0\"],\n [\"apache-2.0\", \"Apache-2.0\"],\n [\"apache license, version 2.0\", \"Apache-2.0\"],\n [\"apache2\", \"Apache-2.0\"],\n [\"bsd-2-clause\", \"BSD-2-Clause\"],\n [\"bsd-3-clause\", \"BSD-3-Clause\"],\n [\"bsd 2-clause\", \"BSD-2-Clause\"],\n [\"bsd 3-clause\", \"BSD-3-Clause\"],\n [\"simplified bsd license\", \"BSD-2-Clause\"],\n [\"new bsd license\", \"BSD-3-Clause\"],\n [\"isc license\", \"ISC\"],\n [\"isc\", \"ISC\"],\n [\"gpl-2.0\", \"GPL-2.0-only\"],\n [\"gpl-3.0\", \"GPL-3.0-only\"],\n [\"gpl-2.0-only\", \"GPL-2.0-only\"],\n [\"gpl-3.0-only\", \"GPL-3.0-only\"],\n [\"lgpl-2.1\", \"LGPL-2.1-only\"],\n [\"lgpl-3.0\", \"LGPL-3.0-only\"],\n [\"mpl-2.0\", \"MPL-2.0\"],\n [\"mozilla public license 2.0\", \"MPL-2.0\"],\n [\"unlicense\", \"Unlicense\"],\n [\"the unlicense\", \"Unlicense\"],\n [\"cc0-1.0\", \"CC0-1.0\"],\n [\"cc0\", \"CC0-1.0\"],\n [\"public domain\", \"Unlicense\"],\n [\"zlib\", \"Zlib\"],\n [\"wtfpl\", \"WTFPL\"],\n [\"artistic-2.0\", \"Artistic-2.0\"],\n [\"boost software license 1.0\", \"BSL-1.0\"],\n [\"bsl-1.0\", \"BSL-1.0\"],\n]);\n\n/**\n * Combine multiple license strings into a single SPDX expression.\n *\n * Default operator is OR (disjunctive, user picks one).\n * Pass \"AND\" for ecosystems where multiple licenses mean all apply (e.g. Arch Linux).\n */\nexport function combineLicenses(\n licenses: (string | null | undefined)[],\n operator: \"OR\" | \"AND\" = \"OR\",\n): string {\n const normalized = licenses.map((l) => normalizeLicense(l)).filter(Boolean);\n\n if (normalized.length === 0) return \"\";\n if (normalized.length === 1) return normalized[0]!;\n return normalized.join(` ${operator} `);\n}\n","/**\n * Normalize a repository URL to a clean HTTPS git URL.\n *\n * Handles various formats:\n * - \"git+https://github.com/foo/bar.git\" → \"https://github.com/foo/bar\"\n * - \"git://github.com/foo/bar\" → \"https://github.com/foo/bar\"\n * - \"ssh://git@github.com/foo/bar.git\" → \"https://github.com/foo/bar\"\n * - \"github:foo/bar\" → \"https://github.com/foo/bar\"\n * - { url: \"...\" } → extracted and normalized\n */\nexport function normalizeRepositoryURL(raw: unknown): string {\n if (!raw) return \"\";\n\n let url: string;\n\n if (typeof raw === \"string\") {\n url = raw;\n } else if (typeof raw === \"object\" && raw !== null) {\n const obj = raw as Record<string, unknown>;\n if (typeof obj[\"url\"] === \"string\") {\n url = obj[\"url\"];\n } else {\n return \"\";\n }\n } else {\n return \"\";\n }\n\n url = url.trim();\n if (!url) return \"\";\n\n // GitHub shorthand: \"github:user/repo\"\n if (url.startsWith(\"github:\")) {\n url = `https://github.com/${url.slice(7)}`;\n }\n\n // GitLab shorthand\n if (url.startsWith(\"gitlab:\")) {\n url = `https://gitlab.com/${url.slice(7)}`;\n }\n\n // Bitbucket shorthand\n if (url.startsWith(\"bitbucket:\")) {\n url = `https://bitbucket.org/${url.slice(10)}`;\n }\n\n // Strip \"git+\" prefix\n if (url.startsWith(\"git+\")) {\n url = url.slice(4);\n }\n\n // Convert git:// to https://\n if (url.startsWith(\"git://\")) {\n url = \"https://\" + url.slice(6);\n }\n\n // Convert ssh://git@host/... to https://host/...\n if (url.startsWith(\"ssh://git@\")) {\n url = \"https://\" + url.slice(10);\n }\n\n // Convert git@host:user/repo to https://host/user/repo\n const sshMatch = url.match(/^git@([^:]+):(.+)$/);\n if (sshMatch) {\n url = `https://${sshMatch[1]}/${sshMatch[2]}`;\n }\n\n // Strip trailing slash first so \".git/\" doesn't survive\n if (url.endsWith(\"/\")) {\n url = url.slice(0, -1);\n }\n\n // Strip .git suffix\n if (url.endsWith(\".git\")) {\n url = url.slice(0, -4);\n }\n\n return url;\n}\n","import type { ParsedPURL } from \"./types.ts\";\nimport type { Client } from \"./client.ts\";\nimport { create, type Registry } from \"./registry.ts\";\nimport { InvalidPURLError } from \"./errors.ts\";\n\n/** Decode a percent-encoded PURL component, throwing InvalidPURLError on malformed sequences. */\nfunction decodePURLComponent(purlStr: string, value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n throw new InvalidPURLError(purlStr, \"malformed percent-encoding\");\n }\n}\n\n/**\n * Parse a PURL string into its components.\n *\n * Format: `pkg:<type>/<namespace>/<name>@<version>?<qualifiers>#<subpath>`\n *\n * @see https://github.com/package-url/purl-spec (ECMA-427)\n */\nexport function parsePURL(purlStr: string): ParsedPURL {\n if (!purlStr.startsWith(\"pkg:\")) {\n throw new InvalidPURLError(purlStr, 'must start with \"pkg:\"');\n }\n\n let remainder = purlStr.slice(4); // strip 'pkg:'\n\n // Extract subpath\n let subpath = \"\";\n const hashIdx = remainder.indexOf(\"#\");\n if (hashIdx !== -1) {\n subpath = remainder\n .slice(hashIdx + 1)\n .split(\"/\")\n .map((s) => decodePURLComponent(purlStr, s))\n .join(\"/\");\n remainder = remainder.slice(0, hashIdx);\n }\n\n // Extract qualifiers\n const qualifiers: Record<string, string> = {};\n const queryIdx = remainder.indexOf(\"?\");\n if (queryIdx !== -1) {\n const queryStr = remainder.slice(queryIdx + 1);\n remainder = remainder.slice(0, queryIdx);\n for (const pair of queryStr.split(\"&\")) {\n const eqIdx = pair.indexOf(\"=\");\n if (eqIdx !== -1) {\n qualifiers[decodePURLComponent(purlStr, pair.slice(0, eqIdx))] = decodePURLComponent(\n purlStr,\n pair.slice(eqIdx + 1),\n );\n }\n }\n }\n\n // Extract version — the version separator is the last '@' that appears\n // after the last '/', so scoped names like 'npm/@vue/core' are not mistaken\n // for having a version.\n let version = \"\";\n const lastSlashBeforeVersion = remainder.lastIndexOf(\"/\");\n const lastAtIdx = remainder.lastIndexOf(\"@\");\n if (lastAtIdx !== -1 && lastAtIdx > lastSlashBeforeVersion) {\n version = decodePURLComponent(purlStr, remainder.slice(lastAtIdx + 1));\n remainder = remainder.slice(0, lastAtIdx);\n }\n\n // Extract type\n const slashIdx = remainder.indexOf(\"/\");\n if (slashIdx === -1) {\n throw new InvalidPURLError(purlStr, \"missing type/name separator\");\n }\n\n const type = remainder.slice(0, slashIdx).toLowerCase();\n if (!type) {\n throw new InvalidPURLError(purlStr, \"empty type\");\n }\n\n const rest = remainder.slice(slashIdx + 1);\n if (!rest) {\n throw new InvalidPURLError(purlStr, \"empty name\");\n }\n\n // Extract namespace and name\n const lastSlashIdx = rest.lastIndexOf(\"/\");\n let namespace = \"\";\n let name: string;\n\n if (lastSlashIdx !== -1) {\n namespace = rest\n .slice(0, lastSlashIdx)\n .split(\"/\")\n .map((s) => decodePURLComponent(purlStr, s))\n .join(\"/\");\n name = decodePURLComponent(purlStr, rest.slice(lastSlashIdx + 1));\n } else {\n name = decodePURLComponent(purlStr, rest);\n }\n\n // Ecosystem-specific normalization per PURL spec\n if (type === \"pypi\") {\n name = name.toLowerCase().replace(/[-_.]+/g, \"-\");\n }\n\n if (type === \"alpm\") {\n name = name.toLowerCase();\n }\n\n return { type, namespace, name, version, qualifiers, subpath };\n}\n\n/** Build the full name from namespace + name (e.g., \"@scope/pkg\" for npm). */\nexport function fullName(parsed: ParsedPURL): string {\n if (parsed.namespace) {\n return `${parsed.namespace}/${parsed.name}`;\n }\n return parsed.name;\n}\n\n/** Create a registry instance from a PURL, returning [registry, name, version]. */\nexport function createFromPURL(purlStr: string, client?: Client): [Registry, string, string] {\n const parsed = parsePURL(purlStr);\n const baseURL = parsed.qualifiers[\"repository_url\"] ?? \"\";\n const reg = create(parsed.type, baseURL || undefined, client);\n return [reg, fullName(parsed), parsed.version];\n}\n\n/** Build a PURL string from components. Inverse of `parsePURL`. */\nexport function buildPURL(parts: {\n type: string;\n name: string;\n version?: string;\n namespace?: string;\n qualifiers?: Record<string, string>;\n subpath?: string;\n}): string {\n let purl = `pkg:${parts.type}/`;\n if (parts.namespace) {\n purl += `${parts.namespace\n .split(\"/\")\n .map((s) => encodeURIComponent(s))\n .join(\"/\")}/`;\n }\n purl += encodeURIComponent(parts.name);\n if (parts.version) {\n purl += `@${encodeURIComponent(parts.version)}`;\n }\n if (parts.qualifiers && Object.keys(parts.qualifiers).length > 0) {\n const qs = Object.entries(parts.qualifiers)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n purl += `?${qs}`;\n }\n if (parts.subpath) {\n purl += `#${parts.subpath\n .split(\"/\")\n .map((s) => encodeURIComponent(s))\n .join(\"/\")}`;\n }\n return purl;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"purl.mjs","names":[],"sources":["../../src/core/license.ts","../../src/core/repository.ts","../../src/core/purl.ts"],"sourcesContent":["/**\n * Normalize a license string to SPDX expression.\n *\n * Handles common variations: \"MIT License\" → \"MIT\", \"Apache 2.0\" → \"Apache-2.0\".\n * Passes through already-valid SPDX identifiers unchanged.\n */\nexport function normalizeLicense(raw: string | null | undefined): string {\n if (!raw) return \"\";\n\n const trimmed = raw.trim();\n if (!trimmed) return \"\";\n\n // Common mappings\n const lower = trimmed.toLowerCase();\n const known = LICENSE_MAP.get(lower);\n if (known) return known;\n\n // Already looks like SPDX — return as-is\n return trimmed;\n}\n\nconst LICENSE_MAP = new Map<string, string>([\n [\"mit license\", \"MIT\"],\n [\"mit\", \"MIT\"],\n [\"apache license 2.0\", \"Apache-2.0\"],\n [\"apache 2.0\", \"Apache-2.0\"],\n [\"apache-2.0\", \"Apache-2.0\"],\n [\"apache license, version 2.0\", \"Apache-2.0\"],\n [\"apache2\", \"Apache-2.0\"],\n [\"bsd-2-clause\", \"BSD-2-Clause\"],\n [\"bsd-3-clause\", \"BSD-3-Clause\"],\n [\"bsd 2-clause\", \"BSD-2-Clause\"],\n [\"bsd 3-clause\", \"BSD-3-Clause\"],\n [\"simplified bsd license\", \"BSD-2-Clause\"],\n [\"new bsd license\", \"BSD-3-Clause\"],\n [\"isc license\", \"ISC\"],\n [\"isc\", \"ISC\"],\n [\"gpl-2.0\", \"GPL-2.0-only\"],\n [\"gpl-3.0\", \"GPL-3.0-only\"],\n [\"gpl-2.0-only\", \"GPL-2.0-only\"],\n [\"gpl-3.0-only\", \"GPL-3.0-only\"],\n [\"lgpl-2.1\", \"LGPL-2.1-only\"],\n [\"lgpl-3.0\", \"LGPL-3.0-only\"],\n [\"mpl-2.0\", \"MPL-2.0\"],\n [\"mozilla public license 2.0\", \"MPL-2.0\"],\n [\"unlicense\", \"Unlicense\"],\n [\"the unlicense\", \"Unlicense\"],\n [\"cc0-1.0\", \"CC0-1.0\"],\n [\"cc0\", \"CC0-1.0\"],\n [\"public domain\", \"Unlicense\"],\n [\"zlib\", \"Zlib\"],\n [\"wtfpl\", \"WTFPL\"],\n [\"artistic-2.0\", \"Artistic-2.0\"],\n [\"boost software license 1.0\", \"BSL-1.0\"],\n [\"bsl-1.0\", \"BSL-1.0\"],\n]);\n\n/**\n * Combine multiple license strings into a single SPDX expression.\n *\n * Default operator is OR (disjunctive, user picks one).\n * Pass \"AND\" for ecosystems where multiple licenses mean all apply (e.g. Arch Linux).\n */\nexport function combineLicenses(\n licenses: (string | null | undefined)[],\n operator: \"OR\" | \"AND\" = \"OR\",\n): string {\n const normalized = licenses.map((l) => normalizeLicense(l)).filter(Boolean);\n\n if (normalized.length === 0) return \"\";\n if (normalized.length === 1) return normalized[0]!;\n return normalized.join(` ${operator} `);\n}\n","/**\n * Normalize a repository URL to a clean HTTPS git URL.\n *\n * Handles various formats:\n * - \"git+https://github.com/foo/bar.git\" → \"https://github.com/foo/bar\"\n * - \"git://github.com/foo/bar\" → \"https://github.com/foo/bar\"\n * - \"ssh://git@github.com/foo/bar.git\" → \"https://github.com/foo/bar\"\n * - \"github:foo/bar\" → \"https://github.com/foo/bar\"\n * - { url: \"...\" } → extracted and normalized\n */\nexport function normalizeRepositoryURL(raw: unknown): string {\n if (!raw) return \"\";\n\n let url: string;\n\n if (typeof raw === \"string\") {\n url = raw;\n } else if (typeof raw === \"object\" && raw !== null) {\n const obj = raw as Record<string, unknown>;\n if (typeof obj[\"url\"] === \"string\") {\n url = obj[\"url\"];\n } else {\n return \"\";\n }\n } else {\n return \"\";\n }\n\n url = url.trim();\n if (!url) return \"\";\n\n // GitHub shorthand: \"github:user/repo\"\n if (url.startsWith(\"github:\")) {\n url = `https://github.com/${url.slice(7)}`;\n }\n\n // GitLab shorthand\n if (url.startsWith(\"gitlab:\")) {\n url = `https://gitlab.com/${url.slice(7)}`;\n }\n\n // Bitbucket shorthand\n if (url.startsWith(\"bitbucket:\")) {\n url = `https://bitbucket.org/${url.slice(10)}`;\n }\n\n // Strip \"git+\" prefix\n if (url.startsWith(\"git+\")) {\n url = url.slice(4);\n }\n\n // Convert git:// to https://\n if (url.startsWith(\"git://\")) {\n url = \"https://\" + url.slice(6);\n }\n\n // Convert ssh://git@host/... to https://host/...\n if (url.startsWith(\"ssh://git@\")) {\n url = \"https://\" + url.slice(10);\n }\n\n // Convert git@host:user/repo to https://host/user/repo\n const sshMatch = url.match(/^git@([^:]+):(.+)$/);\n if (sshMatch) {\n url = `https://${sshMatch[1]}/${sshMatch[2]}`;\n }\n\n // Strip trailing slash first so \".git/\" doesn't survive\n if (url.endsWith(\"/\")) {\n url = url.slice(0, -1);\n }\n\n // Strip .git suffix\n if (url.endsWith(\".git\")) {\n url = url.slice(0, -4);\n }\n\n return url;\n}\n","import type { ParsedPURL } from \"./types.ts\";\nimport type { Client } from \"./client.ts\";\nimport { create, type Registry } from \"./registry.ts\";\nimport { InvalidPURLError } from \"./errors.ts\";\n\nconst QUALIFIER_KEY_PATTERN = /^[a-z][a-z0-9._-]*$/;\n\n/** Decode a percent-encoded PURL component, throwing InvalidPURLError on malformed sequences. */\nfunction decodePURLComponent(purlStr: string, value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n throw new InvalidPURLError(purlStr, \"malformed percent-encoding\");\n }\n}\n\n/**\n * Parse a PURL string into its components.\n *\n * Format: `pkg:<type>/<namespace>/<name>@<version>?<qualifiers>#<subpath>`\n *\n * @see https://github.com/package-url/purl-spec (ECMA-427)\n */\nexport function parsePURL(purlStr: string): ParsedPURL {\n if (!purlStr.startsWith(\"pkg:\")) {\n throw new InvalidPURLError(purlStr, 'must start with \"pkg:\"');\n }\n\n let remainder = purlStr.slice(4); // strip 'pkg:'\n\n // Extract subpath\n let subpath = \"\";\n const hashIdx = remainder.indexOf(\"#\");\n if (hashIdx !== -1) {\n subpath = remainder\n .slice(hashIdx + 1)\n .split(\"/\")\n .map((s) => decodePURLComponent(purlStr, s))\n .join(\"/\");\n remainder = remainder.slice(0, hashIdx);\n }\n\n // Extract qualifiers\n const qualifiers: Record<string, string> = {};\n const queryIdx = remainder.indexOf(\"?\");\n if (queryIdx !== -1) {\n const queryStr = remainder.slice(queryIdx + 1);\n remainder = remainder.slice(0, queryIdx);\n for (const pair of queryStr.split(\"&\")) {\n const eqIdx = pair.indexOf(\"=\");\n if (eqIdx !== -1) {\n qualifiers[decodePURLComponent(purlStr, pair.slice(0, eqIdx))] = decodePURLComponent(\n purlStr,\n pair.slice(eqIdx + 1),\n );\n }\n }\n }\n\n // Extract version — the version separator is the last '@' that appears\n // after the last '/', so scoped names like 'npm/@vue/core' are not mistaken\n // for having a version.\n let version = \"\";\n const lastSlashBeforeVersion = remainder.lastIndexOf(\"/\");\n const lastAtIdx = remainder.lastIndexOf(\"@\");\n if (lastAtIdx !== -1 && lastAtIdx > lastSlashBeforeVersion) {\n version = decodePURLComponent(purlStr, remainder.slice(lastAtIdx + 1));\n remainder = remainder.slice(0, lastAtIdx);\n }\n\n // Extract type\n const slashIdx = remainder.indexOf(\"/\");\n if (slashIdx === -1) {\n throw new InvalidPURLError(purlStr, \"missing type/name separator\");\n }\n\n const type = remainder.slice(0, slashIdx).toLowerCase();\n if (!type) {\n throw new InvalidPURLError(purlStr, \"empty type\");\n }\n\n const rest = remainder.slice(slashIdx + 1);\n if (!rest) {\n throw new InvalidPURLError(purlStr, \"empty name\");\n }\n\n // Extract namespace and name\n const lastSlashIdx = rest.lastIndexOf(\"/\");\n let namespace = \"\";\n let name: string;\n\n if (lastSlashIdx !== -1) {\n namespace = rest\n .slice(0, lastSlashIdx)\n .split(\"/\")\n .map((s) => decodePURLComponent(purlStr, s))\n .join(\"/\");\n name = decodePURLComponent(purlStr, rest.slice(lastSlashIdx + 1));\n } else {\n name = decodePURLComponent(purlStr, rest);\n }\n\n // Ecosystem-specific normalization per PURL spec\n if (type === \"pypi\") {\n name = name.toLowerCase().replace(/[-_.]+/g, \"-\");\n }\n\n if (type === \"alpm\") {\n name = name.toLowerCase();\n }\n\n return { type, namespace, name, version, qualifiers, subpath };\n}\n\n/** Build the full name from namespace + name (e.g., \"@scope/pkg\" for npm). */\nexport function fullName(parsed: ParsedPURL): string {\n if (parsed.namespace) {\n return `${parsed.namespace}/${parsed.name}`;\n }\n return parsed.name;\n}\n\n/** Create a registry instance from a PURL, returning [registry, name, version]. */\nexport function createFromPURL(purlStr: string, client?: Client): [Registry, string, string] {\n const parsed = parsePURL(purlStr);\n const baseURL = parsed.qualifiers[\"repository_url\"] ?? \"\";\n const reg = create(parsed.type, baseURL || undefined, client);\n return [reg, fullName(parsed), parsed.version];\n}\n\n/** Build a PURL string from components. Inverse of `parsePURL`. */\nexport function buildPURL(parts: {\n type: string;\n name: string;\n version?: string;\n namespace?: string;\n qualifiers?: Record<string, string>;\n subpath?: string;\n}): string {\n let purl = `pkg:${parts.type}/`;\n if (parts.namespace) {\n purl += `${parts.namespace\n .split(\"/\")\n .map((s) => encodeURIComponent(s))\n .join(\"/\")}/`;\n }\n purl += encodeURIComponent(parts.name);\n if (parts.version) {\n purl += `@${encodeURIComponent(parts.version)}`;\n }\n if (parts.qualifiers && Object.keys(parts.qualifiers).length > 0) {\n const qualifiers = new Map<string, string>();\n for (const [key, value] of Object.entries(parts.qualifiers)) {\n const canonicalKey = key.toLowerCase();\n if (!QUALIFIER_KEY_PATTERN.test(canonicalKey)) {\n throw new InvalidPURLError(purl, `invalid qualifier key \"${key}\"`);\n }\n if (qualifiers.has(canonicalKey)) {\n throw new InvalidPURLError(purl, `duplicate qualifier key \"${canonicalKey}\"`);\n }\n qualifiers.set(canonicalKey, value);\n }\n const qs = [...qualifiers]\n .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n .join(\"&\");\n purl += `?${qs}`;\n }\n if (parts.subpath) {\n purl += `#${parts.subpath\n .split(\"/\")\n .map((s) => encodeURIComponent(s))\n .join(\"/\")}`;\n }\n return purl;\n}\n"],"mappings":"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"}
|
package/dist/ai.d.mts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { i as Package, l as Version, n as Dependency, r as Maintainer } from "./_chunks/types.mjs";
|
|
2
2
|
import "./_chunks/registry.mjs";
|
|
3
|
+
import "./types.mjs";
|
|
3
4
|
import "./_chunks/index.mjs";
|
|
4
|
-
import "./_chunks/errors.mjs";
|
|
5
|
-
import "./_chunks/index2.mjs";
|
|
6
|
-
import "./_chunks/paths.mjs";
|
|
7
|
-
import "./_chunks/storage.mjs";
|
|
8
|
-
import "./_chunks/cached-registry.mjs";
|
|
9
|
-
import "./_chunks/lockfile.mjs";
|
|
10
|
-
import "./_chunks/index3.mjs";
|
|
11
5
|
import * as ai from "ai";
|
|
12
6
|
|
|
13
7
|
//#region src/ai.d.ts
|
package/dist/ai.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.mts","names":[],"sources":["../src/ai.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ai.d.mts","names":[],"sources":["../src/ai.ts"],"mappings":";;;;;;;cAWa,WAAA,KAAW,IAAA;;;;;;;;;;;;;;;;GAuDtB,OAAA"}
|
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
import "../_chunks/types.mjs";
|
|
2
|
-
import "../_chunks/registry.mjs";
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { c as URLBuilder, i as Package, l as Version, n as Dependency, r as Maintainer } from "../_chunks/types.mjs";
|
|
2
|
+
import { t as Registry } from "../_chunks/registry.mjs";
|
|
3
|
+
import { Storage } from "unstorage";
|
|
4
|
+
|
|
5
|
+
//#region src/cache/cached-registry.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* CachedRegistry wraps any Registry and adds caching backed by unstorage
|
|
8
|
+
* with a lockfile for freshness tracking.
|
|
9
|
+
*
|
|
10
|
+
* Pass a custom `storage` to use a non-default driver (e.g. Cloudflare KV).
|
|
11
|
+
* If omitted, uses the globally configured storage (see `configureStorage()`).
|
|
12
|
+
*/
|
|
13
|
+
declare class CachedRegistry extends Registry {
|
|
14
|
+
readonly inner: Registry;
|
|
15
|
+
readonly storage: Storage;
|
|
16
|
+
private readonly lockfileStorage;
|
|
17
|
+
private readonly inflight;
|
|
18
|
+
constructor(inner: Registry, storage?: Storage);
|
|
19
|
+
ecosystem(): string;
|
|
20
|
+
urls(): URLBuilder;
|
|
21
|
+
fetchPackage(name: string, signal?: AbortSignal): Promise<Package>;
|
|
22
|
+
fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]>;
|
|
23
|
+
fetchDependencies(name: string, version: string, signal?: AbortSignal): Promise<Dependency[]>;
|
|
24
|
+
fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Generic cache-through method:
|
|
27
|
+
* 1. Check lockfile for fresh entry
|
|
28
|
+
* 2. If fresh -> read from storage
|
|
29
|
+
* 3. If stale/missing -> fetch, store, update lockfile
|
|
30
|
+
*/
|
|
31
|
+
private cached;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { CachedRegistry };
|
|
35
|
+
//# sourceMappingURL=cached-registry.d.mts.map
|
package/dist/cache/index.d.mts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import "../_chunks/types.mjs";
|
|
2
|
-
import "../_chunks/registry.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
2
|
+
import { o as Client, t as Registry } from "../_chunks/registry.mjs";
|
|
3
|
+
import { CachedRegistry } from "./cached-registry.mjs";
|
|
4
|
+
import { getCacheDir } from "./paths.mjs";
|
|
5
|
+
import { clearStorage, computeIntegrity, configureStorage, disposeStorage, getEcosystemStorage, getStorage } from "./storage.mjs";
|
|
6
|
+
import { DEFAULT_TTL, EntryType, Lockfile, LockfileEntry, cacheKey, getFreshEntry, isFresh, pruneStale, readLockfile, removeEntry, setEntry, writeLockfile } from "./lockfile.mjs";
|
|
7
|
+
import { Storage } from "unstorage";
|
|
8
|
+
|
|
9
|
+
//#region src/cache/index.d.ts
|
|
10
|
+
/** Options for creating a cached registry. */
|
|
11
|
+
interface CreateCachedOptions {
|
|
12
|
+
/** Custom base URL for the registry API. */
|
|
13
|
+
baseURL?: string;
|
|
14
|
+
/** Custom HTTP client. */
|
|
15
|
+
client?: Client;
|
|
16
|
+
/** Custom unstorage instance. Overrides the globally configured storage. */
|
|
17
|
+
storage?: Storage;
|
|
18
|
+
}
|
|
19
|
+
/** Create a registry instance with caching + lockfile tracking. */
|
|
20
|
+
declare function createCached(ecosystem: string, options?: CreateCachedOptions): Registry;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { CachedRegistry, CreateCachedOptions, DEFAULT_TTL, type EntryType, type Lockfile, type LockfileEntry, cacheKey, clearStorage, computeIntegrity, configureStorage, createCached, disposeStorage, getCacheDir, getEcosystemStorage, getFreshEntry, getStorage, isFresh, pruneStale, readLockfile, removeEntry, setEntry, writeLockfile };
|
|
23
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/cache/index.ts"],"mappings":";;;;;;;;;;UA+BiB,mBAAA;EAAmB;EAElC,OAAA;EAIiB;EAFjB,MAAA,GAAS,MAAA;EAAT;EAEA,OAAA,GAAU,OAAA;AAAA;;iBAII,YAAA,CAAa,SAAA,UAAmB,OAAA,GAAU,mBAAA,GAAsB,QAAA"}
|
|
@@ -1,2 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Storage } from "unstorage";
|
|
2
|
+
|
|
3
|
+
//#region src/cache/lockfile.d.ts
|
|
4
|
+
/** Default TTL per data type (seconds). */
|
|
5
|
+
declare const DEFAULT_TTL: {
|
|
6
|
+
readonly package: 3600;
|
|
7
|
+
readonly versions: 1800;
|
|
8
|
+
readonly dependencies: 86400;
|
|
9
|
+
readonly maintainers: 86400;
|
|
10
|
+
};
|
|
11
|
+
type EntryType = keyof typeof DEFAULT_TTL;
|
|
12
|
+
/** A single cached entry tracked in the lockfile. */
|
|
13
|
+
interface LockfileEntry {
|
|
14
|
+
/** PURL-style key: 'npm:lodash', 'cargo:serde' */
|
|
15
|
+
key: string;
|
|
16
|
+
/** What kind of data: package, versions, dependencies, maintainers */
|
|
17
|
+
type: EntryType;
|
|
18
|
+
/** Unix timestamp (ms) when fetched */
|
|
19
|
+
fetchedAt: number;
|
|
20
|
+
/** TTL in seconds */
|
|
21
|
+
ttl: number;
|
|
22
|
+
/** Latest version at time of caching (for package entries) */
|
|
23
|
+
latestVersion?: string;
|
|
24
|
+
/** Content hash (sha256 of JSON-serialized value) for integrity */
|
|
25
|
+
integrity: string;
|
|
26
|
+
}
|
|
27
|
+
/** The full lockfile structure. */
|
|
28
|
+
interface Lockfile {
|
|
29
|
+
version: number;
|
|
30
|
+
entries: Record<string, LockfileEntry>;
|
|
31
|
+
}
|
|
32
|
+
/** Read the lockfile from storage. Returns empty lockfile if not found or invalid. */
|
|
33
|
+
declare function readLockfile(storage?: Storage): Promise<Lockfile>;
|
|
34
|
+
/** Write the lockfile to storage. */
|
|
35
|
+
declare function writeLockfile(lockfile: Lockfile, storage?: Storage): Promise<void>;
|
|
36
|
+
/** Build a cache key from ecosystem + name + type + optional version. */
|
|
37
|
+
declare function cacheKey(ecosystem: string, name: string, type: EntryType, version?: string): string;
|
|
38
|
+
/** Check if a lockfile entry is still fresh. */
|
|
39
|
+
declare function isFresh(entry: LockfileEntry): boolean;
|
|
40
|
+
/** Get a lockfile entry if it exists and is fresh. Returns null otherwise. */
|
|
41
|
+
declare function getFreshEntry(lockfile: Lockfile, key: string): LockfileEntry | null;
|
|
42
|
+
/** Upsert an entry in the lockfile. Does NOT persist — call writeLockfile() after. */
|
|
43
|
+
declare function setEntry(lockfile: Lockfile, entry: LockfileEntry): void;
|
|
44
|
+
/** Remove an entry from the lockfile. */
|
|
45
|
+
declare function removeEntry(lockfile: Lockfile, key: string): void;
|
|
46
|
+
/** Remove all stale entries from the lockfile. Returns count of removed entries. */
|
|
47
|
+
declare function pruneStale(lockfile: Lockfile): number;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { DEFAULT_TTL, EntryType, Lockfile, LockfileEntry, cacheKey, getFreshEntry, isFresh, pruneStale, readLockfile, removeEntry, setEntry, writeLockfile };
|
|
50
|
+
//# sourceMappingURL=lockfile.d.mts.map
|
package/dist/cache/paths.d.mts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/cache/paths.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the cache directory following platform conventions:
|
|
4
|
+
* - Linux: $XDG_CACHE_HOME/registries or ~/.cache/registries
|
|
5
|
+
* - macOS: ~/Library/Caches/registries
|
|
6
|
+
* - Windows: %LOCALAPPDATA%/registries/cache
|
|
7
|
+
*/
|
|
8
|
+
declare function getCacheDir(): string;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getCacheDir };
|
|
11
|
+
//# sourceMappingURL=paths.d.mts.map
|
package/dist/cache/storage.d.mts
CHANGED
|
@@ -1,2 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Storage } from "unstorage";
|
|
2
|
+
|
|
3
|
+
//#region src/cache/storage.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Configure a custom unstorage instance for @agntn/registries.
|
|
6
|
+
* Call this before any cache operations to use a non-default driver
|
|
7
|
+
* (e.g. Cloudflare KV, Redis, memory).
|
|
8
|
+
*/
|
|
9
|
+
declare function configureStorage(storage: Storage): void;
|
|
10
|
+
/** Get or create the shared storage instance. Uses configured storage or falls back to fs driver. */
|
|
11
|
+
declare function getStorage(): Storage;
|
|
12
|
+
/** Get a namespaced storage for a specific ecosystem (e.g. 'npm', 'cargo'). */
|
|
13
|
+
declare function getEcosystemStorage(ecosystem: string): Storage;
|
|
14
|
+
/** Compute a sha256 integrity hash of a JSON-serializable value. */
|
|
15
|
+
declare function computeIntegrity(value: unknown): string;
|
|
16
|
+
/** Dispose the storage instance. Call on process exit. */
|
|
17
|
+
declare function disposeStorage(): Promise<void>;
|
|
18
|
+
/** Clear all cached data. */
|
|
19
|
+
declare function clearStorage(): Promise<void>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { clearStorage, computeIntegrity, configureStorage, disposeStorage, getEcosystemStorage, getStorage };
|
|
22
|
+
//# sourceMappingURL=storage.d.mts.map
|
package/dist/commands/deps.mjs
CHANGED
|
@@ -27,7 +27,7 @@ var deps_default = defineCommand({
|
|
|
27
27
|
consola.info("Example: pkg:npm/lodash@4.17.21");
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
|
-
consola.info(`No version specified, using latest: ${pkg.latestVersion}`);
|
|
30
|
+
if (!args.json) consola.info(`No version specified, using latest: ${pkg.latestVersion}`);
|
|
31
31
|
const deps = await reg.fetchDependencies(name, pkg.latestVersion);
|
|
32
32
|
outputDeps(name, pkg.latestVersion, deps, args.json);
|
|
33
33
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.mjs","names":[],"sources":["../../src/commands/deps.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { sharedArgs, resolvePURL, withErrorHandling } from \"./shared.ts\";\n\nexport default defineCommand({\n meta: {\n name: \"deps\",\n description: \"List package dependencies\",\n },\n args: {\n ...sharedArgs,\n purl: {\n type: \"positional\",\n description: \"Package PURL with version (e.g. pkg:npm/lodash@4.17.21, cargo/serde@1.0)\",\n required: true,\n },\n },\n async run({ args }) {\n await withErrorHandling(async () => {\n const [reg, name, version] = resolvePURL(args.purl, !args[\"no-cache\"]);\n\n if (!version) {\n // Try to resolve latest version\n const pkg = await reg.fetchPackage(name);\n if (!pkg.latestVersion) {\n consola.error(\n \"PURL must include a version for dependency lookup, and no latest version found.\",\n );\n consola.info(\"Example: pkg:npm/lodash@4.17.21\");\n process.exit(1);\n }\n consola.info(`No version specified, using latest: ${pkg.latestVersion}`);\n const deps = await reg.fetchDependencies(name, pkg.latestVersion);\n outputDeps(name, pkg.latestVersion, deps, args.json);\n return;\n }\n\n const deps = await reg.fetchDependencies(name, version);\n outputDeps(name, version, deps, args.json);\n });\n },\n});\n\nimport type { Dependency } from \"../core/types.ts\";\n\nfunction outputDeps(name: string, version: string, deps: Dependency[], json: boolean): void {\n if (json) {\n console.log(JSON.stringify(deps, null, 2));\n return;\n }\n\n consola.log(\"\");\n consola.log(\n ` \\x1b[1m${name}@${version}\\x1b[0m — ${deps.length} dependenc${deps.length === 1 ? \"y\" : \"ies\"}`,\n );\n consola.log(\"\");\n\n const byScope = new Map<string, Dependency[]>();\n for (const dep of deps) {\n const scope = dep.scope || \"runtime\";\n if (!byScope.has(scope)) byScope.set(scope, []);\n byScope.get(scope)!.push(dep);\n }\n\n const scopeColors: Record<string, string> = {\n runtime: \"\\x1b[32m\",\n development: \"\\x1b[33m\",\n build: \"\\x1b[35m\",\n test: \"\\x1b[36m\",\n optional: \"\\x1b[90m\",\n };\n\n for (const [scope, scopeDeps] of byScope) {\n const color = scopeColors[scope] ?? \"\\x1b[0m\";\n consola.log(` ${color}${scope}\\x1b[0m (${scopeDeps.length})`);\n for (const dep of scopeDeps) {\n const opt = dep.optional ? \" \\x1b[90m(optional)\\x1b[0m\" : \"\";\n consola.log(` ${dep.name} \\x1b[90m${dep.requirements}\\x1b[0m${opt}`);\n }\n consola.log(\"\");\n }\n}\n"],"mappings":";;;;;;AAIA,IAAA,eAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,GAAG;EACH,MAAM;GACJ,MAAM;GACN,aAAa;GACb,UAAU;;EAEb;CACD,MAAM,IAAI,EAAE,QAAQ;AAClB,QAAM,kBAAkB,YAAY;GAClC,MAAM,CAAC,KAAK,MAAM,WAAW,YAAY,KAAK,MAAM,CAAC,KAAK,YAAY;AAEtE,OAAI,CAAC,SAAS;IAEZ,MAAM,MAAM,MAAM,IAAI,aAAa,KAAK;AACxC,QAAI,CAAC,IAAI,eAAe;AACtB,aAAQ,MACN,kFACD;AACD,aAAQ,KAAK,kCAAkC;AAC/C,aAAQ,KAAK,EAAE;;AAEjB,
|
|
1
|
+
{"version":3,"file":"deps.mjs","names":[],"sources":["../../src/commands/deps.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { sharedArgs, resolvePURL, withErrorHandling } from \"./shared.ts\";\n\nexport default defineCommand({\n meta: {\n name: \"deps\",\n description: \"List package dependencies\",\n },\n args: {\n ...sharedArgs,\n purl: {\n type: \"positional\",\n description: \"Package PURL with version (e.g. pkg:npm/lodash@4.17.21, cargo/serde@1.0)\",\n required: true,\n },\n },\n async run({ args }) {\n await withErrorHandling(async () => {\n const [reg, name, version] = resolvePURL(args.purl, !args[\"no-cache\"]);\n\n if (!version) {\n // Try to resolve latest version\n const pkg = await reg.fetchPackage(name);\n if (!pkg.latestVersion) {\n consola.error(\n \"PURL must include a version for dependency lookup, and no latest version found.\",\n );\n consola.info(\"Example: pkg:npm/lodash@4.17.21\");\n process.exit(1);\n }\n if (!args.json) {\n consola.info(`No version specified, using latest: ${pkg.latestVersion}`);\n }\n const deps = await reg.fetchDependencies(name, pkg.latestVersion);\n outputDeps(name, pkg.latestVersion, deps, args.json);\n return;\n }\n\n const deps = await reg.fetchDependencies(name, version);\n outputDeps(name, version, deps, args.json);\n });\n },\n});\n\nimport type { Dependency } from \"../core/types.ts\";\n\nfunction outputDeps(name: string, version: string, deps: Dependency[], json: boolean): void {\n if (json) {\n console.log(JSON.stringify(deps, null, 2));\n return;\n }\n\n consola.log(\"\");\n consola.log(\n ` \\x1b[1m${name}@${version}\\x1b[0m — ${deps.length} dependenc${deps.length === 1 ? \"y\" : \"ies\"}`,\n );\n consola.log(\"\");\n\n const byScope = new Map<string, Dependency[]>();\n for (const dep of deps) {\n const scope = dep.scope || \"runtime\";\n if (!byScope.has(scope)) byScope.set(scope, []);\n byScope.get(scope)!.push(dep);\n }\n\n const scopeColors: Record<string, string> = {\n runtime: \"\\x1b[32m\",\n development: \"\\x1b[33m\",\n build: \"\\x1b[35m\",\n test: \"\\x1b[36m\",\n optional: \"\\x1b[90m\",\n };\n\n for (const [scope, scopeDeps] of byScope) {\n const color = scopeColors[scope] ?? \"\\x1b[0m\";\n consola.log(` ${color}${scope}\\x1b[0m (${scopeDeps.length})`);\n for (const dep of scopeDeps) {\n const opt = dep.optional ? \" \\x1b[90m(optional)\\x1b[0m\" : \"\";\n consola.log(` ${dep.name} \\x1b[90m${dep.requirements}\\x1b[0m${opt}`);\n }\n consola.log(\"\");\n }\n}\n"],"mappings":";;;;;;AAIA,IAAA,eAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,GAAG;EACH,MAAM;GACJ,MAAM;GACN,aAAa;GACb,UAAU;;EAEb;CACD,MAAM,IAAI,EAAE,QAAQ;AAClB,QAAM,kBAAkB,YAAY;GAClC,MAAM,CAAC,KAAK,MAAM,WAAW,YAAY,KAAK,MAAM,CAAC,KAAK,YAAY;AAEtE,OAAI,CAAC,SAAS;IAEZ,MAAM,MAAM,MAAM,IAAI,aAAa,KAAK;AACxC,QAAI,CAAC,IAAI,eAAe;AACtB,aAAQ,MACN,kFACD;AACD,aAAQ,KAAK,kCAAkC;AAC/C,aAAQ,KAAK,EAAE;;AAEjB,QAAI,CAAC,KAAK,KACR,SAAQ,KAAK,uCAAuC,IAAI,gBAAgB;IAE1E,MAAM,OAAO,MAAM,IAAI,kBAAkB,MAAM,IAAI,cAAc;AACjE,eAAW,MAAM,IAAI,eAAe,MAAM,KAAK,KAAK;AACpD;;AAIF,cAAW,MAAM,SADJ,MAAM,IAAI,kBAAkB,MAAM,QAAQ,EACvB,KAAK,KAAK;IAC1C;;CAEL,CAAC;AAIF,SAAS,WAAW,MAAc,SAAiB,MAAoB,MAAqB;AAC1F,KAAI,MAAM;AACR,UAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;AAC1C;;AAGF,SAAQ,IAAI,GAAG;AACf,SAAQ,IACN,YAAY,KAAK,GAAG,QAAQ,YAAY,KAAK,OAAO,YAAY,KAAK,WAAW,IAAI,MAAM,QAC3F;AACD,SAAQ,IAAI,GAAG;CAEf,MAAM,0BAAU,IAAI,KAA2B;AAC/C,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,IAAI,SAAS;AAC3B,MAAI,CAAC,QAAQ,IAAI,MAAM,CAAE,SAAQ,IAAI,OAAO,EAAE,CAAC;AAC/C,UAAQ,IAAI,MAAM,CAAE,KAAK,IAAI;;CAG/B,MAAM,cAAsC;EAC1C,SAAS;EACT,aAAa;EACb,OAAO;EACP,MAAM;EACN,UAAU;EACX;AAED,MAAK,MAAM,CAAC,OAAO,cAAc,SAAS;EACxC,MAAM,QAAQ,YAAY,UAAU;AACpC,UAAQ,IAAI,KAAK,QAAQ,MAAM,WAAW,UAAU,OAAO,GAAG;AAC9D,OAAK,MAAM,OAAO,WAAW;GAC3B,MAAM,MAAM,IAAI,WAAW,+BAA+B;AAC1D,WAAQ,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,aAAa,SAAS,MAAM;;AAEzE,UAAQ,IAAI,GAAG"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,57 @@
|
|
|
1
1
|
import { a as ParsedPURL, c as URLBuilder, i as Package, l as Version, n as Dependency, o as RateLimiter, r as Maintainer, s as Scope, t as ClientOptions, u as VersionStatus } from "./_chunks/types.mjs";
|
|
2
2
|
import { a as register, i as has, n as create, o as Client, r as ecosystems, s as defaultClient, t as Registry } from "./_chunks/registry.mjs";
|
|
3
3
|
import { a as CargoRegistry, i as PyPIRegistry, n as PackagistRegistry, o as NpmRegistry, r as RubyGemsRegistry, t as AlpmRegistry } from "./_chunks/index.mjs";
|
|
4
|
+
import { CachedRegistry } from "./cache/cached-registry.mjs";
|
|
5
|
+
import { getCacheDir } from "./cache/paths.mjs";
|
|
6
|
+
import { clearStorage, computeIntegrity, configureStorage, disposeStorage, getEcosystemStorage, getStorage } from "./cache/storage.mjs";
|
|
7
|
+
import { DEFAULT_TTL, EntryType, Lockfile, LockfileEntry, cacheKey, getFreshEntry, isFresh, pruneStale, readLockfile, removeEntry, setEntry, writeLockfile } from "./cache/lockfile.mjs";
|
|
8
|
+
import { CreateCachedOptions, createCached } from "./cache/index.mjs";
|
|
4
9
|
import { a as RateLimitError, c as combineLicenses, d as createFromPURL, f as fullName, i as PkioError, l as normalizeLicense, n as InvalidPURLError, o as UnknownEcosystemError, p as parsePURL, r as NotFoundError, s as normalizeRepositoryURL, t as HTTPError, u as buildPURL } from "./_chunks/errors.mjs";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
|
|
11
|
+
//#region src/helpers.d.ts
|
|
12
|
+
/** Fetch normalized package metadata from a PURL. */
|
|
13
|
+
declare function fetchPackageFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Package>;
|
|
14
|
+
/** Fetch all versions from a PURL. */
|
|
15
|
+
declare function fetchVersionsFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Version[]>;
|
|
16
|
+
/** Fetch dependencies for a specific version from a PURL. */
|
|
17
|
+
declare function fetchDependenciesFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Dependency[]>;
|
|
18
|
+
/** Fetch maintainers from a PURL. */
|
|
19
|
+
declare function fetchMaintainersFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Maintainer[]>;
|
|
20
|
+
/** Bulk fetch packages from multiple PURLs, with concurrency limit. */
|
|
21
|
+
declare function bulkFetchPackages(purls: string[], options?: {
|
|
22
|
+
concurrency?: number;
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
client?: Client;
|
|
25
|
+
}): Promise<Map<string, Package>>;
|
|
26
|
+
/**
|
|
27
|
+
* Select the best matching version from a list.
|
|
28
|
+
*
|
|
29
|
+
* Resolution order:
|
|
30
|
+
* 1. Exact match for `requested` (non-yanked/deprecated/retracted)
|
|
31
|
+
* 2. Exact match for `latest` (non-yanked/deprecated/retracted)
|
|
32
|
+
* 3. Newest available version with no negative status (by publishedAt)
|
|
33
|
+
*
|
|
34
|
+
* Returns `null` when no usable version exists.
|
|
35
|
+
*/
|
|
36
|
+
declare function selectVersion(versions: Version[], options?: {
|
|
37
|
+
requested?: string;
|
|
38
|
+
latest?: string;
|
|
39
|
+
}): Version | null;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the best documentation URL for a package.
|
|
42
|
+
*
|
|
43
|
+
* Fallback chain:
|
|
44
|
+
* 1. `package.documentation` (explicit docs URL from registry)
|
|
45
|
+
* 2. `package.homepage` (project homepage)
|
|
46
|
+
* 3. `urls.documentation()` (ecosystem default, e.g. docs.rs, rubydoc.info)
|
|
47
|
+
*/
|
|
48
|
+
declare function resolveDocsUrl(pkg: Package, urls: URLBuilder, version?: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the best README URL for a package.
|
|
51
|
+
*
|
|
52
|
+
* Returns the ecosystem-specific URL where the package README can be fetched.
|
|
53
|
+
*/
|
|
54
|
+
declare function resolveReadmeUrl(pkg: Package, urls: URLBuilder, version?: string): string;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { AlpmRegistry, CachedRegistry, CargoRegistry, Client, type ClientOptions, type CreateCachedOptions, DEFAULT_TTL, type Dependency, type EntryType, HTTPError, InvalidPURLError, type Lockfile, type LockfileEntry, type Maintainer, NotFoundError, NpmRegistry, type Package, PackagistRegistry, type ParsedPURL, PkioError, PyPIRegistry, RateLimitError, type RateLimiter, Registry, RubyGemsRegistry, type Scope, type URLBuilder, UnknownEcosystemError, type Version, type VersionStatus, buildPURL, bulkFetchPackages, cacheKey, clearStorage, combineLicenses, computeIntegrity, configureStorage, create, createCached, createFromPURL, defaultClient, disposeStorage, ecosystems, fetchDependenciesFromPURL, fetchMaintainersFromPURL, fetchPackageFromPURL, fetchVersionsFromPURL, fullName, getCacheDir, getEcosystemStorage, getFreshEntry, getStorage, has, isFresh, normalizeLicense, normalizeRepositoryURL, parsePURL, pruneStale, readLockfile, register, removeEntry, resolveDocsUrl, resolveReadmeUrl, selectVersion, setEntry, writeLockfile };
|
|
57
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/helpers.ts"],"mappings":";;;;;;;;;;;;iBAMsB,oBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,OAAA;;iBAMW,qBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,OAAA;;iBAMW,yBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,UAAA;;iBASW,wBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,UAAA;;iBAQW,iBAAA,CACpB,KAAA,YACA,OAAA;EAAY,WAAA;EAAsB,MAAA,GAAS,WAAA;EAAa,MAAA,GAAS,MAAA;AAAA,IAChE,OAAA,CAAQ,GAAA,SAAY,OAAA;;;;;;;;;;;iBAoCP,aAAA,CACd,QAAA,EAAU,OAAA,IACV,OAAA;EACE,SAAA;EACA,MAAA;AAAA,IAED,OAAA;;;;;;;;;iBAiCa,cAAA,CAAe,GAAA,EAAK,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,OAAA;;;;;;iBAS/C,gBAAA,CAAiB,GAAA,EAAK,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { c as URLBuilder, i as Package, l as Version, n as Dependency, r as Maintainer } from "./types.mjs";
|
|
2
|
-
import { t as Registry } from "./registry.mjs";
|
|
3
|
-
import { Storage } from "unstorage";
|
|
4
|
-
|
|
5
|
-
//#region src/cache/cached-registry.d.ts
|
|
6
|
-
/**
|
|
7
|
-
* CachedRegistry wraps any Registry and adds caching backed by unstorage
|
|
8
|
-
* with a lockfile for freshness tracking.
|
|
9
|
-
*
|
|
10
|
-
* Pass a custom `storage` to use a non-default driver (e.g. Cloudflare KV).
|
|
11
|
-
* If omitted, uses the globally configured storage (see `configureStorage()`).
|
|
12
|
-
*/
|
|
13
|
-
declare class CachedRegistry extends Registry {
|
|
14
|
-
readonly inner: Registry;
|
|
15
|
-
readonly storage: Storage;
|
|
16
|
-
private readonly lockfileStorage;
|
|
17
|
-
private readonly inflight;
|
|
18
|
-
constructor(inner: Registry, storage?: Storage);
|
|
19
|
-
ecosystem(): string;
|
|
20
|
-
urls(): URLBuilder;
|
|
21
|
-
fetchPackage(name: string, signal?: AbortSignal): Promise<Package>;
|
|
22
|
-
fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]>;
|
|
23
|
-
fetchDependencies(name: string, version: string, signal?: AbortSignal): Promise<Dependency[]>;
|
|
24
|
-
fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;
|
|
25
|
-
/**
|
|
26
|
-
* Generic cache-through method:
|
|
27
|
-
* 1. Check lockfile for fresh entry
|
|
28
|
-
* 2. If fresh -> read from storage
|
|
29
|
-
* 3. If stale/missing -> fetch, store, update lockfile
|
|
30
|
-
*/
|
|
31
|
-
private cached;
|
|
32
|
-
}
|
|
33
|
-
//#endregion
|
|
34
|
-
export { CachedRegistry as t };
|
|
35
|
-
//# sourceMappingURL=cached-registry.d.mts.map
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { c as URLBuilder, i as Package, l as Version, n as Dependency, r as Maintainer } from "./types.mjs";
|
|
2
|
-
import { o as Client } from "./registry.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/helpers.d.ts
|
|
5
|
-
/** Fetch normalized package metadata from a PURL. */
|
|
6
|
-
declare function fetchPackageFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Package>;
|
|
7
|
-
/** Fetch all versions from a PURL. */
|
|
8
|
-
declare function fetchVersionsFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Version[]>;
|
|
9
|
-
/** Fetch dependencies for a specific version from a PURL. */
|
|
10
|
-
declare function fetchDependenciesFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Dependency[]>;
|
|
11
|
-
/** Fetch maintainers from a PURL. */
|
|
12
|
-
declare function fetchMaintainersFromPURL(purl: string, signal?: AbortSignal, client?: Client): Promise<Maintainer[]>;
|
|
13
|
-
/** Bulk fetch packages from multiple PURLs, with concurrency limit. */
|
|
14
|
-
declare function bulkFetchPackages(purls: string[], options?: {
|
|
15
|
-
concurrency?: number;
|
|
16
|
-
signal?: AbortSignal;
|
|
17
|
-
client?: Client;
|
|
18
|
-
}): Promise<Map<string, Package>>;
|
|
19
|
-
/**
|
|
20
|
-
* Select the best matching version from a list.
|
|
21
|
-
*
|
|
22
|
-
* Resolution order:
|
|
23
|
-
* 1. Exact match for `requested` (non-yanked/deprecated/retracted)
|
|
24
|
-
* 2. Exact match for `latest` (non-yanked/deprecated/retracted)
|
|
25
|
-
* 3. Newest available version with no negative status (by publishedAt)
|
|
26
|
-
*
|
|
27
|
-
* Returns `null` when no usable version exists.
|
|
28
|
-
*/
|
|
29
|
-
declare function selectVersion(versions: Version[], options?: {
|
|
30
|
-
requested?: string;
|
|
31
|
-
latest?: string;
|
|
32
|
-
}): Version | null;
|
|
33
|
-
/**
|
|
34
|
-
* Resolve the best documentation URL for a package.
|
|
35
|
-
*
|
|
36
|
-
* Fallback chain:
|
|
37
|
-
* 1. `package.documentation` (explicit docs URL from registry)
|
|
38
|
-
* 2. `package.homepage` (project homepage)
|
|
39
|
-
* 3. `urls.documentation()` (ecosystem default, e.g. docs.rs, rubydoc.info)
|
|
40
|
-
*/
|
|
41
|
-
declare function resolveDocsUrl(pkg: Package, urls: URLBuilder, version?: string): string;
|
|
42
|
-
/**
|
|
43
|
-
* Resolve the best README URL for a package.
|
|
44
|
-
*
|
|
45
|
-
* Returns the ecosystem-specific URL where the package README can be fetched.
|
|
46
|
-
*/
|
|
47
|
-
declare function resolveReadmeUrl(pkg: Package, urls: URLBuilder, version?: string): string;
|
|
48
|
-
//#endregion
|
|
49
|
-
export { fetchVersionsFromPURL as a, selectVersion as c, fetchPackageFromPURL as i, fetchDependenciesFromPURL as n, resolveDocsUrl as o, fetchMaintainersFromPURL as r, resolveReadmeUrl as s, bulkFetchPackages as t };
|
|
50
|
-
//# sourceMappingURL=index2.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index2.d.mts","names":[],"sources":["../../src/helpers.ts"],"mappings":";;;;;iBAMsB,oBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,OAAA;AAJX;AAAA,iBAUsB,qBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,OAAA;;iBAMW,yBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,UAAA;;iBASW,wBAAA,CACpB,IAAA,UACA,MAAA,GAAS,WAAA,EACT,MAAA,GAAS,MAAA,GACR,OAAA,CAAQ,UAAA;;iBAQW,iBAAA,CACpB,KAAA,YACA,OAAA;EAAY,WAAA;EAAsB,MAAA,GAAS,WAAA;EAAa,MAAA,GAAS,MAAA;AAAA,IAChE,OAAA,CAAQ,GAAA,SAAY,OAAA;;;;;;;AAtCvB;;;;iBA0EgB,aAAA,CACd,QAAA,EAAU,OAAA,IACV,OAAA;EACE,SAAA;EACA,MAAA;AAAA,IAED,OAAA;;;;;;;;;iBAiCa,cAAA,CAAe,GAAA,EAAK,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,OAAA;;AAvG/D;;;;iBAgHgB,gBAAA,CAAiB,GAAA,EAAK,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,OAAA"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { o as Client, t as Registry } from "./registry.mjs";
|
|
2
|
-
import { Storage } from "unstorage";
|
|
3
|
-
|
|
4
|
-
//#region src/cache/index.d.ts
|
|
5
|
-
/** Options for creating a cached registry. */
|
|
6
|
-
interface CreateCachedOptions {
|
|
7
|
-
/** Custom base URL for the registry API. */
|
|
8
|
-
baseURL?: string;
|
|
9
|
-
/** Custom HTTP client. */
|
|
10
|
-
client?: Client;
|
|
11
|
-
/** Custom unstorage instance. Overrides the globally configured storage. */
|
|
12
|
-
storage?: Storage;
|
|
13
|
-
}
|
|
14
|
-
/** Create a registry instance with caching + lockfile tracking. */
|
|
15
|
-
declare function createCached(ecosystem: string, options?: CreateCachedOptions): Registry;
|
|
16
|
-
//#endregion
|
|
17
|
-
export { createCached as n, CreateCachedOptions as t };
|
|
18
|
-
//# sourceMappingURL=index3.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index3.d.mts","names":[],"sources":["../../src/cache/index.ts"],"mappings":";;;;;UA+BiB,mBAAA;EAIN;EAFT,OAAA;EAIU;EAFV,MAAA,GAAS,MAAA;EAEQ;EAAjB,OAAA,GAAU,OAAA;AAAA;;iBAII,YAAA,CAAa,SAAA,UAAmB,OAAA,GAAU,mBAAA,GAAsB,QAAA"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Storage } from "unstorage";
|
|
2
|
-
|
|
3
|
-
//#region src/cache/lockfile.d.ts
|
|
4
|
-
/** Default TTL per data type (seconds). */
|
|
5
|
-
declare const DEFAULT_TTL: {
|
|
6
|
-
readonly package: 3600;
|
|
7
|
-
readonly versions: 1800;
|
|
8
|
-
readonly dependencies: 86400;
|
|
9
|
-
readonly maintainers: 86400;
|
|
10
|
-
};
|
|
11
|
-
type EntryType = keyof typeof DEFAULT_TTL;
|
|
12
|
-
/** A single cached entry tracked in the lockfile. */
|
|
13
|
-
interface LockfileEntry {
|
|
14
|
-
/** PURL-style key: 'npm:lodash', 'cargo:serde' */
|
|
15
|
-
key: string;
|
|
16
|
-
/** What kind of data: package, versions, dependencies, maintainers */
|
|
17
|
-
type: EntryType;
|
|
18
|
-
/** Unix timestamp (ms) when fetched */
|
|
19
|
-
fetchedAt: number;
|
|
20
|
-
/** TTL in seconds */
|
|
21
|
-
ttl: number;
|
|
22
|
-
/** Latest version at time of caching (for package entries) */
|
|
23
|
-
latestVersion?: string;
|
|
24
|
-
/** Content hash (sha256 of JSON-serialized value) for integrity */
|
|
25
|
-
integrity: string;
|
|
26
|
-
}
|
|
27
|
-
/** The full lockfile structure. */
|
|
28
|
-
interface Lockfile {
|
|
29
|
-
version: number;
|
|
30
|
-
entries: Record<string, LockfileEntry>;
|
|
31
|
-
}
|
|
32
|
-
/** Read the lockfile from storage. Returns empty lockfile if not found or invalid. */
|
|
33
|
-
declare function readLockfile(storage?: Storage): Promise<Lockfile>;
|
|
34
|
-
/** Write the lockfile to storage. */
|
|
35
|
-
declare function writeLockfile(lockfile: Lockfile, storage?: Storage): Promise<void>;
|
|
36
|
-
/** Build a cache key from ecosystem + name + type + optional version. */
|
|
37
|
-
declare function cacheKey(ecosystem: string, name: string, type: EntryType, version?: string): string;
|
|
38
|
-
/** Check if a lockfile entry is still fresh. */
|
|
39
|
-
declare function isFresh(entry: LockfileEntry): boolean;
|
|
40
|
-
/** Get a lockfile entry if it exists and is fresh. Returns null otherwise. */
|
|
41
|
-
declare function getFreshEntry(lockfile: Lockfile, key: string): LockfileEntry | null;
|
|
42
|
-
/** Upsert an entry in the lockfile. Does NOT persist — call writeLockfile() after. */
|
|
43
|
-
declare function setEntry(lockfile: Lockfile, entry: LockfileEntry): void;
|
|
44
|
-
/** Remove an entry from the lockfile. */
|
|
45
|
-
declare function removeEntry(lockfile: Lockfile, key: string): void;
|
|
46
|
-
/** Remove all stale entries from the lockfile. Returns count of removed entries. */
|
|
47
|
-
declare function pruneStale(lockfile: Lockfile): number;
|
|
48
|
-
//#endregion
|
|
49
|
-
export { cacheKey as a, pruneStale as c, setEntry as d, writeLockfile as f, LockfileEntry as i, readLockfile as l, EntryType as n, getFreshEntry as o, Lockfile as r, isFresh as s, DEFAULT_TTL as t, removeEntry as u };
|
|
50
|
-
//# sourceMappingURL=lockfile.d.mts.map
|
package/dist/_chunks/paths.d.mts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
//#region src/cache/paths.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Resolve the cache directory following platform conventions:
|
|
4
|
-
* - Linux: $XDG_CACHE_HOME/registries or ~/.cache/registries
|
|
5
|
-
* - macOS: ~/Library/Caches/registries
|
|
6
|
-
* - Windows: %LOCALAPPDATA%/registries/cache
|
|
7
|
-
*/
|
|
8
|
-
declare function getCacheDir(): string;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { getCacheDir as t };
|
|
11
|
-
//# sourceMappingURL=paths.d.mts.map
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Storage } from "unstorage";
|
|
2
|
-
|
|
3
|
-
//#region src/cache/storage.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Configure a custom unstorage instance for @agntn/registries.
|
|
6
|
-
* Call this before any cache operations to use a non-default driver
|
|
7
|
-
* (e.g. Cloudflare KV, Redis, memory).
|
|
8
|
-
*/
|
|
9
|
-
declare function configureStorage(storage: Storage): void;
|
|
10
|
-
/** Get or create the shared storage instance. Uses configured storage or falls back to fs driver. */
|
|
11
|
-
declare function getStorage(): Storage;
|
|
12
|
-
/** Get a namespaced storage for a specific ecosystem (e.g. 'npm', 'cargo'). */
|
|
13
|
-
declare function getEcosystemStorage(ecosystem: string): Storage;
|
|
14
|
-
/** Compute a sha256 integrity hash of a JSON-serializable value. */
|
|
15
|
-
declare function computeIntegrity(value: unknown): string;
|
|
16
|
-
/** Dispose the storage instance. Call on process exit. */
|
|
17
|
-
declare function disposeStorage(): Promise<void>;
|
|
18
|
-
/** Clear all cached data. */
|
|
19
|
-
declare function clearStorage(): Promise<void>;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { getEcosystemStorage as a, disposeStorage as i, computeIntegrity as n, getStorage as o, configureStorage as r, clearStorage as t };
|
|
22
|
-
//# sourceMappingURL=storage.d.mts.map
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|