UNPKG

@confkit/azure

Version:

[![npm](https://img.shields.io/npm/v/%40confkit%2Fazure)](https://www.npmjs.com/package/@confkit/azure) [![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/alexdotpink/confkit/blob/main/LICENSE) ![node](https://img.shields.io/ba

91 lines 2.94 kB
// src/index.ts import { DefaultAzureCredential } from "@azure/identity"; import { SecretClient } from "@azure/keyvault-secrets"; function defaultKeyFromName(name) { return name.replace(/[^A-Za-z0-9_]/g, "_").toUpperCase(); } function azureKeyVaultSource(opts) { const cred = opts.credential ?? new DefaultAzureCredential(); const client = new SecretClient(opts.vaultUrl, cred); const mapNameToKey = opts.mapNameToKey ?? defaultKeyFromName; let cache; let timer; async function fetchNow() { const values = {}; const versions = {}; const names = []; for await (const prop of client.listPropertiesOfSecrets().byPage({ maxPageSize: 100 })) { for (const p of prop) { const name = p.name; if (opts.namePrefix && !name.startsWith(opts.namePrefix)) continue; names.push(name); } } const maxConc = Math.max(1, Math.min(opts.maxConcurrency ?? 8, 24)); let i = 0; await Promise.all( Array.from({ length: maxConc }).map(async () => { while (i < names.length) { const idx = i++; const name = names[idx]; const key = mapNameToKey(name); try { const s = await client.getSecret(name); const val = s.value ?? ""; values[key] = val; versions[key] = s.properties.version; } catch { } } }) ); return { values, versions }; } async function refresh() { const ttl = opts.ttlMs ?? 5 * 60 * 1e3; const jitter = opts.jitter ?? 0.1; const now = Date.now(); const { values: nextValues, versions: nextVersions } = await fetchNow(); if (cache) { const keys = /* @__PURE__ */ new Set([...Object.keys(cache.value), ...Object.keys(nextValues)]); for (const k of keys) { const prevV = cache.value[k]; const curV = nextValues[k]; const prevVer = cache.versions[k]; const curVer = nextVersions[k]; if ((prevV !== curV || prevVer !== curVer) && curV !== void 0 && opts.onRotate) { opts.onRotate(k, curV, { version: curVer }); } } } const expires = now + Math.floor(ttl * (1 - jitter + Math.random() * jitter * 2)); cache = { value: nextValues, expires, versions: nextVersions }; } function schedule() { if (!opts.background) return; const now = Date.now(); const ms = cache ? Math.max(0, cache.expires - now) : opts.ttlMs ?? 5 * 60 * 1e3; if (timer) clearTimeout(timer); timer = setTimeout(async () => { try { await refresh(); } finally { schedule(); } }, ms); } return async () => { const now = Date.now(); if (!cache || now >= cache.expires) { await refresh(); schedule(); } return cache.value; }; } var index_default = azureKeyVaultSource; export { azureKeyVaultSource, index_default as default }; //# sourceMappingURL=index.js.map