@agntn/registries 0.2.0 → 0.3.1

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.
Files changed (113) hide show
  1. package/README.md +26 -3
  2. package/dist/THIRD-PARTY-LICENSES.md +36 -0
  3. package/dist/_chunks/cache.mjs +15 -0
  4. package/dist/{cache/index.mjs.map → _chunks/cache.mjs.map} +1 -1
  5. package/dist/{commands/cache.mjs → _chunks/cache2.mjs} +6 -8
  6. package/dist/_chunks/cache2.mjs.map +1 -0
  7. package/dist/{cache → _chunks}/cached-registry.mjs +12 -8
  8. package/dist/_chunks/cached-registry.mjs.map +1 -0
  9. package/dist/{commands → _chunks}/deps.mjs +20 -14
  10. package/dist/_chunks/deps.mjs.map +1 -0
  11. package/dist/_chunks/helpers.mjs +53 -19
  12. package/dist/_chunks/helpers.mjs.map +1 -1
  13. package/dist/_chunks/index.d.mts +9 -23
  14. package/dist/_chunks/index.d.mts.map +1 -1
  15. package/dist/_chunks/index2.d.mts +156 -25
  16. package/dist/_chunks/index2.d.mts.map +1 -1
  17. package/dist/_chunks/index3.d.mts +173 -3
  18. package/dist/_chunks/index3.d.mts.map +1 -1
  19. package/dist/_chunks/info.mjs +105 -0
  20. package/dist/_chunks/info.mjs.map +1 -0
  21. package/dist/_chunks/libs/typebox.mjs +278 -0
  22. package/dist/_chunks/libs/typebox.mjs.map +1 -0
  23. package/dist/_chunks/lockfile.mjs +183 -0
  24. package/dist/_chunks/lockfile.mjs.map +1 -0
  25. package/dist/_chunks/maintainers.mjs +53 -0
  26. package/dist/_chunks/maintainers.mjs.map +1 -0
  27. package/dist/_chunks/mcp.mjs +15 -0
  28. package/dist/_chunks/mcp.mjs.map +1 -0
  29. package/dist/_chunks/registries.mjs +514 -245
  30. package/dist/_chunks/registries.mjs.map +1 -1
  31. package/dist/_chunks/registry.d.mts +121 -10
  32. package/dist/_chunks/registry.d.mts.map +1 -1
  33. package/dist/_chunks/registry.mjs +121 -31
  34. package/dist/_chunks/registry.mjs.map +1 -1
  35. package/dist/{commands → _chunks}/shared.mjs +15 -8
  36. package/dist/_chunks/shared.mjs.map +1 -0
  37. package/dist/_chunks/tool-operations.mjs +63 -0
  38. package/dist/_chunks/tool-operations.mjs.map +1 -0
  39. package/dist/_chunks/version.mjs +4 -0
  40. package/dist/_chunks/version.mjs.map +1 -0
  41. package/dist/{commands → _chunks}/versions.mjs +10 -9
  42. package/dist/_chunks/versions.mjs.map +1 -0
  43. package/dist/ai.d.mts +2 -8
  44. package/dist/ai.d.mts.map +1 -1
  45. package/dist/ai.mjs +0 -1
  46. package/dist/ai.mjs.map +1 -1
  47. package/dist/cache/index.d.mts +1 -6
  48. package/dist/cache/index.mjs +4 -11
  49. package/dist/cli.mjs +9 -7
  50. package/dist/cli.mjs.map +1 -1
  51. package/dist/index.d.mts +3 -9
  52. package/dist/index.mjs +4 -7
  53. package/dist/mcp.d.mts +7 -0
  54. package/dist/mcp.d.mts.map +1 -0
  55. package/dist/mcp.mjs +155 -0
  56. package/dist/mcp.mjs.map +1 -0
  57. package/dist/registries/index.d.mts +0 -1
  58. package/dist/registries/index.mjs +0 -1
  59. package/dist/tool-operations.d.mts +36 -0
  60. package/dist/tool-operations.d.mts.map +1 -0
  61. package/dist/tool-operations.mjs +5 -0
  62. package/package.json +55 -9
  63. package/packages/omp/extensions/registries.ts +112 -0
  64. package/packages/pi/extensions/registries.ts +125 -0
  65. package/dist/_chunks/cached-registry.d.mts +0 -35
  66. package/dist/_chunks/cached-registry.d.mts.map +0 -1
  67. package/dist/_chunks/errors.d.mts +0 -90
  68. package/dist/_chunks/errors.d.mts.map +0 -1
  69. package/dist/_chunks/lockfile.d.mts +0 -50
  70. package/dist/_chunks/lockfile.d.mts.map +0 -1
  71. package/dist/_chunks/paths.d.mts +0 -11
  72. package/dist/_chunks/paths.d.mts.map +0 -1
  73. package/dist/_chunks/purl.mjs +0 -192
  74. package/dist/_chunks/purl.mjs.map +0 -1
  75. package/dist/_chunks/storage.d.mts +0 -22
  76. package/dist/_chunks/storage.d.mts.map +0 -1
  77. package/dist/_chunks/types.d.mts +0 -73
  78. package/dist/_chunks/types.d.mts.map +0 -1
  79. package/dist/cache/cached-registry.d.mts +0 -4
  80. package/dist/cache/cached-registry.mjs.map +0 -1
  81. package/dist/cache/lockfile.d.mts +0 -2
  82. package/dist/cache/lockfile.mjs +0 -68
  83. package/dist/cache/lockfile.mjs.map +0 -1
  84. package/dist/cache/paths.d.mts +0 -2
  85. package/dist/cache/paths.mjs +0 -26
  86. package/dist/cache/paths.mjs.map +0 -1
  87. package/dist/cache/storage.d.mts +0 -2
  88. package/dist/cache/storage.mjs +0 -40
  89. package/dist/cache/storage.mjs.map +0 -1
  90. package/dist/commands/cache.d.mts +0 -7
  91. package/dist/commands/cache.d.mts.map +0 -1
  92. package/dist/commands/cache.mjs.map +0 -1
  93. package/dist/commands/deps.d.mts +0 -23
  94. package/dist/commands/deps.d.mts.map +0 -1
  95. package/dist/commands/deps.mjs.map +0 -1
  96. package/dist/commands/info.d.mts +0 -26
  97. package/dist/commands/info.d.mts.map +0 -1
  98. package/dist/commands/info.mjs +0 -54
  99. package/dist/commands/info.mjs.map +0 -1
  100. package/dist/commands/maintainers.d.mts +0 -23
  101. package/dist/commands/maintainers.d.mts.map +0 -1
  102. package/dist/commands/maintainers.mjs +0 -46
  103. package/dist/commands/maintainers.mjs.map +0 -1
  104. package/dist/commands/shared.d.mts +0 -27
  105. package/dist/commands/shared.d.mts.map +0 -1
  106. package/dist/commands/shared.mjs.map +0 -1
  107. package/dist/commands/versions.d.mts +0 -31
  108. package/dist/commands/versions.d.mts.map +0 -1
  109. package/dist/commands/versions.mjs.map +0 -1
  110. package/dist/core/index.d.mts +0 -4
  111. package/dist/core/index.mjs +0 -3
  112. package/dist/types.d.mts +0 -3
  113. package/dist/types.mjs +0 -1
package/README.md CHANGED
@@ -15,12 +15,14 @@ There is no embeddable TypeScript library that normalizes across registries. The
15
15
 
