feat(config): add Azure Key Vault secret resolution with env fallback

This commit is contained in:
saravanakumardb1 2026-02-14 22:15:02 -08:00
parent fb3bc750eb
commit 2e5b4de0c4
4 changed files with 351 additions and 0 deletions

View File

@ -18,6 +18,20 @@
"test": "vitest run"
},
"peerDependencies": {
"@azure/identity": ">=4.0.0",
"@azure/keyvault-secrets": ">=4.8.0",
"zod": ">=3.20.0"
},
"peerDependenciesMeta": {
"@azure/identity": {
"optional": true
},
"@azure/keyvault-secrets": {
"optional": true
}
},
"devDependencies": {
"@azure/identity": "^4.13.0",
"@azure/keyvault-secrets": "^4.10.0"
}
}

View File

@ -6,3 +6,8 @@ export {
_resetProductIdentity,
type ProductIdentity,
} from './product-identity.js';
export {
resolveKeyVaultSecrets,
LYSNR_SECRETS,
type SecretMapping,
} from './keyvault.js';

View File

@ -0,0 +1,89 @@
/**
* Azure Key Vault secret resolution for Node.js services + dashboards.
*
* Call resolveKeyVaultSecrets() BEFORE Zod config parsing to populate
* process.env from Key Vault. Falls back gracefully when AKV is unavailable.
*
* Requires: AZURE_KEYVAULT_URL env var (skip if not set).
* Auth: DefaultAzureCredential (managed identity in prod, az cli locally).
*/
export interface SecretMapping {
/** Azure Key Vault secret name (e.g. 'lysnr-cosmos-key') */
kvName: string;
/** Environment variable name to populate (e.g. 'COSMOS_KEY') */
envVar: string;
}
/**
* Resolve secrets from Azure Key Vault into process.env.
*
* - Only fetches secrets whose env var is empty/unset (env takes precedence).
* - Skips entirely if AZURE_KEYVAULT_URL is not set.
* - Logs warnings but does NOT throw services fall back to .env values.
*
* @param secrets - Array of {kvName, envVar} mappings
* @param opts - Optional: custom vault URL override
*/
export async function resolveKeyVaultSecrets(
secrets: SecretMapping[],
opts?: { vaultUrl?: string },
): Promise<void> {
const vaultUrl = opts?.vaultUrl || process.env.AZURE_KEYVAULT_URL;
if (!vaultUrl) return; // No KV configured — use env vars as-is
// Filter to only secrets that are missing from env
const missing = secrets.filter((s) => !process.env[s.envVar]);
if (missing.length === 0) return; // All secrets already in env
try {
const { DefaultAzureCredential } = await import('@azure/identity');
const { SecretClient } = await import('@azure/keyvault-secrets');
const client = new SecretClient(vaultUrl, new DefaultAzureCredential());
const results = await Promise.allSettled(
missing.map(async (s) => {
const secret = await client.getSecret(s.kvName);
if (secret.value) {
process.env[s.envVar] = secret.value;
}
}),
);
const failures = results.filter((r) => r.status === 'rejected');
if (failures.length > 0) {
console.warn(
`[keyvault] ${failures.length}/${missing.length} secrets failed to resolve — falling back to env vars`,
);
}
} catch (err) {
console.warn(`[keyvault] Unable to connect to Key Vault at ${vaultUrl} — using env vars`);
}
}
/**
* Standard secret mappings used across all LysnrAI services.
* Services pick the subset they need.
*/
export const LYSNR_SECRETS = {
COSMOS_KEY: { kvName: 'lysnr-cosmos-key', envVar: 'COSMOS_KEY' },
COSMOS_ENDPOINT: { kvName: 'lysnr-cosmos-endpoint', envVar: 'COSMOS_ENDPOINT' },
JWT_SECRET: { kvName: 'lysnr-jwt-secret', envVar: 'JWT_SECRET' },
STRIPE_SECRET_KEY: { kvName: 'lysnr-stripe-secret-key', envVar: 'STRIPE_SECRET_KEY' },
STRIPE_WEBHOOK_SECRET: { kvName: 'lysnr-stripe-webhook-secret', envVar: 'STRIPE_WEBHOOK_SECRET' },
BILLING_INTERNAL_KEY: { kvName: 'lysnr-billing-internal-key', envVar: 'BILLING_INTERNAL_KEY' },
AZURE_BLOB_CONNECTION_STRING: {
kvName: 'lysnr-blob-connection-string',
envVar: 'AZURE_BLOB_CONNECTION_STRING',
},
AZURE_BLOB_ACCOUNT_KEY: { kvName: 'lysnr-blob-account-key', envVar: 'AZURE_BLOB_ACCOUNT_KEY' },
GEMINI_API_KEY: { kvName: 'lysnr-gemini-api-key', envVar: 'GEMINI_API_KEY' },
SEED_SECRET: { kvName: 'lysnr-seed-secret', envVar: 'SEED_SECRET' },
AZURE_SPEECH_KEY: { kvName: 'lysnr-azure-speech-key', envVar: 'AZURE_SPEECH_KEY' },
AZURE_OPENAI_KEY: { kvName: 'lysnr-azure-openai-key', envVar: 'AZURE_OPENAI_KEY' },
AZURE_OPENAI_ENDPOINT: {
kvName: 'lysnr-azure-openai-endpoint',
envVar: 'AZURE_OPENAI_ENDPOINT',
},
} as const satisfies Record<string, SecretMapping>;

