Estructura inicial del proyecto

This commit is contained in:
2026-06-02 16:57:08 +00:00
commit 8b306b9afc
9864 changed files with 1435687 additions and 0 deletions

View File

@ -0,0 +1,539 @@
/*! @azure/msal-common v16.6.2 2026-05-19 */
'use strict';
import { getAndFlushLogsFromCache } from '../../logger/Logger.mjs';
import { IntFields, PerformanceEventStatus, EXT_FIELD_PREFIX } from './PerformanceEvent.mjs';
import { AuthError } from '../../error/AuthError.mjs';
import { CacheError } from '../../error/CacheError.mjs';
import { ServerError } from '../../error/ServerError.mjs';
import { InteractionRequiredAuthError } from '../../error/InteractionRequiredAuthError.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Starts context by adding payload to the stack
* @param event {PerformanceEvent}
* @param stack {?PerformanceEventStackedContext[]} stack
*/
function startContext(event, stack) {
if (!stack) {
return;
}
stack.push({
name: event.name,
});
}
/**
* Ends context by removing payload from the stack and returning parent or self, if stack is empty, payload
*
* @param event {PerformanceEvent}
* @param stack {?PerformanceEventStackedContext[]} stack
* @param error {?unknown} error
*/
function endContext(event, stack, error) {
if (!stack?.length) {
return;
}
const peek = (stack) => {
return stack.length ? stack[stack.length - 1] : undefined;
};
const abbrEventName = event.name;
const top = peek(stack);
if (top?.name !== abbrEventName) {
return;
}
const current = stack?.pop();
if (!current) {
return;
}
const errorCode = error instanceof AuthError
? error.errorCode
: error instanceof Error
? error.name
: undefined;
const subErr = error instanceof AuthError ? error.subError : undefined;
if (errorCode && current.childErr !== errorCode) {
current.err = errorCode;
if (subErr) {
current.subErr = subErr;
}
}
delete current.name;
delete current.childErr;
const context = {
...current,
dur: event.durationMs,
};
if (!event.success) {
context.fail = 1;
}
const parent = peek(stack);
if (!parent) {
return { [abbrEventName]: context };
}
if (errorCode) {
parent.childErr = errorCode;
}
let childName;
if (!parent[abbrEventName]) {
childName = abbrEventName;
}
else {
const siblings = Object.keys(parent).filter((key) => key.startsWith(abbrEventName)).length;
childName = `${abbrEventName}_${siblings + 1}`;
}
parent[childName] = context;
return parent;
}
/**
* Adds error name and stack trace to the telemetry event
* @param error {Error}
* @param logger {Logger}
* @param event {PerformanceEvent}
* @param stackMaxSize {number} max error stack size to capture
*/
function addError(error, logger, event, stackMaxSize = 5) {
if (!(error instanceof Error)) {
logger.trace("PerformanceClient.addErrorStack: Input error is not instance of Error", event.correlationId);
return;
}
else if (error instanceof AuthError) {
event.errorCode = error.errorCode;
event.subErrorCode = error.subError;
if (!event.serverErrorNo &&
(error instanceof ServerError ||
error instanceof InteractionRequiredAuthError) &&
error.errorNo) {
event.serverErrorNo = error.errorNo;
}
return;
}
else if (error instanceof CacheError) {
event.errorCode = error.errorCode;
return;
}
else if (event.errorStack?.length) {
logger.trace("PerformanceClient.addErrorStack: Stack already exist", event.correlationId);
return;
}
else if (!error.stack?.length) {
logger.trace("PerformanceClient.addErrorStack: Input stack is empty", event.correlationId);
return;
}
if (error.stack) {
event.errorStack = compactStack(error.stack, stackMaxSize);
}
event.errorName = error.name;
}
/**
* Compacts error stack into array by fetching N first entries
* @param stack {string} error stack
* @param stackMaxSize {number} max error stack size to capture
* @returns {string[]}
*/
function compactStack(stack, stackMaxSize) {
if (stackMaxSize < 0) {
return [];
}
const stackArr = stack.split("\n") || [];
const res = [];
// Check for a handful of known, common runtime errors and log them (with redaction where applicable).
const firstLine = stackArr[0];
if (firstLine.startsWith("TypeError: Cannot read property") ||
firstLine.startsWith("TypeError: Cannot read properties of") ||
firstLine.startsWith("TypeError: Cannot set property") ||
firstLine.startsWith("TypeError: Cannot set properties of") ||
firstLine.endsWith("is not a function")) {
// These types of errors are not at risk of leaking PII. They will indicate unavailable APIs
res.push(compactStackLine(firstLine));
}
else if (firstLine.startsWith("SyntaxError") ||
firstLine.startsWith("TypeError")) {
// Prevent unintentional leaking of arbitrary info by redacting contents between both single and double quotes
res.push(compactStackLine(
// Example: SyntaxError: Unexpected token 'e', "test" is not valid JSON -> SyntaxError: Unexpected token <redacted>, <redacted> is not valid JSON
firstLine.replace(/['].*[']|["].*["]/g, "<redacted>")));
}
// Get top N stack lines
for (let ix = 1; ix < stackArr.length; ix++) {
if (res.length >= stackMaxSize) {
break;
}
const line = stackArr[ix];
res.push(compactStackLine(line));
}
return res;
}
/**
* Compacts error stack line by shortening file path
* Example: https://localhost/msal-common/src/authority/Authority.js:100:1 -> Authority.js:100:1
* @param line {string} stack line
* @returns {string}
*/
function compactStackLine(line) {
const filePathIx = line.lastIndexOf(" ") + 1;
if (filePathIx < 1) {
return line;
}
const filePath = line.substring(filePathIx);
let fileNameIx = filePath.lastIndexOf("/");
fileNameIx = fileNameIx < 0 ? filePath.lastIndexOf("\\") : fileNameIx;
if (fileNameIx >= 0) {
return (line.substring(0, filePathIx) +
"(" +
filePath.substring(fileNameIx + 1) +
(filePath.charAt(filePath.length - 1) === ")" ? "" : ")")).trimStart();
}
return line.trimStart();
}
function getAccountType(account) {
const idTokenClaims = account?.idTokenClaims;
if (idTokenClaims?.tfp || idTokenClaims?.acr) {
return "B2C";
}
if (!idTokenClaims?.tid) {
return undefined;
}
else if (idTokenClaims?.tid === "9188040d-6c67-4c5b-b112-36a304b66dad") {
return "MSA";
}
return "AAD";
}
class PerformanceClient {
/**
* Creates an instance of PerformanceClient,
* an abstract class containing core performance telemetry logic.
*
* @constructor
* @param {string} clientId Client ID of the application
* @param {string} authority Authority used by the application
* @param {Logger} logger Logger used by the application
* @param {string} libraryName Name of the library
* @param {string} libraryVersion Version of the library
* @param {ApplicationTelemetry} applicationTelemetry application name and version
* @param {Set<String>} intFields integer fields to be truncated
*/
constructor(clientId, authority, logger, libraryName, libraryVersion, applicationTelemetry, intFields) {
this.authority = authority;
this.libraryName = libraryName;
this.libraryVersion = libraryVersion;
this.applicationTelemetry = applicationTelemetry;
this.clientId = clientId;
this.logger = logger;
this.callbacks = new Map();
this.eventsByCorrelationId = new Map();
this.eventStack = new Map();
this.intFields = intFields || new Set();
for (const item of IntFields) {
this.intFields.add(item);
}
}
/**
* Starts measuring performance for a given operation. Returns a function that should be used to end the measurement.
*
* @param {PerformanceEvents} measureName
* @param {?string} [correlationId]
* @returns {InProgressPerformanceEvent}
*/
startMeasurement(measureName, correlationId) {
// Generate a placeholder correlation if the request does not provide one
const eventCorrelationId = correlationId || this.generateId();
const inProgressEvent = {
eventId: this.generateId(),
status: PerformanceEventStatus.InProgress,
authority: this.authority,
libraryName: this.libraryName,
libraryVersion: this.libraryVersion,
clientId: this.clientId,
name: measureName,
startTimeMs: Date.now(),
correlationId: eventCorrelationId,
appName: this.applicationTelemetry?.appName,
appVersion: this.applicationTelemetry?.appVersion,
};
// Store in progress events so they can be discarded if not ended properly
this.cacheEventByCorrelationId(inProgressEvent);
startContext(inProgressEvent, this.eventStack.get(eventCorrelationId));
// Return the event and functions the caller can use to properly end/flush the measurement
return {
end: (event, error, account) => {
return this.endMeasurement({
// Initial set of event properties
...inProgressEvent,
// Properties set when event ends
...event,
}, error, account);
},
discard: () => {
return this.discardMeasurements(inProgressEvent.correlationId);
},
add: (fields) => {
return this.addFields(fields, inProgressEvent.correlationId);
},
increment: (fields) => {
return this.incrementFields(fields, inProgressEvent.correlationId);
},
event: inProgressEvent,
};
}
/**
* Stops measuring the performance for an operation. Should only be called directly by PerformanceClient classes,
* as consumers should instead use the function returned by startMeasurement.
* Adds a new field named as "[event name]DurationMs" for sub-measurements, completes and emits an event
* otherwise.
*
* @param {PerformanceEvent} event
* @param {unknown} error
* @param {AccountInfo?} account
* @returns {(PerformanceEvent | null)}
*/
endMeasurement(event, error, account) {
const rootEvent = this.eventsByCorrelationId.get(event.correlationId);
if (!rootEvent) {
this.logger.trace(`PerformanceClient: Measurement not found for '${event.eventId}'`, event.correlationId);
return null;
}
const isRoot = event.eventId === rootEvent.eventId;
event.durationMs = Math.round(event.durationMs || this.getDurationMs(event.startTimeMs));
const context = JSON.stringify(endContext(event, this.eventStack.get(rootEvent.correlationId), error));
if (isRoot) {
this.discardMeasurements(rootEvent.correlationId);
}
else {
rootEvent.incompleteSubMeasurements?.delete(event.eventId);
}
if (error) {
addError(error, this.logger, rootEvent);
}
// Add sub-measurement attribute to root event's ext field.
if (!isRoot) {
rootEvent.ext = {
...rootEvent.ext,
...event.ext,
};
rootEvent.ext[event.name + "DurationMs"] = Math.floor(event.durationMs);
return { ...rootEvent };
}
if (isRoot &&
!error &&
(rootEvent.errorCode || rootEvent.subErrorCode)) {
this.logger.trace(`PerformanceClient: Remove error and sub-error codes for root event '${event.name}' as intermediate error was successfully handled`, event.correlationId);
rootEvent.errorCode = undefined;
rootEvent.subErrorCode = undefined;
}
let finalEvent = { ...rootEvent, ...event };
let incompleteSubsCount = 0;
// Incomplete sub-measurements are discarded. They are likely an instrumentation bug that should be fixed.
finalEvent.incompleteSubMeasurements?.forEach((subMeasurement) => {
this.logger.trace(`PerformanceClient: Incomplete submeasurement '${subMeasurement.name}' found for '${event.name}'`, finalEvent.correlationId);
incompleteSubsCount++;
});
finalEvent.incompleteSubMeasurements = undefined;
const logs = getAndFlushLogsFromCache(event.correlationId);
// Format logs: [millis1,hash1;millis2,hash2;...]
const formattedLogs = logs
.map((logMessage) => `${logMessage.milliseconds},${logMessage.hash}`)
.join(";");
finalEvent = {
...finalEvent,
status: PerformanceEventStatus.Completed,
incompleteSubsCount,
context,
logs: formattedLogs,
};
if (account) {
finalEvent.accountType = getAccountType(account);
finalEvent.dataBoundary = account.dataBoundary;
}
this.truncateIntegralFields(finalEvent);
this.emitEvents([finalEvent], event.correlationId);
return finalEvent;
}
/**
* Saves extra information to be emitted when the measurements are flushed
* @param fields
* @param correlationId
*/
addFields(fields, correlationId) {
const event = this.eventsByCorrelationId.get(correlationId);
if (event) {
const staticFields = {};
const dynamicFields = {};
for (const key in fields) {
if (key.startsWith(EXT_FIELD_PREFIX)) {
const dynamicKey = key.slice(EXT_FIELD_PREFIX.length);
const value = fields[key];
if (typeof value === "string" ||
typeof value === "number") {
dynamicFields[dynamicKey] = value;
}
}
else {
staticFields[key] = fields[key];
}
}
const updatedEvent = {
...event,
...staticFields,
};
if (Object.keys(dynamicFields).length) {
updatedEvent.ext = {
...updatedEvent.ext,
...dynamicFields,
};
}
this.eventsByCorrelationId.set(correlationId, updatedEvent);
}
else {
this.logger.trace("PerformanceClient: Event not found for", correlationId);
}
}
/**
* Increment counters to be emitted when the measurements are flushed
* @param fields {string[]}
* @param correlationId {string} correlation identifier
*/
incrementFields(fields, correlationId) {
const event = this.eventsByCorrelationId.get(correlationId);
if (event) {
for (const counter in fields) {
if (counter.startsWith(EXT_FIELD_PREFIX)) {
event.ext = event.ext || {};
// Route to ext sub-object
const dynamicKey = counter.slice(EXT_FIELD_PREFIX.length);
const currentValue = event.ext[dynamicKey];
if (currentValue === undefined) {
event.ext[dynamicKey] = 0;
}
else if (isNaN(Number(currentValue))) {
return;
}
event.ext[dynamicKey] =
(Number(event.ext[dynamicKey]) || 0) +
(fields[counter] ?? 0);
}
else {
/* eslint-disable custom-msal/no-dynamic-telemetry-fields -- internal dispatching of static fields by name */
if (!event.hasOwnProperty(counter)) {
event[counter] = 0;
}
else if (isNaN(Number(event[counter]))) {
return;
}
event[counter] += fields[counter];
/* eslint-enable custom-msal/no-dynamic-telemetry-fields */
}
}
}
else {
this.logger.trace("PerformanceClient: Event not found for", correlationId);
}
}
/**
* Upserts event into event cache.
* First key is the correlation id, second key is the event id.
* Allows for events to be grouped by correlation id,
* and to easily allow for properties on them to be updated.
*
* @private
* @param {PerformanceEvent} event
*/
cacheEventByCorrelationId(event) {
const rootEvent = this.eventsByCorrelationId.get(event.correlationId);
if (rootEvent) {
rootEvent.incompleteSubMeasurements =
rootEvent.incompleteSubMeasurements || new Map();
rootEvent.incompleteSubMeasurements.set(event.eventId, {
name: event.name,
startTimeMs: event.startTimeMs,
});
}
else {
this.eventsByCorrelationId.set(event.correlationId, { ...event });
this.eventStack.set(event.correlationId, []);
}
}
/**
* Removes measurements and aux data for a given correlation id.
*
* @param {string} correlationId
*/
discardMeasurements(correlationId) {
this.eventsByCorrelationId.delete(correlationId);
this.eventStack.delete(correlationId);
}
/**
* Registers a callback function to receive performance events.
*
* @param {PerformanceCallbackFunction} callback
* @returns {string}
*/
addPerformanceCallback(callback) {
for (const [id, cb] of this.callbacks) {
if (cb.toString() === callback.toString()) {
this.logger.warning(`PerformanceClient: Performance callback is already registered with id: ${id}`, "");
return id;
}
}
const callbackId = this.generateId();
this.callbacks.set(callbackId, callback);
this.logger.verbose(`PerformanceClient: Performance callback registered with id: '${callbackId}'`, "");
return callbackId;
}
/**
* Removes a callback registered with addPerformanceCallback.
*
* @param {string} callbackId
* @returns {boolean}
*/
removePerformanceCallback(callbackId) {
const result = this.callbacks.delete(callbackId);
if (result) {
this.logger.verbose(`PerformanceClient: Performance callback '${callbackId}' removed.`, "");
}
else {
this.logger.verbose(`PerformanceClient: Performance callback '${callbackId}' not removed.`, "");
}
return result;
}
/**
* Emits events to all registered callbacks.
*
* @param {PerformanceEvent[]} events
* @param {?string} [correlationId]
*/
emitEvents(events, correlationId) {
this.logger.verbose("PerformanceClient: Emitting performance events", correlationId);
this.callbacks.forEach((callback, callbackId) => {
this.logger.trace(`PerformanceClient: Emitting event to callback '${callbackId}'`, correlationId);
callback.apply(null, [events]);
});
}
/**
* Enforce truncation of integral fields in performance event.
* @param {PerformanceEvent} event performance event to update.
*/
truncateIntegralFields(event) {
this.intFields.forEach((key) => {
/* eslint-disable custom-msal/no-dynamic-telemetry-fields -- internal truncation of known integer fields */
if (key in event && typeof event[key] === "number") {
event[key] = Math.floor(event[key]);
}
/* eslint-enable custom-msal/no-dynamic-telemetry-fields */
});
}
/**
* Returns event duration in milliseconds
* @param startTimeMs {number}
* @returns {number}
*/
getDurationMs(startTimeMs) {
const durationMs = Date.now() - startTimeMs;
// Handle clock skew
return durationMs < 0 ? durationMs : 0;
}
}
export { PerformanceClient, addError, compactStack, compactStackLine, endContext, getAccountType, startContext };
//# sourceMappingURL=PerformanceClient.mjs.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,55 @@
/*! @azure/msal-common v16.6.2 2026-05-19 */
'use strict';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* State of the performance event.
*
* @export
* @enum {number}
*/
const PerformanceEventStatus = {
NotStarted: 0,
InProgress: 1,
Completed: 2,
};
/**
* Prefix used to mark telemetry field names as dynamic.
* Fields with this prefix in addFields/incrementFields calls will be routed
* to the PerformanceEvent.ext sub-object.
*/
const EXT_FIELD_PREFIX = "ext.";
const IntFields = new Set([
"accessTokenSize",
"durationMs",
"idTokenSize",
"matsSilentStatus",
"matsHttpStatus",
"refreshTokenSize",
"startTimeMs",
"status",
"multiMatchedAT",
"multiMatchedID",
"multiMatchedRT",
"unencryptedCacheCount",
"encryptedCacheExpiredCount",
"oldAccountCount",
"oldAccessCount",
"oldIdCount",
"oldRefreshCount",
"currAccountCount",
"currAccessCount",
"currIdCount",
"currRefreshCount",
"expiredCacheRemovedCount",
"upgradedCacheCount",
"cacheMatchedAccounts",
"networkRtt",
"redirectBridgeTimeoutMs",
"redirectBridgeMessageVersion",
]);
export { EXT_FIELD_PREFIX, IntFields, PerformanceEventStatus };
//# sourceMappingURL=PerformanceEvent.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"PerformanceEvent.mjs","sources":["../../../src/telemetry/performance/PerformanceEvent.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;AAGG;AAIH;;;;;AAKG;AACU,MAAA,sBAAsB,GAAG;AAClC,IAAA,UAAU,EAAE,CAAC;AACb,IAAA,UAAU,EAAE,CAAC;AACb,IAAA,SAAS,EAAE,CAAC;EACL;AAkfX;;;;AAIG;AACI,MAAM,gBAAgB,GAAG,OAAO;AAE1B,MAAA,SAAS,GAAwB,IAAI,GAAG,CAAC;IAClD,iBAAiB;IACjB,YAAY;IACZ,aAAa;IACb,kBAAkB;IAClB,gBAAgB;IAChB,kBAAkB;IAClB,aAAa;IACb,QAAQ;IACR,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,uBAAuB;IACvB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,iBAAiB;IACjB,aAAa;IACb,kBAAkB;IAClB,0BAA0B;IAC1B,oBAAoB;IACpB,sBAAsB;IACtB,YAAY;IACZ,yBAAyB;IACzB,8BAA8B;AACjC,CAAA;;;;"}

