@vltpkg/registry-client 1.0.0-rc.27 → 1.0.0-rc.29
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/auth.d.ts +21 -0
- package/dist/auth.js +63 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -4
- package/package.json +9 -9
package/dist/auth.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { Keychain } from '@vltpkg/keychain';
|
|
2
2
|
export type Token = `Bearer ${string}` | `Basic ${string}`;
|
|
3
|
+
/**
|
|
4
|
+
* Normalize a registry URL into a stable key that preserves the
|
|
5
|
+
* path prefix. The result is `origin + pathname` with trailing
|
|
6
|
+
* slashes stripped so that
|
|
7
|
+
* `https://r.io/luke/` and `https://r.io/luke`
|
|
8
|
+
* both produce the same key.
|
|
9
|
+
*
|
|
10
|
+
* For plain-origin registries the result is identical to the old
|
|
11
|
+
* `new URL(url).origin` behaviour (e.g. `https://registry.npmjs.org`).
|
|
12
|
+
*/
|
|
13
|
+
export declare const normalizeRegistryKey: (url: string) => string;
|
|
3
14
|
export declare const keychains: Map<string, Keychain<Token>>;
|
|
4
15
|
/**
|
|
5
16
|
* In-memory token store for OIDC-exchanged tokens.
|
|
@@ -13,3 +24,13 @@ export declare const isToken: (t: any) => t is Token;
|
|
|
13
24
|
export declare const deleteToken: (registry: string, identity: string) => Promise<void>;
|
|
14
25
|
export declare const setToken: (registry: string, token: Token, identity: string) => Promise<void>;
|
|
15
26
|
export declare const getToken: (registry: string, identity: string) => Promise<Token | undefined>;
|
|
27
|
+
/**
|
|
28
|
+
* Find the best matching token for a request URL by performing a
|
|
29
|
+
* longest-prefix match against all known registry keys (runtime
|
|
30
|
+
* tokens, env-var registries, and keychain entries).
|
|
31
|
+
*
|
|
32
|
+
* This is used by `RegistryClient.request()` which only has the
|
|
33
|
+
* full request URL — not the configured registry URL that was used
|
|
34
|
+
* to construct it.
|
|
35
|
+
*/
|
|
36
|
+
export declare const getTokenByURL: (requestUrl: string, identity: string) => Promise<Token | undefined>;
|
package/dist/auth.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import { Keychain } from '@vltpkg/keychain';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a registry URL into a stable key that preserves the
|
|
4
|
+
* path prefix. The result is `origin + pathname` with trailing
|
|
5
|
+
* slashes stripped so that
|
|
6
|
+
* `https://r.io/luke/` and `https://r.io/luke`
|
|
7
|
+
* both produce the same key.
|
|
8
|
+
*
|
|
9
|
+
* For plain-origin registries the result is identical to the old
|
|
10
|
+
* `new URL(url).origin` behaviour (e.g. `https://registry.npmjs.org`).
|
|
11
|
+
*/
|
|
12
|
+
export const normalizeRegistryKey = (url) => {
|
|
13
|
+
const u = new URL(url);
|
|
14
|
+
return (u.origin + u.pathname).replace(/\/+$/, '');
|
|
15
|
+
};
|
|
2
16
|
// just exported for testing
|
|
3
17
|
export const keychains = new Map();
|
|
4
18
|
/**
|
|
@@ -7,7 +21,7 @@ export const keychains = new Map();
|
|
|
7
21
|
*/
|
|
8
22
|
export const runtimeTokens = new Map();
|
|
9
23
|
export const setRuntimeToken = (registry, token) => {
|
|
10
|
-
runtimeTokens.set(
|
|
24
|
+
runtimeTokens.set(normalizeRegistryKey(registry), token);
|
|
11
25
|
};
|
|
12
26
|
export const clearRuntimeTokens = () => {
|
|
13
27
|
runtimeTokens.clear();
|
|
@@ -26,28 +40,69 @@ export const isToken = (t) => typeof t === 'string' &&
|
|
|
26
40
|
export const deleteToken = async (registry, identity) => {
|
|
27
41
|
const kc = getKC(identity);
|
|
28
42
|
await kc.load();
|
|
29
|
-
kc.delete(
|
|
43
|
+
kc.delete(normalizeRegistryKey(registry));
|
|
30
44
|
await kc.save();
|
|
31
45
|
};
|
|
32
46
|
export const setToken = async (registry, token, identity) => {
|
|
33
47
|
const kc = getKC(identity);
|
|
34
|
-
return kc.set(
|
|
48
|
+
return kc.set(normalizeRegistryKey(registry), token);
|
|
35
49
|
};
|
|
36
50
|
export const getToken = async (registry, identity) => {
|
|
37
51
|
const kc = getKC(identity);
|
|
38
|
-
|
|
52
|
+
const key = normalizeRegistryKey(registry);
|
|
39
53
|
// Runtime tokens (e.g. from OIDC exchange) take precedence
|
|
40
|
-
const rt = runtimeTokens.get(
|
|
54
|
+
const rt = runtimeTokens.get(key);
|
|
41
55
|
if (rt)
|
|
42
56
|
return rt;
|
|
43
57
|
const envReg = process.env.VLT_REGISTRY;
|
|
44
|
-
if (envReg &&
|
|
58
|
+
if (envReg && key === normalizeRegistryKey(envReg)) {
|
|
45
59
|
const envTok = process.env.VLT_TOKEN;
|
|
46
60
|
if (envTok)
|
|
47
61
|
return `Bearer ${envTok}`;
|
|
48
62
|
}
|
|
49
|
-
const tok = process.env[`VLT_TOKEN_${
|
|
63
|
+
const tok = process.env[`VLT_TOKEN_${key.replace(/[^a-zA-Z0-9]+/g, '_')}`];
|
|
50
64
|
if (tok)
|
|
51
65
|
return `Bearer ${tok}`;
|
|
52
|
-
return kc.get(
|
|
66
|
+
return kc.get(key);
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Find the best matching token for a request URL by performing a
|
|
70
|
+
* longest-prefix match against all known registry keys (runtime
|
|
71
|
+
* tokens, env-var registries, and keychain entries).
|
|
72
|
+
*
|
|
73
|
+
* This is used by `RegistryClient.request()` which only has the
|
|
74
|
+
* full request URL — not the configured registry URL that was used
|
|
75
|
+
* to construct it.
|
|
76
|
+
*/
|
|
77
|
+
export const getTokenByURL = async (requestUrl, identity) => {
|
|
78
|
+
const normalized = normalizeRegistryKey(requestUrl);
|
|
79
|
+
// Collect all known registry keys.
|
|
80
|
+
const candidates = [...runtimeTokens.keys()];
|
|
81
|
+
const envReg = process.env.VLT_REGISTRY;
|
|
82
|
+
if (envReg) {
|
|
83
|
+
candidates.push(normalizeRegistryKey(envReg));
|
|
84
|
+
}
|
|
85
|
+
const kc = getKC(identity);
|
|
86
|
+
// Keychain entries
|
|
87
|
+
for (const k of await kc.keys()) {
|
|
88
|
+
candidates.push(k);
|
|
89
|
+
}
|
|
90
|
+
// Find the longest candidate key that is a prefix of the
|
|
91
|
+
// normalized request URL.
|
|
92
|
+
let bestKey;
|
|
93
|
+
let bestLen = 0;
|
|
94
|
+
for (const candidate of candidates) {
|
|
95
|
+
if (candidate.length > bestLen &&
|
|
96
|
+
(normalized === candidate ||
|
|
97
|
+
normalized.startsWith(candidate + '/'))) {
|
|
98
|
+
bestKey = candidate;
|
|
99
|
+
bestLen = candidate.length;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (bestKey) {
|
|
103
|
+
return getToken(bestKey, identity);
|
|
104
|
+
}
|
|
105
|
+
// Fall back to origin-only match (handles VLT_TOKEN_* env vars
|
|
106
|
+
// which we can't enumerate by URL).
|
|
107
|
+
return getToken(requestUrl, identity);
|
|
53
108
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ import type { Integrity } from '@vltpkg/types';
|
|
|
3
3
|
import type { Dispatcher } from 'undici';
|
|
4
4
|
import { RetryAgent } from 'undici';
|
|
5
5
|
import type { Token } from './auth.ts';
|
|
6
|
-
import { clearRuntimeTokens, deleteToken, getKC, isToken, keychains, runtimeTokens, setRuntimeToken, setToken } from './auth.ts';
|
|
6
|
+
import { clearRuntimeTokens, deleteToken, getKC, getTokenByURL, isToken, keychains, normalizeRegistryKey, runtimeTokens, setRuntimeToken, setToken } from './auth.ts';
|
|
7
7
|
import type { JSONObj } from './cache-entry.ts';
|
|
8
8
|
import { CacheEntry } from './cache-entry.ts';
|
|
9
9
|
import type { TokenResponse } from './token-response.ts';
|
|
10
10
|
import type { WebAuthChallenge } from './web-auth-challenge.ts';
|
|
11
11
|
import { oidc } from './oidc.ts';
|
|
12
12
|
import type { OidcOptions } from './oidc.ts';
|
|
13
|
-
export { CacheEntry, clearRuntimeTokens, deleteToken, getKC, isToken, keychains, oidc, runtimeTokens, setRuntimeToken, setToken, type JSONObj, type OidcOptions, type Token, type TokenResponse, type WebAuthChallenge, };
|
|
13
|
+
export { CacheEntry, clearRuntimeTokens, deleteToken, getKC, getTokenByURL, isToken, keychains, normalizeRegistryKey, oidc, runtimeTokens, setRuntimeToken, setToken, type JSONObj, type OidcOptions, type Token, type TokenResponse, type WebAuthChallenge, };
|
|
14
14
|
export type CacheableMethod = 'GET' | 'HEAD';
|
|
15
15
|
export declare const isCacheableMethod: (m: unknown) => m is CacheableMethod;
|
|
16
16
|
export type RegistryClientOptions = {
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { setTimeout } from 'node:timers/promises';
|
|
|
10
10
|
import { loadPackageJson } from 'package-json-from-dist';
|
|
11
11
|
import { Agent, RetryAgent } from 'undici';
|
|
12
12
|
import { addHeader } from "./add-header.js";
|
|
13
|
-
import { clearRuntimeTokens, deleteToken, getKC, getToken, isToken, keychains, runtimeTokens, setRuntimeToken, setToken, } from "./auth.js";
|
|
13
|
+
import { clearRuntimeTokens, deleteToken, getKC, getToken, getTokenByURL, isToken, keychains, normalizeRegistryKey, runtimeTokens, setRuntimeToken, setToken, } from "./auth.js";
|
|
14
14
|
import { CacheEntry } from "./cache-entry.js";
|
|
15
15
|
import { register } from "./cache-revalidate.js";
|
|
16
16
|
import { bun, deno, node } from "./env.js";
|
|
@@ -22,7 +22,7 @@ import { getTokenResponse } from "./token-response.js";
|
|
|
22
22
|
import { getWebAuthChallenge } from "./web-auth-challenge.js";
|
|
23
23
|
import { getEncondedValue } from "./string-encoding.js";
|
|
24
24
|
import { oidc } from "./oidc.js";
|
|
25
|
-
export { CacheEntry, clearRuntimeTokens, deleteToken, getKC, isToken, keychains, oidc, runtimeTokens, setRuntimeToken, setToken, };
|
|
25
|
+
export { CacheEntry, clearRuntimeTokens, deleteToken, getKC, getTokenByURL, isToken, keychains, normalizeRegistryKey, oidc, runtimeTokens, setRuntimeToken, setToken, };
|
|
26
26
|
export const isCacheableMethod = (m) => m === 'GET' || m === 'HEAD';
|
|
27
27
|
const { version } = loadPackageJson(import.meta.filename, process.env.__VLT_INTERNAL_REGISTRY_CLIENT_PACKAGE_JSON);
|
|
28
28
|
const nua = globalThis.navigator?.userAgent ??
|
|
@@ -213,7 +213,6 @@ export class RegistryClient {
|
|
|
213
213
|
const { useCache = !!m } = options;
|
|
214
214
|
signal?.throwIfAborted();
|
|
215
215
|
// first, try to get from the cache before making any request.
|
|
216
|
-
const { origin } = u;
|
|
217
216
|
const key = `${method !== 'GET' ? method + ' ' : ''}${u}`;
|
|
218
217
|
const buffer = useCache ?
|
|
219
218
|
await this.cache.fetch(key, { context: { integrity } })
|
|
@@ -247,7 +246,7 @@ export class RegistryClient {
|
|
|
247
246
|
}
|
|
248
247
|
options.method = options.method ?? 'GET';
|
|
249
248
|
// will remove if we don't have a token.
|
|
250
|
-
options.headers = addHeader(options.headers, 'authorization', await
|
|
249
|
+
options.headers = addHeader(options.headers, 'authorization', await getTokenByURL(String(u), this.identity));
|
|
251
250
|
let response = null;
|
|
252
251
|
try {
|
|
253
252
|
response = await this.agent.request(options);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vltpkg/registry-client",
|
|
3
3
|
"description": "Fetch package artifacts and metadata from registries",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.29",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
"url": "http://vlt.sh"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@vltpkg/cache": "1.0.0-rc.
|
|
17
|
-
"@vltpkg/cache-unzip": "1.0.0-rc.
|
|
18
|
-
"@vltpkg/error-cause": "1.0.0-rc.
|
|
19
|
-
"@vltpkg/keychain": "1.0.0-rc.
|
|
20
|
-
"@vltpkg/output": "1.0.0-rc.
|
|
21
|
-
"@vltpkg/types": "1.0.0-rc.
|
|
22
|
-
"@vltpkg/url-open": "1.0.0-rc.
|
|
23
|
-
"@vltpkg/xdg": "1.0.0-rc.
|
|
16
|
+
"@vltpkg/cache": "1.0.0-rc.29",
|
|
17
|
+
"@vltpkg/cache-unzip": "1.0.0-rc.29",
|
|
18
|
+
"@vltpkg/error-cause": "1.0.0-rc.29",
|
|
19
|
+
"@vltpkg/keychain": "1.0.0-rc.29",
|
|
20
|
+
"@vltpkg/output": "1.0.0-rc.29",
|
|
21
|
+
"@vltpkg/types": "1.0.0-rc.29",
|
|
22
|
+
"@vltpkg/url-open": "1.0.0-rc.29",
|
|
23
|
+
"@vltpkg/xdg": "1.0.0-rc.29",
|
|
24
24
|
"cache-control-parser": "^2.0.6",
|
|
25
25
|
"package-json-from-dist": "^1.0.1",
|
|
26
26
|
"undici": "^7.16.0"
|