16
16
  @agntn/registries fills that gap. One `fetchPackage` call, same response shape, regardless of whether the package lives on npm or Packagist. Uses [PURL (ECMA-427)](https://github.com/package-url/purl-spec) for addressing, so `pkg:npm/lodash` and `pkg:cargo/serde` resolve through the same code path. Storage-backed caching with a lockfile keeps things fast on repeated lookups.
17
17
 
18
+ Docs and the live lookup explorer: [registries.agntn.dev](https://registries.agntn.dev). The source lives in [`docs/`](./docs); run `pnpm docs` after `pnpm build` for a local copy.
19
+
18
20
  ## Features
19
21
 
20
22
  - 🔍 **Single API, six registries** - npm, PyPI, crates.io, RubyGems, Packagist, Arch Linux (official + AUR)
21
23
  - 📦 **PURL-native** - [ECMA-427](https://github.com/package-url/purl-spec) identifiers as first-class input
22
24
  - 🏷️ **Normalized data model** - same `Package`, `Version`, `Dependency`, `Maintainer` types everywhere
23
- - 💾 **Storage-backed cache + lockfile** - unstorage-native, sha256 integrity checks, configurable TTL
25
+ - 💾 **Cache on unstorage with a lockfile** - sha256 integrity checks, configurable TTL
24
26
  - ⌨️ **CLI included** - `registries info npm/lodash`, `registries versions cargo/serde`, `registries deps pypi/flask@3.1.1`
25
27
  - 🔁 **Retry + backoff** - exponential backoff with jitter, rate limiter interface
26
28
  - 🪶 **ESM-only, zero CJS** - built with [obuild](https://github.com/unjs/obuild)
@@ -78,7 +80,7 @@ Add `--json` for machine-readable output, `--no-cache` to skip the cache.
78
80
 
79
81
  ### AI SDK tool
80
82
 
81
- `@agntn/registries/ai` exports a ready-made tool for AI SDK apps:
83
+ `@agntn/registries/ai` exports a tool for AI SDK apps that needs no wiring:
82
84
 
83
85
  ```ts
84
86
  import { generateText } from "ai";
@@ -101,6 +103,26 @@ The tool supports these operations through one input schema:
101
103
  // { operation: 'bulk-packages', purls: ['pkg:npm/lodash', 'pkg:cargo/serde'], concurrency?: number }
102
104
  ```
103
105
 
106
+ ### MCP
107
+
108
+ The package ships an MCP server with six read-only tools for metadata, versions, dependencies, maintainers, bulk lookups, and ecosystem discovery:
109
+
110
+ ```bash
111
+ claude mcp add registries --scope user -- npx @agntn/registries mcp
112
+ ```
113
+
114
+ Hosts with their own transport can import `createMcpServer` from `@agntn/registries/mcp`.
115
+
116
+ ### Pi and OMP extensions
117
+
118
+ Install the published package in OMP:
119
+
120
+ ```bash
121
+ omp install @agntn/registries
122
+ ```
123
+
124
+ From a source checkout, use `omp install .`. The package manifests point OMP and Pi at their matching extension entrypoints, and both expose the same six read-only tools as MCP.
125
+
104
126
  ## Registries
105
127
 
106
128
  | Ecosystem | PURL type | Registry |
@@ -229,6 +251,7 @@ registries <command> [options]
229
251
  | `registries versions <purl>` | List all published versions |
230
252
  | `registries deps <purl>` | Dependencies for a specific version |
231
253
  | `registries maintainers <purl>` | Package maintainers / authors |
254
+ | `registries mcp` | Start the MCP server over stdio |
232
255
  | `registries cache status` | Show cache stats (entries, freshness) |
233
256
  | `registries cache path` | Print cache directory path |
234
257
  | `registries cache clear` | Remove all cached data |
@@ -265,7 +288,7 @@ interface Package {
265
288
  homepage: string;
266
289
  documentation: string; // docs URL (docs.rs, readthedocs, rubydoc, etc.)
267
290
  repository: string;
268
- licenses: string; // SPDX-normalized
291
+ licenses: string; // normalized to SPDX
269
292
  keywords: string[];
270
293
  namespace: string; // e.g. "@vue" for npm scoped packages
271
294
  latestVersion: string;
@@ -0,0 +1,36 @@
1
+ # Licenses of Bundled Dependencies
2
+
3
+ The published artifact additionally contains code with the following licenses:
4
+ MIT
5
+
6
+ # Bundled Dependencies
7
+
8
+ ## typebox
9
+
10
+ License: MIT
11
+ By: sinclairzx81
12
+ Repository: https://github.com/sinclairzx81/typebox
13
+
14
+ > TypeBox
15
+ >
16
+ > The MIT License (MIT)
17
+ >
18
+ > Copyright (c) 2017-2026 Haydn Paterson
19
+ >
20
+ > Permission is hereby granted, free of charge, to any person obtaining a copy
21
+ > of this software and associated documentation files (the "Software"), to deal
22
+ > in the Software without restriction, including without limitation the rights
23
+ > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24
+ > copies of the Software, and to permit persons to whom the Software is
25
+ > furnished to do so, subject to the following conditions:
26
+ >
27
+ > The above copyright notice and this permission notice shall be included in
28
+ > all copies or substantial portions of the Software.
29
+ >
30
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32
+ > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33
+ > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34
+ > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35
+ > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36
+ > THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ import { n as create } from "./registry.mjs";
2
+ import { t as CachedRegistry } from "./cached-registry.mjs";
3
+ /**
4
+ * Create a registry with cache and lockfile tracking.
5
+ *
6
+ * @param ecosystem - Registry ecosystem key.
7
+ * @param options - Optional registry, client, and storage overrides.
8
+ * @returns {Registry} A cached registry instance.
9
+ */
10
+ function createCached(ecosystem, options) {
11
+ return new CachedRegistry(create(ecosystem, options?.baseURL, options?.client), options?.storage);
12
+ }
13
+ export { createCached as t };
14
+
15
+ //# sourceMappingURL=cache.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cache/index.ts"],"sourcesContent":["// Cache\nexport { getCacheDir } from \"./paths.ts\";\nexport {\n getStorage,\n getEcosystemStorage,\n computeIntegrity,\n disposeStorage,\n clearStorage,\n configureStorage,\n} from \"./storage.ts\";\nexport { CachedRegistry } from \"./cached-registry.ts\";\nexport {\n readLockfile,\n writeLockfile,\n cacheKey,\n isFresh,\n getFreshEntry,\n setEntry,\n removeEntry,\n pruneStale,\n DEFAULT_TTL,\n} from \"./lockfile.ts\";\nexport type { Lockfile, LockfileEntry, EntryType } from \"./lockfile.ts\";\n\n// Convenience\nimport type { Storage } from \"unstorage\";\nimport type { Client } from \"../core/client.ts\";\nimport { create, type Registry } from \"../core/registry.ts\";\nimport { CachedRegistry } from \"./cached-registry.ts\";\n\n/** Options for creating a cached registry. */\nexport interface CreateCachedOptions {\n /** Custom base URL for the registry API. */\n baseURL?: string;\n /** Custom HTTP client. */\n client?: Client;\n /** Custom unstorage instance. Overrides the globally configured storage. */\n storage?: Storage;\n}\n\n/** Create a registry instance with caching + lockfile tracking. */\nexport function createCached(ecosystem: string, options?: CreateCachedOptions): Registry {\n const inner = create(ecosystem, options?.baseURL, options?.client);\n return new CachedRegistry(inner, options?.storage);\n}\n"],"mappings":";;;;;;AAyCA,SAAgB,aAAa,WAAmB,SAAyC;AAEvF,QAAO,IAAI,eADG,OAAO,WAAW,SAAS,SAAS,SAAS,OAAO,EACjC,SAAS,QAAQ"}
1
+ {"version":3,"file":"cache.mjs","names":[],"sources":["../../src/cache/index.ts"],"sourcesContent":["// Cache\nexport { getCacheDir } from \"./paths.ts\";\nexport {\n getStorage,\n getEcosystemStorage,\n computeIntegrity,\n disposeStorage,\n clearStorage,\n configureStorage,\n} from \"./storage.ts\";\nexport { CachedRegistry } from \"./cached-registry.ts\";\nexport {\n readLockfile,\n writeLockfile,\n cacheKey,\n isFresh,\n getFreshEntry,\n setEntry,\n removeEntry,\n pruneStale,\n DEFAULT_TTL,\n} from \"./lockfile.ts\";\nexport type { Lockfile, LockfileEntry, EntryType } from \"./lockfile.ts\";\n\n// Convenience\nimport type { Storage } from \"unstorage\";\nimport type { Client } from \"../core/client.ts\";\nimport { create, type Registry } from \"../core/registry.ts\";\nimport { CachedRegistry } from \"./cached-registry.ts\";\n\n/** Options for creating a cached registry. */\nexport interface CreateCachedOptions {\n /** Custom base URL for the registry API. */\n baseURL?: string;\n /** Custom HTTP client. */\n client?: Client;\n /** Custom unstorage instance. Overrides the globally configured storage. */\n storage?: Storage;\n}\n\n/**\n * Create a registry with cache and lockfile tracking.\n *\n * @param ecosystem - Registry ecosystem key.\n * @param options - Optional registry, client, and storage overrides.\n * @returns {Registry} A cached registry instance.\n */\nexport function createCached(ecosystem: string, options?: CreateCachedOptions): Registry {\n const inner = create(ecosystem, options?.baseURL, options?.client);\n return new CachedRegistry(inner, options?.storage);\n}\n"],"mappings":";;;;;;;;;AA+CA,SAAgB,aAAa,WAAmB,SAAyC;AAEvF,QAAO,IAAI,eADG,OAAO,WAAW,SAAS,SAAS,SAAS,OAAO,EACjC,SAAS,QAAQ"}
@@ -1,6 +1,4 @@
1
- import { getCacheDir } from "../cache/paths.mjs";
2
- import { clearStorage } from "../cache/storage.mjs";
3
- import { pruneStale, readLockfile, writeLockfile } from "../cache/lockfile.mjs";
1
+ import { a as pruneStale, g as getCacheDir, l as writeLockfile, o as readLockfile, u as clearStorage } from "./lockfile.mjs";
4
2
  import { defineCommand } from "citty";
5
3
  import consola from "consola";
6
4
  var cache_default = defineCommand({
@@ -46,9 +44,9 @@ var cache_default = defineCommand({
46
44
  });
47
45
  const stale = entries.length - fresh.length;
48
46
  consola.log("");
49
- consola.log(` \x1b[1mCache status\x1b[0m`);
50
- consola.log(` \x1b[90mDirectory:\x1b[0m ${getCacheDir()}`);
51
- consola.log(` \x1b[90mEntries:\x1b[0m ${entries.length} total, ${fresh.length} fresh, ${stale} stale`);
47
+ consola.log(` \x1B[1mCache status\x1B[0m`);
48
+ consola.log(` \x1B[90mDirectory:\x1B[0m ${getCacheDir()}`);
49
+ consola.log(` \x1B[90mEntries:\x1B[0m ${entries.length} total, ${fresh.length} fresh, ${stale} stale`);
52
50
  consola.log("");
53
51
  if (fresh.length > 0) {
54
52
  const byEco = /* @__PURE__ */ new Map();
@@ -56,7 +54,7 @@ var cache_default = defineCommand({
56
54
  const eco = e.key.split(":")[0];
57
55
  byEco.set(eco, (byEco.get(eco) ?? 0) + 1);
58
56
  }
59
- for (const [eco, count] of byEco) consola.log(` \x1b[36m${eco}\x1b[0m: ${count} cached`);
57
+ for (const [eco, count] of byEco) consola.log(` \x1B[36m${eco}\x1B[0m: ${count} cached`);
60
58
  consola.log("");
61
59
  }
62
60
  }
@@ -77,4 +75,4 @@ var cache_default = defineCommand({
77
75
  });
78
76
  export { cache_default as default };
79
77
 
80
- //# sourceMappingURL=cache.mjs.map
78
+ //# sourceMappingURL=cache2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache2.mjs","names":[],"sources":["../../src/commands/cache.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport consola from \"consola\";\nimport { getCacheDir } from \"../cache/paths.ts\";\nimport { clearStorage } from \"../cache/storage.ts\";\nimport { readLockfile, writeLockfile, pruneStale } from \"../cache/lockfile.ts\";\n\nexport default defineCommand({\n meta: {\n name: \"cache\",\n description: \"Manage the registries cache\",\n },\n subCommands: {\n clear: defineCommand({\n meta: {\n name: \"clear\",\n description: \"Remove all cached data\",\n },\n async run() {\n await clearStorage();\n await writeLockfile({ version: 1, entries: {} });\n consola.success(\"Cache cleared\");\n },\n }),\n path: defineCommand({\n meta: {\n name: \"path\",\n description: \"Show cache directory path\",\n },\n run() {\n console.log(getCacheDir());\n },\n }),\n status: defineCommand({\n meta: {\n name: \"status\",\n description: \"Show cache status and entry count\",\n },\n async run() {\n const lockfile = await readLockfile();\n const entries = Object.values(lockfile.entries);\n const fresh = entries.filter((e) => {\n const expiresAt = e.fetchedAt + e.ttl * 1000;\n return Date.now() < expiresAt;\n });\n const stale = entries.length - fresh.length;\n\n consola.log(\"\");\n consola.log(` \\x1B[1mCache status\\x1B[0m`);\n consola.log(` \\x1B[90mDirectory:\\x1B[0m ${getCacheDir()}`);\n consola.log(\n ` \\x1B[90mEntries:\\x1B[0m ${entries.length} total, ${fresh.length} fresh, ${stale} stale`,\n );\n consola.log(\"\");\n\n if (fresh.length > 0) {\n // Group by ecosystem\n const byEco = new Map<string, number>();\n for (const e of fresh) {\n const eco = e.key.split(\":\")[0]!;\n byEco.set(eco, (byEco.get(eco) ?? 0) + 1);\n }\n for (const [eco, count] of byEco) {\n consola.log(` \\x1B[36m${eco}\\x1B[0m: ${count} cached`);\n }\n consola.log(\"\");\n }\n },\n }),\n prune: defineCommand({\n meta: {\n name: \"prune\",\n description: \"Remove stale cache entries\",\n },\n async run() {\n const lockfile = await readLockfile();\n const removed = pruneStale(lockfile);\n await writeLockfile(lockfile);\n consola.success(`Pruned ${removed} stale entries`);\n },\n }),\n },\n});\n"],"mappings":";;;AAMA,IAAA,gBAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,aAAa;EACX,OAAO,cAAc;GACnB,MAAM;IACJ,MAAM;IACN,aAAa;IACd;GACD,MAAM,MAAM;AACV,UAAM,cAAc;AACpB,UAAM,cAAc;KAAE,SAAS;KAAG,SAAS,EAAA;KAAI,CAAC;AAChD,YAAQ,QAAQ,gBAAgB;;GAEnC,CAAC;EACF,MAAM,cAAc;GAClB,MAAM;IACJ,MAAM;IACN,aAAa;IACd;GACD,MAAM;AACJ,YAAQ,IAAI,aAAa,CAAC;;GAE7B,CAAC;EACF,QAAQ,cAAc;GACpB,MAAM;IACJ,MAAM;IACN,aAAa;IACd;GACD,MAAM,MAAM;IACV,MAAM,WAAW,MAAM,cAAc;IACrC,MAAM,UAAU,OAAO,OAAO,SAAS,QAAQ;IAC/C,MAAM,QAAQ,QAAQ,QAAQ,MAAM;KAClC,MAAM,YAAY,EAAE,YAAY,EAAE,MAAM;AACxC,YAAO,KAAK,KAAK,GAAG;MACpB;IACF,MAAM,QAAQ,QAAQ,SAAS,MAAM;AAErC,YAAQ,IAAI,GAAG;AACf,YAAQ,IAAI,+BAA+B;AAC3C,YAAQ,IAAI,gCAAgC,aAAa,GAAG;AAC5D,YAAQ,IACN,gCAAgC,QAAQ,OAAO,UAAU,MAAM,OAAO,UAAU,MAAM,QACvF;AACD,YAAQ,IAAI,GAAG;AAEf,QAAI,MAAM,SAAS,GAAG;KAEpB,MAAM,wBAAQ,IAAI,KAAqB;AACvC,UAAK,MAAM,KAAK,OAAO;MACrB,MAAM,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC;AAC7B,YAAM,IAAI,MAAM,MAAM,IAAI,IAAI,IAAI,KAAK,EAAE;;AAE3C,UAAK,MAAM,CAAC,KAAK,UAAU,MACzB,SAAQ,IAAI,aAAa,IAAI,WAAW,MAAM,SAAS;AAEzD,aAAQ,IAAI,GAAG;;;GAGpB,CAAC;EACF,OAAO,cAAc;GACnB,MAAM;IACJ,MAAM;IACN,aAAa;IACd;GACD,MAAM,MAAM;IACV,MAAM,WAAW,MAAM,cAAc;IACrC,MAAM,UAAU,WAAW,SAAS;AACpC,UAAM,cAAc,SAAS;AAC7B,YAAQ,QAAQ,UAAU,QAAQ,gBAAgB;;GAErD,CAAA;;CAEJ,CAAC"}
@@ -1,6 +1,5 @@
1
- import { t as Registry } from "../_chunks/registry.mjs";
2
- import { computeIntegrity, getStorage } from "./storage.mjs";
3
- import { DEFAULT_TTL, cacheKey, getFreshEntry, readLockfile, setEntry, writeLockfile } from "./lockfile.mjs";
1
+ import { t as Registry } from "./registry.mjs";
2
+ import { c as setEntry, d as computeIntegrity, h as getStorage, l as writeLockfile, n as cacheKey, o as readLockfile, r as getFreshEntry, t as DEFAULT_TTL } from "./lockfile.mjs";
4
3
  /**
5
4
  * CachedRegistry wraps any Registry and adds caching backed by unstorage
6
5
  * with a lockfile for freshness tracking.
@@ -41,10 +40,15 @@ var CachedRegistry = class extends Registry {
41
40
  return this.cached(name, "maintainers", void 0, () => this.inner.fetchMaintainers(name, signal), signal);
42
41
  }
43
42
  /**
44
- * Generic cache-through method:
45
- * 1. Check lockfile for fresh entry
46
- * 2. If fresh -> read from storage
47
- * 3. If stale/missing -> fetch, store, update lockfile
43
+ * Read a fresh cached value or fetch and persist its replacement.
44
+ *
45
+ * @param name - Package name.
46
+ * @param type - Cached data type.
47
+ * @param version - Package version when the cache entry is versioned.
48
+ * @param fetcher - Upstream operation used after a cache miss.
49
+ * @param signal - Optional cancellation signal.
50
+ * @param extraMeta - Optional lockfile metadata derived from the fetched value.
51
+ * @returns {Promise<T>} The cached or freshly fetched value.
48
52
  */
49
53
  async cached(name, type, version, fetcher, signal, extraMeta) {
50
54
  const key = cacheKey(this.inner.ecosystem(), name, type, version);
@@ -87,6 +91,6 @@ var CachedRegistry = class extends Registry {
87
91
  }
88
92
  }
89
93
  };
90
- export { CachedRegistry };
94
+ export { CachedRegistry as t };
91
95
 
92
96
  //# sourceMappingURL=cached-registry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cached-registry.mjs","names":[],"sources":["../../src/cache/cached-registry.ts"],"sourcesContent":["import type { Dependency, Maintainer, Package, URLBuilder, Version } from \"../core/types.ts\";\nimport { Registry } from \"../core/registry.ts\";\nimport { getStorage, computeIntegrity } from \"./storage.ts\";\nimport {\n readLockfile,\n writeLockfile,\n cacheKey,\n getFreshEntry,\n setEntry,\n DEFAULT_TTL,\n} from \"./lockfile.ts\";\nimport type { EntryType, LockfileEntry } from \"./lockfile.ts\";\nimport type { Storage } from \"unstorage\";\n\n/**\n * CachedRegistry wraps any Registry and adds caching backed by unstorage\n * with a lockfile for freshness tracking.\n *\n * Pass a custom `storage` to use a non-default driver (e.g. Cloudflare KV).\n * If omitted, uses the globally configured storage (see `configureStorage()`).\n */\nexport class CachedRegistry extends Registry {\n readonly inner: Registry;\n readonly storage: Storage;\n private readonly lockfileStorage: Storage;\n private readonly inflight = new Map<string, Promise<unknown>>();\n\n constructor(inner: Registry, storage?: Storage) {\n super();\n this.inner = inner;\n this.storage = storage ?? getStorage();\n this.lockfileStorage = storage ?? getStorage();\n }\n\n ecosystem(): string {\n return this.inner.ecosystem();\n }\n\n urls(): URLBuilder {\n return this.inner.urls();\n }\n\n async fetchPackage(name: string, signal?: AbortSignal): Promise<Package> {\n return this.cached<Package>(\n name,\n \"package\",\n undefined,\n () => this.inner.fetchPackage(name, signal),\n signal,\n (value) => ({ latestVersion: value.latestVersion }),\n );\n }\n\n async fetchVersions(name: string, signal?: AbortSignal): Promise<Version[]> {\n const versions = await this.cached<Version[]>(\n name,\n \"versions\",\n undefined,\n () => this.inner.fetchVersions(name, signal),\n signal,\n );\n // JSON round-trip through storage turns Date objects into ISO strings.\n // Revive them so consumers can safely call .getTime() / .toISOString().\n return versions.map((v) => ({\n ...v,\n publishedAt: v.publishedAt ? new Date(v.publishedAt as unknown as string) : null,\n }));\n }\n\n async fetchDependencies(\n name: string,\n version: string,\n signal?: AbortSignal,\n ): Promise<Dependency[]> {\n return this.cached<Dependency[]>(\n name,\n \"dependencies\",\n version,\n () => this.inner.fetchDependencies(name, version, signal),\n signal,\n );\n }\n\n async fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]> {\n return this.cached<Maintainer[]>(\n name,\n \"maintainers\",\n undefined,\n () => this.inner.fetchMaintainers(name, signal),\n signal,\n );\n }\n\n /**\n * Read a fresh cached value or fetch and persist its replacement.\n *\n * @param name - Package name.\n * @param type - Cached data type.\n * @param version - Package version when the cache entry is versioned.\n * @param fetcher - Upstream operation used after a cache miss.\n * @param signal - Optional cancellation signal.\n * @param extraMeta - Optional lockfile metadata derived from the fetched value.\n * @returns {Promise<T>} The cached or freshly fetched value.\n */\n private async cached<T>(\n name: string,\n type: EntryType,\n version: string | undefined,\n fetcher: () => Promise<T>,\n signal: AbortSignal | undefined,\n extraMeta?: (value: T) => Record<string, unknown>,\n ): Promise<T> {\n const eco = this.inner.ecosystem();\n const key = cacheKey(eco, name, type, version);\n const storageKey = key;\n\n // 1. Check lockfile\n const lockfile = await readLockfile(this.lockfileStorage);\n const entry = getFreshEntry(lockfile, key);\n\n if (entry) {\n // 2. Read from storage\n const cached = await this.storage.getItem<T>(storageKey);\n if (cached !== null) {\n // Verify integrity\n const currentHash = computeIntegrity(cached);\n if (currentHash === entry.integrity) {\n return cached;\n }\n // Integrity mismatch - refetch\n }\n }\n\n // 3. Coalesce concurrent fetches for the same key (single-flight).\n // Skip dedup when caller provides an AbortSignal to avoid sharing\n // cancellation context across unrelated callers.\n if (!signal) {\n const pending = this.inflight.get(key);\n if (pending) {\n return pending as Promise<T>;\n }\n }\n\n const flight = (async () => {\n const value = await fetcher();\n\n // Persist to cache (best-effort - storage failures must not discard fetched data)\n const meta = extraMeta ? extraMeta(value) : {};\n const newEntry: LockfileEntry = {\n key,\n type,\n fetchedAt: Date.now(),\n ttl: DEFAULT_TTL[type],\n integrity: computeIntegrity(value),\n ...(\"latestVersion\" in meta ? { latestVersion: meta[\"latestVersion\"] as string } : {}),\n };\n try {\n await this.storage.setItem(storageKey, value as Record<string, unknown>);\n // Re-read lockfile before writing to avoid overwriting entries\n // added by concurrent calls for different keys.\n const freshLockfile = await readLockfile(this.lockfileStorage);\n setEntry(freshLockfile, newEntry);\n await writeLockfile(freshLockfile, this.lockfileStorage);\n } catch {\n // Storage I/O failed (disk full, permissions, remote driver timeout, etc.).\n // The data was already fetched successfully - return it anyway.\n }\n\n return value;\n })();\n\n if (!signal) {\n this.inflight.set(key, flight);\n }\n try {\n return await flight;\n } finally {\n if (!signal) {\n this.inflight.delete(key);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;AAqBA,IAAa,iBAAb,cAAoC,SAAS;CAC3C;CACA;CACA;CACA,2BAA4B,IAAI,KAA+B;CAE/D,YAAY,OAAiB,SAAmB;AAC9C,SAAO;AACP,OAAK,QAAQ;AACb,OAAK,UAAU,WAAW,YAAY;AACtC,OAAK,kBAAkB,WAAW,YAAY;;CAGhD,YAAoB;AAClB,SAAO,KAAK,MAAM,WAAW;;CAG/B,OAAmB;AACjB,SAAO,KAAK,MAAM,MAAM;;CAG1B,MAAM,aAAa,MAAc,QAAwC;AACvE,SAAO,KAAK,OACV,MACA,WACA,KAAA,SACM,KAAK,MAAM,aAAa,MAAM,OAAO,EAC3C,SACC,WAAW,EAAE,eAAe,MAAM,eAAe,EACnD;;CAGH,MAAM,cAAc,MAAc,QAA0C;AAU1E,UATiB,MAAM,KAAK,OAC1B,MACA,YACA,KAAA,SACM,KAAK,MAAM,cAAc,MAAM,OAAO,EAC5C,OACD,EAGe,KAAK,OAAO;GAC1B,GAAG;GACH,aAAa,EAAE,cAAc,IAAI,KAAK,EAAE,YAAiC,GAAG;GAC7E,EAAE;;CAGL,MAAM,kBACJ,MACA,SACA,QACuB;AACvB,SAAO,KAAK,OACV,MACA,gBACA,eACM,KAAK,MAAM,kBAAkB,MAAM,SAAS,OAAO,EACzD,OACD;;CAGH,MAAM,iBAAiB,MAAc,QAA6C;AAChF,SAAO,KAAK,OACV,MACA,eACA,KAAA,SACM,KAAK,MAAM,iBAAiB,MAAM,OAAO,EAC/C,OACD;;;;;;;;;;;;;CAcH,MAAc,OACZ,MACA,MACA,SACA,SACA,QACA,WACY;EAEZ,MAAM,MAAM,SADA,KAAK,MAAM,WAAW,EACR,MAAM,MAAM,QAAQ;EAC9C,MAAM,aAAa;EAInB,MAAM,QAAQ,cADG,MAAM,aAAa,KAAK,gBAAgB,EACnB,IAAI;AAE1C,MAAI,OAAO;GAET,MAAM,SAAS,MAAM,KAAK,QAAQ,QAAW,WAAW;AACxD,OAAI,WAAW;QAEO,iBAAiB,OAAO,KACxB,MAAM,UACxB,QAAO;;;AASb,MAAI,CAAC,QAAQ;GACX,MAAM,UAAU,KAAK,SAAS,IAAI,IAAI;AACtC,OAAI,QACF,QAAO;;EAIX,MAAM,UAAU,YAAY;GAC1B,MAAM,QAAQ,MAAM,SAAS;GAG7B,MAAM,OAAO,YAAY,UAAU,MAAM,GAAG,EAAE;GAC9C,MAAM,WAA0B;IAC9B;IACA;IACA,WAAW,KAAK,KAAK;IACrB,KAAK,YAAY;IACjB,WAAW,iBAAiB,MAAM;IAClC,GAAI,mBAAmB,OAAO,EAAE,eAAe,KAAK,kBAA4B,GAAG,EAAA;IACpF;AACD,OAAI;AACF,UAAM,KAAK,QAAQ,QAAQ,YAAY,MAAiC;IAGxE,MAAM,gBAAgB,MAAM,aAAa,KAAK,gBAAgB;AAC9D,aAAS,eAAe,SAAS;AACjC,UAAM,cAAc,eAAe,KAAK,gBAAgB;WAClD;AAKR,UAAO;MACL;AAEJ,MAAI,CAAC,OACH,MAAK,SAAS,IAAI,KAAK,OAAO;AAEhC,MAAI;AACF,UAAO,MAAM;YACL;AACR,OAAI,CAAC,OACH,MAAK,SAAS,OAAO,IAAI"}
@@ -1,7 +1,8 @@
1
- import "../_chunks/registry.mjs";
2
- import "../_chunks/purl.mjs";
3
- import "../_chunks/registries.mjs";
4
- import { resolvePURL, sharedArgs, withErrorHandling } from "./shared.mjs";
1
+ import "./registry.mjs";
2
+ import "./registries.mjs";
3
+ import "./lockfile.mjs";
4
+ import "./cached-registry.mjs";
5
+ import { n as sharedArgs, r as withErrorHandling, t as resolvePURL } from "./shared.mjs";
5
6
  import { defineCommand } from "citty";
6
7
  import consola from "consola";
7
8
  var deps_default = defineCommand({
@@ -27,7 +28,7 @@ var deps_default = defineCommand({
27
28
  consola.info("Example: pkg:npm/lodash@4.17.21");
28
29
  process.exit(1);
29
30
  }
30
- consola.info(`No version specified, using latest: ${pkg.latestVersion}`);
31
+ if (!args.json) consola.info(`No version specified, using latest: ${pkg.latestVersion}`);
31
32
  const deps = await reg.fetchDependencies(name, pkg.latestVersion);
32
33
  outputDeps(name, pkg.latestVersion, deps, args.json);
33
34
  return;
@@ -42,14 +43,9 @@ function outputDeps(name, version, deps, json) {
42
43
  return;
43
44
  }
44
45
  consola.log("");
45
- consola.log(` \x1b[1m${name}@${version}\x1b[0m — ${deps.length} dependenc${deps.length === 1 ? "y" : "ies"}`);
46
+ consola.log(` \x1B[1m${name}@${version}\x1B[0m — ${deps.length} dependenc${deps.length === 1 ? "y" : "ies"}`);
46
47
  consola.log("");
47
- const byScope = /* @__PURE__ */ new Map();
48
- for (const dep of deps) {
49
- const scope = dep.scope || "runtime";
50
- if (!byScope.has(scope)) byScope.set(scope, []);
51
- byScope.get(scope).push(dep);
52
- }
48
+ const byScope = groupByScope(deps);
53
49
  const scopeColors = {
54
50
  runtime: "\x1B[32m",
55
51
  development: "\x1B[33m",
@@ -59,14 +55,24 @@ function outputDeps(name, version, deps, json) {
59
55
  };
60
56
  for (const [scope, scopeDeps] of byScope) {
61
57
  const color = scopeColors[scope] ?? "\x1B[0m";
62
- consola.log(` ${color}${scope}\x1b[0m (${scopeDeps.length})`);
58
+ consola.log(` ${color}${scope}\x1B[0m (${scopeDeps.length})`);
63
59
  for (const dep of scopeDeps) {
64
60
  const opt = dep.optional ? " \x1B[90m(optional)\x1B[0m" : "";
65
- consola.log(` ${dep.name} \x1b[90m${dep.requirements}\x1b[0m${opt}`);
61
+ consola.log(` ${dep.name} \x1B[90m${dep.requirements}\x1B[0m${opt}`);
66
62
  }
67
63
  consola.log("");
68
64
  }
69
65
  }
66
+ function groupByScope(deps) {
67
+ const byScope = /* @__PURE__ */ new Map();
68
+ for (const dep of deps) {
69
+ const scope = dep.scope || "runtime";
70
+ const scopeDeps = byScope.get(scope) ?? [];
71
+ scopeDeps.push(dep);
72
+ byScope.set(scope, scopeDeps);
73
+ }
74
+ return byScope;
75
+ }
70
76
  export { deps_default as default };
71
77
 
72
78
  //# sourceMappingURL=deps.mjs.map
@@ -0,0 +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 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(\n name: string,\n version: string,\n deps: readonly Dependency[],\n json: boolean,\n): 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 = groupByScope(deps);\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\nfunction groupByScope(deps: readonly Dependency[]): Map<string, Dependency[]> {\n const byScope = new Map<string, Dependency[]>();\n\n for (const dep of deps) {\n const scope = dep.scope || \"runtime\";\n const scopeDeps = byScope.get(scope) ?? [];\n scopeDeps.push(dep);\n byScope.set(scope, scopeDeps);\n }\n\n return byScope;\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,WACP,MACA,SACA,MACA,MACM;AACN,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,UAAU,aAAa,KAAK;CAElC,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;;;AAInB,SAAS,aAAa,MAAwD;CAC5E,MAAM,0BAAU,IAAI,KAA2B;AAE/C,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,IAAI,SAAS;EAC3B,MAAM,YAAY,QAAQ,IAAI,MAAM,IAAI,EAAE;AAC1C,YAAU,KAAK,IAAI;AACnB,UAAQ,IAAI,OAAO,UAAU;;AAG/B,QAAO"}
@@ -1,28 +1,62 @@
1
1
  import { l as InvalidPURLError } from "./registry.mjs";
2
- import { n as createFromPURL } from "./purl.mjs";
3
- /** Fetch normalized package metadata from a PURL. */
2
+ import { c as createFromPURL } from "./registries.mjs";
3
+ /**
4
+ * Fetch normalized package metadata from a package URL.
5
+ *
6
+ * @param purl - Package URL.
7
+ * @param signal - Optional cancellation signal.
8
+ * @param client - Optional HTTP client.
9
+ * @returns {Promise<Package>} Normalized package metadata.
10
+ */
4
11
  async function fetchPackageFromPURL(purl, signal, client) {
5
12
  const [reg, name] = createFromPURL(purl, client);
6
13
  return reg.fetchPackage(name, signal);
7
14
  }
8
- /** Fetch all versions from a PURL. */
15
+ /**
16
+ * Fetch all versions from a package URL.
17
+ *
18
+ * @param purl - Package URL.
19
+ * @param signal - Optional cancellation signal.
20
+ * @param client - Optional HTTP client.
21
+ * @returns {Promise<Version[]>} Normalized versions.
22
+ */
9
23
  async function fetchVersionsFromPURL(purl, signal, client) {
10
24
  const [reg, name] = createFromPURL(purl, client);
11
25
  return reg.fetchVersions(name, signal);
12
26
  }
13
- /** Fetch dependencies for a specific version from a PURL. */
27
+ /**
28
+ * Fetch dependencies for a versioned package URL.
29
+ *
30
+ * @param purl - Versioned package URL.
31
+ * @param signal - Optional cancellation signal.
32
+ * @param client - Optional HTTP client.
33
+ * @returns {Promise<Dependency[]>} Normalized dependencies.
34
+ */
14
35
  async function fetchDependenciesFromPURL(purl, signal, client) {
15
36
  const [reg, name, version] = createFromPURL(purl, client);
16
37
  if (!version) throw new InvalidPURLError(purl, "must include a version for dependency lookup");
17
38
  return reg.fetchDependencies(name, version, signal);
18
39
  }
19
- /** Fetch maintainers from a PURL. */
40
+ /**
41
+ * Fetch maintainers from a package URL.
42
+ *
43
+ * @param purl - Package URL.
44
+ * @param signal - Optional cancellation signal.
45
+ * @param client - Optional HTTP client.
46
+ * @returns {Promise<Maintainer[]>} Normalized maintainers.
47
+ */
20
48
  async function fetchMaintainersFromPURL(purl, signal, client) {
21
49
  const [reg, name] = createFromPURL(purl, client);
22
50
  return reg.fetchMaintainers(name, signal);
23
51
  }
24
52
  const DEFAULT_CONCURRENCY = 15;
25
- /** Bulk fetch packages from multiple PURLs, with concurrency limit. */
53
+ /**
54
+ * Fetch packages concurrently, skipping failed lookups.
55
+ *
56
+ * @param purls - Package URLs to fetch.
57
+ * @param options - Optional concurrency, cancellation, and client settings.
58
+ * @returns {Promise<Map<string, Package>>} Results keyed by package URL.
59
+ */
26
60
  async function bulkFetchPackages(purls, options) {
27
61
  const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;
28
62
  const results = /* @__PURE__ */ new Map();
@@ -44,14 +78,11 @@ async function bulkFetchPackages(purls, options) {
44
78
  return results;
45
79
  }
46
80
  /**
47
- * Select the best matching version from a list.
48
- *
49
- * Resolution order:
50
- * 1. Exact match for `requested` (non-yanked/deprecated/retracted)
51
- * 2. Exact match for `latest` (non-yanked/deprecated/retracted)
52
- * 3. Newest available version with no negative status (by publishedAt)
81
+ * Select an exact requested or latest version, then the newest usable one.
53
82
  *
54
- * Returns `null` when no usable version exists.
83
+ * @param versions - Candidate versions.
84
+ * @param options - Optional requested and latest version numbers.
85
+ * @returns {Version | null} The selected version, or null.
55
86
  */
56
87
  function selectVersion(versions, options) {
57
88
  const { requested, latest } = options ?? {};
@@ -74,18 +105,21 @@ function selectVersion(versions, options) {
74
105
  /**
75
106
  * Resolve the best documentation URL for a package.
76
107
  *
77
- * Fallback chain:
78
- * 1. `package.documentation` (explicit docs URL from registry)
79
- * 2. `package.homepage` (project homepage)
80
- * 3. `urls.documentation()` (ecosystem default, e.g. docs.rs, rubydoc.info)
108
+ * @param pkg - Package metadata.
109
+ * @param urls - Ecosystem URL builder.
110
+ * @param version - Optional package version.
111
+ * @returns {string} The explicit, homepage, or ecosystem documentation URL.
81
112
  */
82
113
  function resolveDocsUrl(pkg, urls, version) {
83
114
  return pkg.documentation || pkg.homepage || urls.documentation(pkg.name, version);
84
115
  }
85
116
  /**
86
- * Resolve the best README URL for a package.
117
+ * Resolve the ecosystem README URL for a package.
87
118
  *
88
- * Returns the ecosystem-specific URL where the package README can be fetched.
119
+ * @param pkg - Package metadata.
120
+ * @param urls - Ecosystem URL builder.
121
+ * @param version - Optional package version.
122
+ * @returns {string} The README URL.
89
123
  */
90
124
  function resolveReadmeUrl(pkg, urls, version) {
91
125
  return urls.readme(pkg.name, version);
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.mjs","names":[],"sources":["../../src/helpers.ts"],"sourcesContent":["import type { Package, Version, Dependency, Maintainer, URLBuilder } from \"./core/types.ts\";\nimport type { Client } from \"./core/client.ts\";\nimport { createFromPURL } from \"./core/purl.ts\";\nimport { InvalidPURLError } from \"./core/errors.ts\";\n\n/** Fetch normalized package metadata from a PURL. */\nexport async function fetchPackageFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Package> {\n const [reg, name] = createFromPURL(purl, client);\n return reg.fetchPackage(name, signal);\n}\n\n/** Fetch all versions from a PURL. */\nexport async function fetchVersionsFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Version[]> {\n const [reg, name] = createFromPURL(purl, client);\n return reg.fetchVersions(name, signal);\n}\n\n/** Fetch dependencies for a specific version from a PURL. */\nexport async function fetchDependenciesFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Dependency[]> {\n const [reg, name, version] = createFromPURL(purl, client);\n if (!version) {\n throw new InvalidPURLError(purl, \"must include a version for dependency lookup\");\n }\n return reg.fetchDependencies(name, version, signal);\n}\n\n/** Fetch maintainers from a PURL. */\nexport async function fetchMaintainersFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Maintainer[]> {\n const [reg, name] = createFromPURL(purl, client);\n return reg.fetchMaintainers(name, signal);\n}\n\nconst DEFAULT_CONCURRENCY = 15;\n\n/** Bulk fetch packages from multiple PURLs, with concurrency limit. */\nexport async function bulkFetchPackages(\n purls: string[],\n options?: { concurrency?: number; signal?: AbortSignal; client?: Client },\n): Promise<Map<string, Package>> {\n const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;\n const results = new Map<string, Package>();\n const queue = [...purls];\n\n const signal = options?.signal;\n\n const workers = Array.from({ length: Math.min(concurrency, queue.length) }, async () => {\n while (queue.length > 0) {\n if (signal?.aborted) break;\n\n const purl = queue.shift()!;\n try {\n const pkg = await fetchPackageFromPURL(purl, signal, options?.client);\n results.set(purl, pkg);\n } catch {\n if (signal?.aborted) break;\n // Silently skip failed lookups — absent from results map\n }\n }\n });\n\n await Promise.all(workers);\n return results;\n}\n\n/**\n * Select the best matching version from a list.\n *\n * Resolution order:\n * 1. Exact match for `requested` (non-yanked/deprecated/retracted)\n * 2. Exact match for `latest` (non-yanked/deprecated/retracted)\n * 3. Newest available version with no negative status (by publishedAt)\n *\n * Returns `null` when no usable version exists.\n */\nexport function selectVersion(\n versions: Version[],\n options?: {\n requested?: string;\n latest?: string;\n },\n): Version | null {\n const { requested, latest } = options ?? {};\n\n if (requested) {\n const exact = versions.find((v) => v.number === requested && v.status === \"\");\n if (exact) return exact;\n }\n\n if (latest) {\n const latestV = versions.find((v) => v.number === latest && v.status === \"\");\n if (latestV) return latestV;\n }\n\n const usable = versions.filter((v) => v.status === \"\");\n if (usable.length === 0) return null;\n\n usable.sort((a, b) => {\n const at = a.publishedAt?.getTime() ?? 0;\n const bt = b.publishedAt?.getTime() ?? 0;\n return bt - at;\n });\n\n return usable[0] ?? null;\n}\n\n/**\n * Resolve the best documentation URL for a package.\n *\n * Fallback chain:\n * 1. `package.documentation` (explicit docs URL from registry)\n * 2. `package.homepage` (project homepage)\n * 3. `urls.documentation()` (ecosystem default, e.g. docs.rs, rubydoc.info)\n */\nexport function resolveDocsUrl(pkg: Package, urls: URLBuilder, version?: string): string {\n return pkg.documentation || pkg.homepage || urls.documentation(pkg.name, version);\n}\n\n/**\n * Resolve the best README URL for a package.\n *\n * Returns the ecosystem-specific URL where the package README can be fetched.\n */\nexport function resolveReadmeUrl(pkg: Package, urls: URLBuilder, version?: string): string {\n return urls.readme(pkg.name, version);\n}\n"],"mappings":";;;AAMA,eAAsB,qBACpB,MACA,QACA,QACkB;CAClB,MAAM,CAAC,KAAK,QAAQ,eAAe,MAAM,OAAO;AAChD,QAAO,IAAI,aAAa,MAAM,OAAO;;;AAIvC,eAAsB,sBACpB,MACA,QACA,QACoB;CACpB,MAAM,CAAC,KAAK,QAAQ,eAAe,MAAM,OAAO;AAChD,QAAO,IAAI,cAAc,MAAM,OAAO;;;AAIxC,eAAsB,0BACpB,MACA,QACA,QACuB;CACvB,MAAM,CAAC,KAAK,MAAM,WAAW,eAAe,MAAM,OAAO;AACzD,KAAI,CAAC,QACH,OAAM,IAAI,iBAAiB,MAAM,+CAA+C;AAElF,QAAO,IAAI,kBAAkB,MAAM,SAAS,OAAO;;;AAIrD,eAAsB,yBACpB,MACA,QACA,QACuB;CACvB,MAAM,CAAC,KAAK,QAAQ,eAAe,MAAM,OAAO;AAChD,QAAO,IAAI,iBAAiB,MAAM,OAAO;;AAG3C,MAAM,sBAAsB;;AAG5B,eAAsB,kBACpB,OACA,SAC+B;CAC/B,MAAM,cAAc,SAAS,eAAe;CAC5C,MAAM,0BAAU,IAAI,KAAsB;CAC1C,MAAM,QAAQ,CAAC,GAAG,MAAM;CAExB,MAAM,SAAS,SAAS;CAExB,MAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,OAAO,EAAE,EAAE,YAAY;AACtF,SAAO,MAAM,SAAS,GAAG;AACvB,OAAI,QAAQ,QAAS;GAErB,MAAM,OAAO,MAAM,OAAO;AAC1B,OAAI;IACF,MAAM,MAAM,MAAM,qBAAqB,MAAM,QAAQ,SAAS,OAAO;AACrE,YAAQ,IAAI,MAAM,IAAI;WAChB;AACN,QAAI,QAAQ,QAAS;;;GAIzB;AAEF,OAAM,QAAQ,IAAI,QAAQ;AAC1B,QAAO;;;;;;;;;;;;AAaT,SAAgB,cACd,UACA,SAIgB;CAChB,MAAM,EAAE,WAAW,WAAW,WAAW,EAAE;AAE3C,KAAI,WAAW;EACb,MAAM,QAAQ,SAAS,MAAM,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,GAAG;AAC7E,MAAI,MAAO,QAAO;;AAGpB,KAAI,QAAQ;EACV,MAAM,UAAU,SAAS,MAAM,MAAM,EAAE,WAAW,UAAU,EAAE,WAAW,GAAG;AAC5E,MAAI,QAAS,QAAO;;CAGtB,MAAM,SAAS,SAAS,QAAQ,MAAM,EAAE,WAAW,GAAG;AACtD,KAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAO,MAAM,GAAG,MAAM;EACpB,MAAM,KAAK,EAAE,aAAa,SAAS,IAAI;AAEvC,UADW,EAAE,aAAa,SAAS,IAAI,KAC3B;GACZ;AAEF,QAAO,OAAO,MAAM;;;;;;;;;;AAWtB,SAAgB,eAAe,KAAc,MAAkB,SAA0B;AACvF,QAAO,IAAI,iBAAiB,IAAI,YAAY,KAAK,cAAc,IAAI,MAAM,QAAQ;;;;;;;AAQnF,SAAgB,iBAAiB,KAAc,MAAkB,SAA0B;AACzF,QAAO,KAAK,OAAO,IAAI,MAAM,QAAQ"}
1
+ {"version":3,"file":"helpers.mjs","names":[],"sources":["../../src/helpers.ts"],"sourcesContent":["import type { Package, Version, Dependency, Maintainer, URLBuilder } from \"./core/types.ts\";\nimport type { Client } from \"./core/client.ts\";\nimport { createFromPURL } from \"./core/purl.ts\";\nimport { InvalidPURLError } from \"./core/errors.ts\";\n\n/**\n * Fetch normalized package metadata from a package URL.\n *\n * @param purl - Package URL.\n * @param signal - Optional cancellation signal.\n * @param client - Optional HTTP client.\n * @returns {Promise<Package>} Normalized package metadata.\n */\nexport async function fetchPackageFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Package> {\n const [reg, name] = createFromPURL(purl, client);\n return reg.fetchPackage(name, signal);\n}\n\n/**\n * Fetch all versions from a package URL.\n *\n * @param purl - Package URL.\n * @param signal - Optional cancellation signal.\n * @param client - Optional HTTP client.\n * @returns {Promise<Version[]>} Normalized versions.\n */\nexport async function fetchVersionsFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Version[]> {\n const [reg, name] = createFromPURL(purl, client);\n return reg.fetchVersions(name, signal);\n}\n\n/**\n * Fetch dependencies for a versioned package URL.\n *\n * @param purl - Versioned package URL.\n * @param signal - Optional cancellation signal.\n * @param client - Optional HTTP client.\n * @returns {Promise<Dependency[]>} Normalized dependencies.\n */\nexport async function fetchDependenciesFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Dependency[]> {\n const [reg, name, version] = createFromPURL(purl, client);\n if (!version) {\n throw new InvalidPURLError(purl, \"must include a version for dependency lookup\");\n }\n return reg.fetchDependencies(name, version, signal);\n}\n\n/**\n * Fetch maintainers from a package URL.\n *\n * @param purl - Package URL.\n * @param signal - Optional cancellation signal.\n * @param client - Optional HTTP client.\n * @returns {Promise<Maintainer[]>} Normalized maintainers.\n */\nexport async function fetchMaintainersFromPURL(\n purl: string,\n signal?: AbortSignal,\n client?: Client,\n): Promise<Maintainer[]> {\n const [reg, name] = createFromPURL(purl, client);\n return reg.fetchMaintainers(name, signal);\n}\n\nconst DEFAULT_CONCURRENCY = 15;\n\n/**\n * Fetch packages concurrently, skipping failed lookups.\n *\n * @param purls - Package URLs to fetch.\n * @param options - Optional concurrency, cancellation, and client settings.\n * @returns {Promise<Map<string, Package>>} Results keyed by package URL.\n */\nexport async function bulkFetchPackages(\n purls: readonly string[],\n options?: Readonly<{ concurrency?: number; signal?: AbortSignal; client?: Client }>,\n): Promise<Map<string, Package>> {\n const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;\n const results = new Map<string, Package>();\n const queue = [...purls];\n\n const signal = options?.signal;\n\n const workers = Array.from({ length: Math.min(concurrency, queue.length) }, async () => {\n while (queue.length > 0) {\n if (signal?.aborted) break;\n\n const purl = queue.shift()!;\n try {\n const pkg = await fetchPackageFromPURL(purl, signal, options?.client);\n results.set(purl, pkg);\n } catch {\n if (signal?.aborted) break;\n // Silently skip failed lookups — absent from results map\n }\n }\n });\n\n await Promise.all(workers);\n return results;\n}\n\n/**\n * Select an exact requested or latest version, then the newest usable one.\n *\n * @param versions - Candidate versions.\n * @param options - Optional requested and latest version numbers.\n * @returns {Version | null} The selected version, or null.\n */\nexport function selectVersion(\n versions: readonly Version[],\n options?: Readonly<{\n requested?: string;\n latest?: string;\n }>,\n): Version | null {\n const { requested, latest } = options ?? {};\n\n if (requested) {\n const exact = versions.find((v) => v.number === requested && v.status === \"\");\n if (exact) return exact;\n }\n\n if (latest) {\n const latestV = versions.find((v) => v.number === latest && v.status === \"\");\n if (latestV) return latestV;\n }\n\n const usable = versions.filter((v) => v.status === \"\");\n if (usable.length === 0) return null;\n\n usable.sort((a, b) => {\n const at = a.publishedAt?.getTime() ?? 0;\n const bt = b.publishedAt?.getTime() ?? 0;\n return bt - at;\n });\n\n return usable[0] ?? null;\n}\n\n/**\n * Resolve the best documentation URL for a package.\n *\n * @param pkg - Package metadata.\n * @param urls - Ecosystem URL builder.\n * @param version - Optional package version.\n * @returns {string} The explicit, homepage, or ecosystem documentation URL.\n */\nexport function resolveDocsUrl(pkg: Package, urls: URLBuilder, version?: string): string {\n return pkg.documentation || pkg.homepage || urls.documentation(pkg.name, version);\n}\n\n/**\n * Resolve the ecosystem README URL for a package.\n *\n * @param pkg - Package metadata.\n * @param urls - Ecosystem URL builder.\n * @param version - Optional package version.\n * @returns {string} The README URL.\n */\nexport function resolveReadmeUrl(pkg: Package, urls: URLBuilder, version?: string): string {\n return urls.readme(pkg.name, version);\n}\n"],"mappings":";;;;;;;;;;AAaA,eAAsB,qBACpB,MACA,QACA,QACkB;CAClB,MAAM,CAAC,KAAK,QAAQ,eAAe,MAAM,OAAO;AAChD,QAAO,IAAI,aAAa,MAAM,OAAO;;;;;;;;;;AAWvC,eAAsB,sBACpB,MACA,QACA,QACoB;CACpB,MAAM,CAAC,KAAK,QAAQ,eAAe,MAAM,OAAO;AAChD,QAAO,IAAI,cAAc,MAAM,OAAO;;;;;;;;;;AAWxC,eAAsB,0BACpB,MACA,QACA,QACuB;CACvB,MAAM,CAAC,KAAK,MAAM,WAAW,eAAe,MAAM,OAAO;AACzD,KAAI,CAAC,QACH,OAAM,IAAI,iBAAiB,MAAM,+CAA+C;AAElF,QAAO,IAAI,kBAAkB,MAAM,SAAS,OAAO;;;;;;;;;;AAWrD,eAAsB,yBACpB,MACA,QACA,QACuB;CACvB,MAAM,CAAC,KAAK,QAAQ,eAAe,MAAM,OAAO;AAChD,QAAO,IAAI,iBAAiB,MAAM,OAAO;;AAG3C,MAAM,sBAAsB;;;;;;;;AAS5B,eAAsB,kBACpB,OACA,SAC+B;CAC/B,MAAM,cAAc,SAAS,eAAe;CAC5C,MAAM,0BAAU,IAAI,KAAsB;CAC1C,MAAM,QAAQ,CAAC,GAAG,MAAM;CAExB,MAAM,SAAS,SAAS;CAExB,MAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,OAAO,EAAE,EAAE,YAAY;AACtF,SAAO,MAAM,SAAS,GAAG;AACvB,OAAI,QAAQ,QAAS;GAErB,MAAM,OAAO,MAAM,OAAO;AAC1B,OAAI;IACF,MAAM,MAAM,MAAM,qBAAqB,MAAM,QAAQ,SAAS,OAAO;AACrE,YAAQ,IAAI,MAAM,IAAI;WAChB;AACN,QAAI,QAAQ,QAAS;;;GAIzB;AAEF,OAAM,QAAQ,IAAI,QAAQ;AAC1B,QAAO;;;;;;;;;AAUT,SAAgB,cACd,UACA,SAIgB;CAChB,MAAM,EAAE,WAAW,WAAW,WAAW,EAAE;AAE3C,KAAI,WAAW;EACb,MAAM,QAAQ,SAAS,MAAM,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,GAAG;AAC7E,MAAI,MAAO,QAAO;;AAGpB,KAAI,QAAQ;EACV,MAAM,UAAU,SAAS,MAAM,MAAM,EAAE,WAAW,UAAU,EAAE,WAAW,GAAG;AAC5E,MAAI,QAAS,QAAO;;CAGtB,MAAM,SAAS,SAAS,QAAQ,MAAM,EAAE,WAAW,GAAG;AACtD,KAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAO,MAAM,GAAG,MAAM;EACpB,MAAM,KAAK,EAAE,aAAa,SAAS,IAAI;AAEvC,UADW,EAAE,aAAa,SAAS,IAAI,KAC3B;GACZ;AAEF,QAAO,OAAO,MAAM;;;;;;;;;;AAWtB,SAAgB,eAAe,KAAc,MAAkB,SAA0B;AACvF,QAAO,IAAI,iBAAiB,IAAI,YAAY,KAAK,cAAc,IAAI,MAAM,QAAQ;;;;;;;;;;AAWnF,SAAgB,iBAAiB,KAAc,MAAkB,SAA0B;AACzF,QAAO,KAAK,OAAO,IAAI,MAAM,QAAQ"}
@@ -1,5 +1,4 @@
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, t as Registry } from "./registry.mjs";
1
+ import { d as Package, g as Version, h as URLBuilder, l as Dependency, o as Client, t as Registry, u as Maintainer } from "./registry.mjs";
3
2
 
4
3
  //#region src/registries/npm.d.ts
5
4
  /** npm registry client. */
@@ -13,13 +12,12 @@ declare class NpmRegistry extends Registry {
13
12
  fetchDependencies(name: string, version: string, signal?: AbortSignal): Promise<Dependency[]>;
14
13
  fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;
15
14
  urls(): URLBuilder;
16
- /** Build a stable dedup key. Prefers email (unique per account), falls back to name. */
15
+ private mapDependencies;
16
+ private collectMaintainers;
17
+ private toMaintainer;
17
18
  private maintainerKey;
18
- /** Encode package name for URL (handle scoped packages). */
19
19
  private encodeName;
20
- /** Extract namespace from scoped package name. */
21
20
  private extractNamespace;
22
- /** Extract and normalize license. */
23
21
  private extractLicense;
24
22
  }
25
23
  //#endregion
@@ -50,17 +48,14 @@ declare class PyPIRegistry extends Registry {
50
48
  fetchDependencies(name: string, version: string, signal?: AbortSignal): Promise<Dependency[]>;
51
49
  fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;
52
50
  urls(): URLBuilder;
53
- /** Match a filename to a version from the known versions list. */
51
+ private indexFilesByVersion;
52
+ private toVersion;
54
53
  private matchFileVersion;
55
- /** Normalize package name per PEP 503. */
56
54
  private normalizeName;
57
- /** Extract repository URL from project_urls. */
58
55
  private extractRepository;
59
- /** Find a project URL by key, case-insensitive. */
60
56
  private findProjectUrl;
61
- /** Parse comma-separated keywords. */
62
57
  private parseKeywords;
63
- /** Parse PEP 508 dependency string into a normalized Dependency. */
58
+ private parseExtraMarker;
64
59
  private parsePEP508;
65
60
  }
66
61
  //#endregion
@@ -90,13 +85,11 @@ declare class PackagistRegistry extends Registry {
90
85
  fetchDependencies(name: string, version: string, signal?: AbortSignal): Promise<Dependency[]>;
91
86
  fetchMaintainers(name: string, signal?: AbortSignal): Promise<Maintainer[]>;
92
87
  urls(): URLBuilder;
93
- /** Parse "vendor/package" format. */
88
+ private collectMaintainers;
89
+ private toMaintainer;
94
90
  private parseName;
95
- /** Find the highest non-dev version. */
96
91
  private findLatestVersion;
97
- /** Extract and normalize licenses. */
98
92
  private extractLicenses;
99
- /** Skip PHP and extension dependencies. */
100
93
  private shouldSkipDependency;
101
94
  }
102
95
  //#endregion
@@ -116,25 +109,18 @@ declare class AlpmRegistry extends Registry {
116
109
  private fetchOfficialVersions;
117
110
  private fetchOfficialDependencies;
118
111
  private fetchOfficialMaintainers;
119
- /** Search official repos by exact package name. Prefers x86_64 results. */
120
112
  private searchOfficial;
121
113
  private fetchAurPackage;
122
114
  private fetchAurVersions;
123
115
  private fetchAurDependencies;
124
116
  private fetchAurMaintainers;
125
- /** Fetch package info from AUR RPC v5. */
126
117
  private fetchAurInfo;
127
- /** Parse "namespace/name" into components. Defaults to "arch" namespace. */
128
118
  private parseName;
129
119
  private assertSupportedNamespace;
130
120
  private assertVersionMatches;
131
- /** Format ALPM version: epoch:pkgver-pkgrel (epoch omitted when 0). */
132
121
  private formatVersion;
133
- /** Build normalized dependency list from ALPM dependency arrays. */
134
122
  private buildDependencies;
135
- /** Parse a dependency string like "glibc>=2.33" or "bash". */
136
123
  private parseDep;
137
- /** Parse optional dependency like "perl-locale-gettext: translation support". */
138
124
  private parseOptDep;
139
125
  }
140
126
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/registries/npm.ts","../../src/registries/cargo.ts","../../src/registries/pypi.ts","../../src/registries/rubygems.ts","../../src/registries/packagist.ts","../../src/registries/alpm.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/registries/npm.ts","../../src/registries/cargo.ts","../../src/registries/pypi.ts","../../src/registries/rubygems.ts","../../src/registries/packagist.ts","../../src/registries/alpm.ts"],"mappings":"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"}