View File

@ -0,0 +1,74 @@
/*! @azure/msal-common v16.6.2 2026-05-19 */
'use strict';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Time spent sending/waiting for the response of a request to the token endpoint
*/
const NetworkClientSendPostRequestAsync = "networkClientSendPostRequestAsync";
const RefreshTokenClientExecutePostToTokenEndpoint = "refreshTokenClientExecutePostToTokenEndpoint";
const AuthorizationCodeClientExecutePostToTokenEndpoint = "authorizationCodeClientExecutePostToTokenEndpoint";
/**
* Time spent on the network for refresh token acquisition
*/
const RefreshTokenClientExecuteTokenRequest = "refreshTokenClientExecuteTokenRequest";
/**
* Time taken for acquiring refresh token , records RT size
*/
const RefreshTokenClientAcquireToken = "refreshTokenClientAcquireToken";
/**
* Time taken for acquiring cached refresh token
*/
const RefreshTokenClientAcquireTokenWithCachedRefreshToken = "refreshTokenClientAcquireTokenWithCachedRefreshToken";
/**
* Helper function to create token request body in RefreshTokenClient (msal-common).
*/
const RefreshTokenClientCreateTokenRequestBody = "refreshTokenClientCreateTokenRequestBody";
const SilentFlowClientGenerateResultFromCacheRecord = "silentFlowClientGenerateResultFromCacheRecord";
/**
* getAuthCodeUrl API (msal-browser and msal-node).
*/
const GetAuthCodeUrl = "getAuthCodeUrl";
/**
* Functions from InteractionHandler (msal-browser)
*/
const HandleCodeResponseFromServer = "handleCodeResponseFromServer";
/**
* APIs in Authorization Code Client (msal-common)
*/
const AuthClientExecuteTokenRequest = "authClientExecuteTokenRequest";
const AuthClientCreateTokenRequestBody = "authClientCreateTokenRequestBody";
const UpdateTokenEndpointAuthority = "updateTokenEndpointAuthority";
/**
* Generate functions in PopTokenGenerator (msal-common)
*/
const PopTokenGenerateCnf = "popTokenGenerateCnf";
/**
* handleServerTokenResponse API in ResponseHandler (msal-common)
*/
const HandleServerTokenResponse = "handleServerTokenResponse";
/**
* Authority functions
*/
const AuthorityResolveEndpointsAsync = "authorityResolveEndpointsAsync";
const AuthorityGetCloudDiscoveryMetadataFromNetwork = "authorityGetCloudDiscoveryMetadataFromNetwork";
const AuthorityUpdateCloudDiscoveryMetadata = "authorityUpdateCloudDiscoveryMetadata";
const AuthorityGetEndpointMetadataFromNetwork = "authorityGetEndpointMetadataFromNetwork";
const AuthorityUpdateEndpointMetadata = "authorityUpdateEndpointMetadata";
const AuthorityUpdateMetadataWithRegionalInformation = "authorityUpdateMetadataWithRegionalInformation";
/**
* Region Discovery functions
*/
const RegionDiscoveryDetectRegion = "regionDiscoveryDetectRegion";
const RegionDiscoveryGetRegionFromIMDS = "regionDiscoveryGetRegionFromIMDS";
const RegionDiscoveryGetCurrentVersion = "regionDiscoveryGetCurrentVersion";
/**
* Cache operations
*/
const CacheManagerGetRefreshToken = "cacheManagerGetRefreshToken";
const SetUserData = "setUserData";
export { AuthClientCreateTokenRequestBody, AuthClientExecuteTokenRequest, AuthorityGetCloudDiscoveryMetadataFromNetwork, AuthorityGetEndpointMetadataFromNetwork, AuthorityResolveEndpointsAsync, AuthorityUpdateCloudDiscoveryMetadata, AuthorityUpdateEndpointMetadata, AuthorityUpdateMetadataWithRegionalInformation, AuthorizationCodeClientExecutePostToTokenEndpoint, CacheManagerGetRefreshToken, GetAuthCodeUrl, HandleCodeResponseFromServer, HandleServerTokenResponse, NetworkClientSendPostRequestAsync, PopTokenGenerateCnf, RefreshTokenClientAcquireToken, RefreshTokenClientAcquireTokenWithCachedRefreshToken, RefreshTokenClientCreateTokenRequestBody, RefreshTokenClientExecutePostToTokenEndpoint, RefreshTokenClientExecuteTokenRequest, RegionDiscoveryDetectRegion, RegionDiscoveryGetCurrentVersion, RegionDiscoveryGetRegionFromIMDS, SetUserData, SilentFlowClientGenerateResultFromCacheRecord, UpdateTokenEndpointAuthority };
//# sourceMappingURL=PerformanceEvents.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"PerformanceEvents.mjs","sources":["../../../src/telemetry/performance/PerformanceEvents.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;AAGG;AAEH;;AAEG;AACI,MAAM,iCAAiC,GAC1C,oCAAoC;AACjC,MAAM,4CAA4C,GACrD,+CAA+C;AAC5C,MAAM,iDAAiD,GAC1D,oDAAoD;AAExD;;AAEG;AACI,MAAM,qCAAqC,GAC9C,wCAAwC;AAE5C;;AAEG;AACI,MAAM,8BAA8B,GAAG,iCAAiC;AAE/E;;AAEG;AACI,MAAM,oDAAoD,GAC7D,uDAAuD;AAE3D;;AAEG;AACI,MAAM,wCAAwC,GACjD,2CAA2C;AAExC,MAAM,6CAA6C,GACtD,gDAAgD;AAEpD;;AAEG;AACI,MAAM,cAAc,GAAG,iBAAiB;AAE/C;;AAEG;AACI,MAAM,4BAA4B,GAAG,+BAA+B;AAE3E;;AAEG;AACI,MAAM,6BAA6B,GAAG,gCAAgC;AACtE,MAAM,gCAAgC,GACzC,mCAAmC;AAChC,MAAM,4BAA4B,GAAG,+BAA+B;AAE3E;;AAEG;AACI,MAAM,mBAAmB,GAAG,sBAAsB;AAEzD;;AAEG;AACI,MAAM,yBAAyB,GAAG,4BAA4B;AAErE;;AAEG;AACI,MAAM,8BAA8B,GAAG,iCAAiC;AACxE,MAAM,6CAA6C,GACtD,gDAAgD;AAC7C,MAAM,qCAAqC,GAC9C,wCAAwC;AACrC,MAAM,uCAAuC,GAChD,0CAA0C;AACvC,MAAM,+BAA+B,GACxC,kCAAkC;AAC/B,MAAM,8CAA8C,GACvD,iDAAiD;AAErD;;AAEG;AACI,MAAM,2BAA2B,GAAG,8BAA8B;AAClE,MAAM,gCAAgC,GACzC,mCAAmC;AAChC,MAAM,gCAAgC,GACzC,mCAAmC;AAEvC;;AAEG;AACI,MAAM,2BAA2B,GAAG,8BAA8B;AAClE,MAAM,WAAW,GAAG;;;;"}