243
pnpm-lock.yaml generated
View File

@ -92,6 +92,13 @@ importers:
zod:
specifier: '>=3.20.0'
version: 4.3.6
devDependencies:
'@azure/identity':
specifier: ^4.13.0
version: 4.13.0
'@azure/keyvault-secrets':
specifier: ^4.10.0
version: 4.10.0(@azure/core-client@1.10.1)
packages/cosmos:
dependencies:
@ -383,6 +390,10 @@ packages:
resolution: {integrity: sha512-fPnfL4JsmJJ/jEYUhlznKfrEr2pMvJwBncGVcUC2Xi7Nlj0MrUMRE+UOrptl/lRV2W7l68Br+b9Ikzm0KiZZHg==}
engines: {node: '>=20.0.0'}
'@azure/identity@4.13.0':
resolution: {integrity: sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==}
engines: {node: '>=20.0.0'}
'@azure/keyvault-common@2.0.0':
resolution: {integrity: sha512-wRLVaroQtOqfg60cxkzUkGKrKMsCP6uYXAOomOIysSMyt1/YM0eUn9LqieAWM8DLcU4+07Fio2YGpPeqUbpP9w==}
engines: {node: '>=18.0.0'}
@ -391,10 +402,26 @@ packages:
resolution: {integrity: sha512-eDT7iXoBTRZ2n3fLiftuGJFD+yjkiB1GNqzU2KbY1TLYeXeSPVTVgn2eJ5vmRTZ11978jy2Kg2wI7xa9Tyr8ag==}
engines: {node: '>=18.0.0'}
'@azure/keyvault-secrets@4.10.0':
resolution: {integrity: sha512-WvXc3h2hqHL1pMzUU7ANE2RBKoxjK3JQc0YNn6GUFvOWQtf2ZR+sH4/5cZu8zAg62v9qLCduBN7065nHKl+AOA==}
engines: {node: '>=18.0.0'}
'@azure/logger@1.3.0':
resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==}
engines: {node: '>=20.0.0'}
'@azure/msal-browser@4.28.2':
resolution: {integrity: sha512-6vYUMvs6kJxJgxaCmHn/F8VxjLHNh7i9wzfwPGf8kyBJ8Gg2yvBXx175Uev8LdrD1F5C4o7qHa2CC4IrhGE1XQ==}
engines: {node: '>=0.8.0'}
'@azure/msal-common@15.14.2':
resolution: {integrity: sha512-n8RBJEUmd5QotoqbZfd+eGBkzuFI1KX6jw2b3WcpSyGjwmzoeI/Jb99opIBPHpb8y312NB+B6+FGi2ZVSR8yfA==}
engines: {node: '>=0.8.0'}
'@azure/msal-node@3.8.7':
resolution: {integrity: sha512-a+Xnrae+uwLnlw68bplS1X4kuJ9F/7K6afuMFyRkNIskhjgDezl5Fhrx+1pmAlDmC0VaaAxjRQMp1OmcqVwkIg==}
engines: {node: '>=16'}
'@azure/storage-blob@12.31.0':
resolution: {integrity: sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg==}
engines: {node: '>=20.0.0'}
@ -1244,6 +1271,13 @@ packages:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
bundle-name@4.1.0:
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
engines: {node: '>=18'}
cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
@ -1350,6 +1384,18 @@ packages:
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
default-browser-id@5.0.1:
resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==}
engines: {node: '>=18'}
default-browser@5.5.0:
resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==}
engines: {node: '>=18'}
define-lazy-prop@3.0.0:
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
engines: {node: '>=12'}
dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
@ -1372,6 +1418,9 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
emoji-regex@10.6.0:
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
@ -1702,6 +1751,11 @@ packages:
resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==}
engines: {node: '>= 10'}
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@ -1722,6 +1776,11 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
hasBin: true
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
@ -1741,6 +1800,10 @@ packages:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
is-wsl@3.1.0:
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
engines: {node: '>=16'}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@ -1814,6 +1877,16 @@ packages:
jsonfile@4.0.0:
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
jsonwebtoken@9.0.3:
resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==}
engines: {node: '>=12', npm: '>=6'}
jwa@2.0.1:
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
jws@4.0.1:
resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@ -1845,9 +1918,30 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
lodash.includes@4.3.0:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
lodash.isboolean@3.0.3:
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
lodash.isinteger@4.0.4:
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
lodash.isnumber@3.0.3:
resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
lodash.isstring@4.0.1:
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lodash.startcase@4.4.0:
resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
@ -1957,6 +2051,10 @@ packages:
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'}
open@10.2.0:
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
engines: {node: '>=18'}
openapi-types@12.1.3:
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
@ -2172,9 +2270,16 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
run-applescript@7.1.0:
resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==}
engines: {node: '>=18'}
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
safe-regex2@5.0.0:
resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==}
@ -2423,6 +2528,10 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
vite-node@3.2.4:
resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@ -2542,6 +2651,10 @@ packages:
resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=18'}
wsl-utils@0.1.0:
resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
engines: {node: '>=18'}
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
@ -2695,6 +2808,22 @@ snapshots:
- '@azure/core-client'
- supports-color
'@azure/identity@4.13.0':
dependencies:
'@azure/abort-controller': 2.1.2
'@azure/core-auth': 1.10.1
'@azure/core-client': 1.10.1
'@azure/core-rest-pipeline': 1.22.2
'@azure/core-tracing': 1.3.1
'@azure/core-util': 1.13.1
'@azure/logger': 1.3.0
'@azure/msal-browser': 4.28.2
'@azure/msal-node': 3.8.7
open: 10.2.0
tslib: 2.8.1
transitivePeerDependencies:
- supports-color
'@azure/keyvault-common@2.0.0':
dependencies:
'@azure/abort-controller': 2.1.2
@ -2726,6 +2855,24 @@ snapshots:
- '@azure/core-client'
- supports-color
'@azure/keyvault-secrets@4.10.0(@azure/core-client@1.10.1)':
dependencies:
'@azure-rest/core-client': 2.5.1
'@azure/abort-controller': 2.1.2
'@azure/core-auth': 1.10.1
'@azure/core-http-compat': 2.3.2(@azure/core-client@1.10.1)(@azure/core-rest-pipeline@1.22.2)
'@azure/core-lro': 2.7.2
'@azure/core-paging': 1.6.2
'@azure/core-rest-pipeline': 1.22.2
'@azure/core-tracing': 1.3.1
'@azure/core-util': 1.13.1
'@azure/keyvault-common': 2.0.0
'@azure/logger': 1.3.0
tslib: 2.8.1
transitivePeerDependencies:
- '@azure/core-client'
- supports-color
'@azure/logger@1.3.0':
dependencies:
'@typespec/ts-http-runtime': 0.3.3
@ -2733,6 +2880,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@azure/msal-browser@4.28.2':
dependencies:
'@azure/msal-common': 15.14.2
'@azure/msal-common@15.14.2': {}
'@azure/msal-node@3.8.7':
dependencies:
'@azure/msal-common': 15.14.2
jsonwebtoken: 9.0.3
uuid: 8.3.2
'@azure/storage-blob@12.31.0':
dependencies:
'@azure/abort-controller': 2.1.2
@ -3609,6 +3768,12 @@ snapshots:
dependencies:
fill-range: 7.1.1
buffer-equal-constant-time@1.0.1: {}
bundle-name@4.1.0:
dependencies:
run-applescript: 7.1.0
cac@6.7.14: {}
call-bind-apply-helpers@1.0.2:
@ -3708,6 +3873,15 @@ snapshots:
deep-is@0.1.4: {}
default-browser-id@5.0.1: {}
default-browser@5.5.0:
dependencies:
bundle-name: 4.1.0
default-browser-id: 5.0.1
define-lazy-prop@3.0.0: {}
dequal@2.0.3: {}
detect-indent@6.1.0: {}
@ -3726,6 +3900,10 @@ snapshots:
eastasianwidth@0.2.0: {}
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
emoji-regex@10.6.0: {}
emoji-regex@8.0.0: {}
@ -4117,6 +4295,8 @@ snapshots:
ipaddr.js@2.3.0: {}
is-docker@3.0.0: {}
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
@ -4131,6 +4311,10 @@ snapshots:
dependencies:
is-extglob: 2.1.1
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
is-number@7.0.0: {}
is-potential-custom-element-name@1.0.1:
@ -4144,6 +4328,10 @@ snapshots:
is-windows@1.0.2: {}
is-wsl@3.1.0:
dependencies:
is-inside-container: 1.0.0
isexe@2.0.0: {}
istanbul-lib-coverage@3.2.2: {}
@ -4241,6 +4429,30 @@ snapshots:
optionalDependencies:
graceful-fs: 4.2.11
jsonwebtoken@9.0.3:
dependencies:
jws: 4.0.1
lodash.includes: 4.3.0
lodash.isboolean: 3.0.3
lodash.isinteger: 4.0.4
lodash.isnumber: 3.0.3
lodash.isplainobject: 4.0.6
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
semver: 7.7.4
jwa@2.0.1:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
jws@4.0.1:
dependencies:
jwa: 2.0.1
safe-buffer: 5.2.1
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@ -4290,8 +4502,22 @@ snapshots:
dependencies:
p-locate: 5.0.0
lodash.includes@4.3.0: {}
lodash.isboolean@3.0.3: {}
lodash.isinteger@4.0.4: {}
lodash.isnumber@3.0.3: {}
lodash.isplainobject@4.0.6: {}
lodash.isstring@4.0.1: {}
lodash.merge@4.6.2: {}
lodash.once@4.1.1: {}
lodash.startcase@4.4.0: {}
log-update@6.1.0:
@ -4383,6 +4609,13 @@ snapshots:
dependencies:
mimic-function: 5.0.1
open@10.2.0:
dependencies:
default-browser: 5.5.0
define-lazy-prop: 3.0.0
is-inside-container: 1.0.0
wsl-utils: 0.1.0
openapi-types@12.1.3: {}
optionator@0.9.4:
@ -4590,10 +4823,14 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.57.1
fsevents: 2.3.3
run-applescript@7.1.0: {}
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
safe-buffer@5.2.1: {}
safe-regex2@5.0.0:
dependencies:
ret: 0.5.0
@ -4823,6 +5060,8 @@ snapshots:
dependencies:
punycode: 2.3.1
uuid@8.3.2: {}
vite-node@3.2.4(@types/node@20.19.33)(tsx@4.21.0)(yaml@2.8.2):
dependencies:
cac: 6.7.14
@ -5030,6 +5269,10 @@ snapshots:
string-width: 7.2.0
strip-ansi: 7.1.2
wsl-utils@0.1.0:
dependencies:
is-wsl: 3.1.0
xml-name-validator@5.0.0:
optional: true