View File

@ -0,0 +1,59 @@
/*! @azure/msal-common v16.6.2 2026-05-19 */
'use strict';
import { PerformanceEventStatus } from './PerformanceEvent.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
class StubPerformanceClient {
generateId() {
return "callback-id";
}
startMeasurement(measureName, correlationId) {
return {
end: () => null,
discard: () => { },
add: () => { },
increment: () => { },
event: {
eventId: this.generateId(),
status: PerformanceEventStatus.InProgress,
authority: "",
libraryName: "",
libraryVersion: "",
clientId: "",
name: measureName,
startTimeMs: Date.now(),
correlationId: correlationId || "",
},
};
}
endMeasurement() {
return null;
}
discardMeasurements() {
return;
}
removePerformanceCallback() {
return true;
}
addPerformanceCallback() {
return "";
}
emitEvents() {
return;
}
addFields() {
return;
}
incrementFields() {
return;
}
cacheEventByCorrelationId() {
return;
}
}
export { StubPerformanceClient };
//# sourceMappingURL=StubPerformanceClient.mjs.map

View File

@ -0,0 +1 @@
{"version":3,"file":"StubPerformanceClient.mjs","sources":["../../../src/telemetry/performance/StubPerformanceClient.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAAA;;;AAGG;MAwBU,qBAAqB,CAAA;IAC9B,UAAU,GAAA;AACN,QAAA,OAAO,aAAa,CAAC;KACxB;IAED,gBAAgB,CACZ,WAAmB,EACnB,aAAkC,EAAA;QAElC,OAAO;AACH,YAAA,GAAG,EAAE,MAAM,IAAI;AACf,YAAA,OAAO,EAAE,MAAK,GAAG;AACjB,YAAA,GAAG,EAAE,MAAK,GAAG;AACb,YAAA,SAAS,EAAE,MAAK,GAAG;AACnB,YAAA,KAAK,EAAE;AACH,gBAAA,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE;gBAC1B,MAAM,EAAE,sBAAsB,CAAC,UAAU;AACzC,gBAAA,SAAS,EAAE,EAAE;AACb,gBAAA,WAAW,EAAE,EAAE;AACf,gBAAA,cAAc,EAAE,EAAE;AAClB,gBAAA,QAAQ,EAAE,EAAE;AACZ,gBAAA,IAAI,EAAE,WAAW;AACjB,gBAAA,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;gBACvB,aAAa,EAAE,aAAa,IAAI,EAAE;AACrC,aAAA;SACJ,CAAC;KACL;IAED,cAAc,GAAA;AACV,QAAA,OAAO,IAAI,CAAC;KACf;IAED,mBAAmB,GAAA;QACf,OAAO;KACV;IAED,yBAAyB,GAAA;AACrB,QAAA,OAAO,IAAI,CAAC;KACf;IAED,sBAAsB,GAAA;AAClB,QAAA,OAAO,EAAE,CAAC;KACb;IAED,UAAU,GAAA;QACN,OAAO;KACV;IAED,SAAS,GAAA;QACL,OAAO;KACV;IAED,eAAe,GAAA;QACX,OAAO;KACV;IAED,yBAAyB,GAAA;QACrB,OAAO;KACV;AACJ;;;;"}

View File

@ -0,0 +1,266 @@
/*! @azure/msal-common v16.6.2 2026-05-19 */
'use strict';
import { CacheOutcome, SERVER_TELEM_CACHE_KEY, CACHE_KEY_SEPARATOR, SERVER_TELEM_SCHEMA_VERSION, SERVER_TELEM_VALUE_SEPARATOR, SERVER_TELEM_CATEGORY_SEPARATOR, SERVER_TELEM_OVERFLOW_TRUE, SERVER_TELEM_OVERFLOW_FALSE, SERVER_TELEM_MAX_CACHED_ERRORS, SERVER_TELEM_UNKNOWN_ERROR, SERVER_TELEM_MAX_LAST_HEADER_BYTES } from '../../utils/Constants.mjs';
import { AuthError } from '../../error/AuthError.mjs';
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
const skuGroupSeparator = ",";
const skuValueSeparator = "|";
function makeExtraSkuString(params) {
const { skus, libraryName, libraryVersion, extensionName, extensionVersion, } = params;
const skuMap = new Map([
[0, [libraryName, libraryVersion]],
[2, [extensionName, extensionVersion]],
]);
let skuArr = [];
if (skus?.length) {
skuArr = skus.split(skuGroupSeparator);
// Ignore invalid input sku param
if (skuArr.length < 4) {
return skus;
}
}
else {
skuArr = Array.from({ length: 4 }, () => skuValueSeparator);
}
skuMap.forEach((value, key) => {
if (value.length === 2 && value[0]?.length && value[1]?.length) {
setSku({
skuArr,
index: key,
skuName: value[0],
skuVersion: value[1],
});
}
});
return skuArr.join(skuGroupSeparator);
}
function setSku(params) {
const { skuArr, index, skuName, skuVersion } = params;
if (index >= skuArr.length) {
return;
}
skuArr[index] = [skuName, skuVersion].join(skuValueSeparator);
}
/** @internal */
class ServerTelemetryManager {
constructor(telemetryRequest, cacheManager) {
this.cacheOutcome = CacheOutcome.NOT_APPLICABLE;
this.cacheManager = cacheManager;
this.apiId = telemetryRequest.apiId;
this.correlationId = telemetryRequest.correlationId;
this.wrapperSKU = telemetryRequest.wrapperSKU || "";
this.wrapperVer = telemetryRequest.wrapperVer || "";
this.telemetryCacheKey =
SERVER_TELEM_CACHE_KEY +
CACHE_KEY_SEPARATOR +
telemetryRequest.clientId;
}
/**
* API to add MSER Telemetry to request
*/
generateCurrentRequestHeaderValue() {
const request = `${this.apiId}${SERVER_TELEM_VALUE_SEPARATOR}${this.cacheOutcome}`;
const platformFieldsArr = [this.wrapperSKU, this.wrapperVer];
const nativeBrokerErrorCode = this.getNativeBrokerErrorCode();
if (nativeBrokerErrorCode?.length) {
platformFieldsArr.push(`broker_error=${nativeBrokerErrorCode}`);
}
const platformFields = platformFieldsArr.join(SERVER_TELEM_VALUE_SEPARATOR);
const regionDiscoveryFields = this.getRegionDiscoveryFields();
const requestWithRegionDiscoveryFields = [
request,
regionDiscoveryFields,
].join(SERVER_TELEM_VALUE_SEPARATOR);
return [
SERVER_TELEM_SCHEMA_VERSION,
requestWithRegionDiscoveryFields,
platformFields,
].join(SERVER_TELEM_CATEGORY_SEPARATOR);
}
/**
* API to add MSER Telemetry for the last failed request
*/
generateLastRequestHeaderValue() {
const lastRequests = this.getLastRequests();
const maxErrors = ServerTelemetryManager.maxErrorsToSend(lastRequests);
const failedRequests = lastRequests.failedRequests
.slice(0, 2 * maxErrors)
.join(SERVER_TELEM_VALUE_SEPARATOR);
const errors = lastRequests.errors
.slice(0, maxErrors)
.join(SERVER_TELEM_VALUE_SEPARATOR);
const errorCount = lastRequests.errors.length;
// Indicate whether this header contains all data or partial data
const overflow = maxErrors < errorCount
? SERVER_TELEM_OVERFLOW_TRUE
: SERVER_TELEM_OVERFLOW_FALSE;
const platformFields = [errorCount, overflow].join(SERVER_TELEM_VALUE_SEPARATOR);
return [
SERVER_TELEM_SCHEMA_VERSION,
lastRequests.cacheHits,
failedRequests,
errors,
platformFields,
].join(SERVER_TELEM_CATEGORY_SEPARATOR);
}
/**
* API to cache token failures for MSER data capture
* @param error
*/
cacheFailedRequest(error) {
const lastRequests = this.getLastRequests();
if (lastRequests.errors.length >=
SERVER_TELEM_MAX_CACHED_ERRORS) {
// Remove a cached error to make room, first in first out
lastRequests.failedRequests.shift(); // apiId
lastRequests.failedRequests.shift(); // correlationId
lastRequests.errors.shift();
}
lastRequests.failedRequests.push(this.apiId, this.correlationId);
if (error instanceof Error && !!error && error.toString()) {
if (error instanceof AuthError) {
if (error.subError) {
lastRequests.errors.push(error.subError);
}
else if (error.errorCode) {
lastRequests.errors.push(error.errorCode);
}
else {
lastRequests.errors.push(error.toString());
}
}
else {
lastRequests.errors.push(error.toString());
}
}
else {
lastRequests.errors.push(SERVER_TELEM_UNKNOWN_ERROR);
}
this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
return;
}
/**
* Update server telemetry cache entry by incrementing cache hit counter
*/
incrementCacheHits() {
const lastRequests = this.getLastRequests();
lastRequests.cacheHits += 1;
this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
return lastRequests.cacheHits;
}
/**
* Get the server telemetry entity from cache or initialize a new one
*/
getLastRequests() {
const initialValue = {
failedRequests: [],
errors: [],
cacheHits: 0,
};
const lastRequests = this.cacheManager.getServerTelemetry(this.telemetryCacheKey, this.correlationId);
return lastRequests || initialValue;
}
/**
* Remove server telemetry cache entry
*/
clearTelemetryCache() {
const lastRequests = this.getLastRequests();
const numErrorsFlushed = ServerTelemetryManager.maxErrorsToSend(lastRequests);
const errorCount = lastRequests.errors.length;
if (numErrorsFlushed === errorCount) {
// All errors were sent on last request, clear Telemetry cache
this.cacheManager.removeItem(this.telemetryCacheKey, this.correlationId);
}
else {
// Partial data was flushed to server, construct a new telemetry cache item with errors that were not flushed
const serverTelemEntity = {
failedRequests: lastRequests.failedRequests.slice(numErrorsFlushed * 2),
errors: lastRequests.errors.slice(numErrorsFlushed),
cacheHits: 0,
};
this.cacheManager.setServerTelemetry(this.telemetryCacheKey, serverTelemEntity, this.correlationId);
}
}
/**
* Returns the maximum number of errors that can be flushed to the server in the next network request
* @param serverTelemetryEntity
*/
static maxErrorsToSend(serverTelemetryEntity) {
let i;
let maxErrors = 0;
let dataSize = 0;
const errorCount = serverTelemetryEntity.errors.length;
for (i = 0; i < errorCount; i++) {
// failedRequests parameter contains pairs of apiId and correlationId, multiply index by 2 to preserve pairs
const apiId = serverTelemetryEntity.failedRequests[2 * i] || "";
const correlationId = serverTelemetryEntity.failedRequests[2 * i + 1] || "";
const errorCode = serverTelemetryEntity.errors[i] || "";
// Count number of characters that would be added to header, each character is 1 byte. Add 3 at the end to account for separators
dataSize +=
apiId.toString().length +
correlationId.toString().length +
errorCode.length +
3;
if (dataSize < SERVER_TELEM_MAX_LAST_HEADER_BYTES) {
// Adding this entry to the header would still keep header size below the limit
maxErrors += 1;
}
else {
break;
}
}
return maxErrors;
}
/**
* Get the region discovery fields
*
* @returns string
*/
getRegionDiscoveryFields() {
const regionDiscoveryFields = [];
regionDiscoveryFields.push(this.regionUsed || "");
regionDiscoveryFields.push(this.regionSource || "");
regionDiscoveryFields.push(this.regionOutcome || "");
return regionDiscoveryFields.join(",");
}
/**
* Update the region discovery metadata
*
* @param regionDiscoveryMetadata
* @returns void
*/
updateRegionDiscoveryMetadata(regionDiscoveryMetadata) {
this.regionUsed = regionDiscoveryMetadata.region_used;
this.regionSource = regionDiscoveryMetadata.region_source;
this.regionOutcome = regionDiscoveryMetadata.region_outcome;
}
/**
* Set cache outcome
*/
setCacheOutcome(cacheOutcome) {
this.cacheOutcome = cacheOutcome;
}
setNativeBrokerErrorCode(errorCode) {
const lastRequests = this.getLastRequests();
lastRequests.nativeBrokerErrorCode = errorCode;
this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
}
getNativeBrokerErrorCode() {
return this.getLastRequests().nativeBrokerErrorCode;
}
clearNativeBrokerErrorCode() {
const lastRequests = this.getLastRequests();
delete lastRequests.nativeBrokerErrorCode;
this.cacheManager.setServerTelemetry(this.telemetryCacheKey, lastRequests, this.correlationId);
}
static makeExtraSkuString(params) {
return makeExtraSkuString(params);
}
}
export { ServerTelemetryManager };
//# sourceMappingURL=ServerTelemetryManager.mjs.map

File diff suppressed because one or more lines are too long