@absolutejs/voice 0.0.22-beta.267 → 0.0.22-beta.269

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/index.d.ts CHANGED
@@ -115,7 +115,7 @@ export type { VoiceLiveLatencyOptions, VoiceLiveLatencyReport, VoiceLiveLatencyR
115
115
  export type { VoiceLatencySLOBudget, VoiceLatencySLOGateError, VoiceLatencySLOGateOptions, VoiceLatencySLOGateReport, VoiceLatencySLOMeasurement, VoiceLatencySLOStage, VoiceLatencySLOStageSummary, VoiceLatencySLOStatus } from './latencySlo';
116
116
  export type { VoiceTurnQualityHTMLHandlerOptions, VoiceTurnQualityItem, VoiceTurnQualityOptions, VoiceTurnQualityReport, VoiceTurnQualityRoutesOptions, VoiceTurnQualityStatus } from './turnQuality';
117
117
  export type { VoiceOutcomeContractAssertionInput, VoiceOutcomeContractAssertionReport, VoiceOutcomeContractDefinition, VoiceOutcomeContractHTMLHandlerOptions, VoiceOutcomeContractIssue, VoiceOutcomeContractOptions, VoiceOutcomeContractReport, VoiceOutcomeContractRoutesOptions, VoiceOutcomeContractStatus, VoiceOutcomeContractSuiteReport } from './outcomeContract';
118
- export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookNormalizationEvidenceDecision, VoiceTelephonyWebhookNormalizationEvidenceInput, VoiceTelephonyWebhookNormalizationEvidenceReport, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
118
+ export type { VoiceTelephonyOutcomeAction, VoiceTelephonyOutcomeDecision, VoiceTelephonyOutcomePolicy, VoiceTelephonyOutcomeProviderEvent, VoiceTelephonyOutcomeRouteResult, VoiceTelephonyOutcomeStatusDecision, VoiceTelephonyWebhookDecision, VoiceTelephonyWebhookHandlerOptions, VoiceTelephonyWebhookIdempotencyStore, VoiceTelephonyWebhookNormalizationEvidenceDecision, VoiceTelephonyWebhookNormalizationEvidenceInput, VoiceTelephonyWebhookNormalizationEvidenceReport, VoiceTelephonyWebhookParseInput, VoiceTelephonyWebhookProvider, VoiceTelephonyWebhookRoutesOptions, VoiceTelephonyWebhookVerificationEvidenceAttempt, VoiceTelephonyWebhookVerificationResult, StoredVoiceTelephonyWebhookDecision } from './telephonyOutcome';
119
119
  export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneAssistantEvidenceInput, VoicePhoneAssistantEvidenceReport, VoicePhoneCallControlEvidenceInput, VoicePhoneCallControlEvidenceReport, VoicePhoneAgentLifecycleStage, VoicePhoneAgentPlivoCarrier, VoicePhoneAgentRoutes, VoicePhoneAgentRoutesOptions, VoicePhoneAgentSetupReport, VoicePhoneAgentTelnyxCarrier, VoicePhoneAgentTwilioCarrier } from './phoneAgent';
120
120
  export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
121
121
  export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
package/dist/index.js CHANGED
@@ -17396,6 +17396,7 @@ var isCallDisposition = (value) => value === "completed" || value === "escalated
17396
17396
  var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
17397
17397
  const issues = [];
17398
17398
  const decisions = input.decisions ?? [];
17399
+ const verificationAttempts = input.verificationAttempts ?? [];
17399
17400
  const actions = uniqueSorted3(decisions.map((decision) => decision.decision?.action ?? decision.action).filter(isTelephonyOutcomeAction));
17400
17401
  const dispositions = uniqueSorted3(decisions.map((decision) => decision.decision?.disposition ?? decision.disposition).filter(isCallDisposition));
17401
17402
  const providers = uniqueSorted3(decisions.map((decision) => decision.provider ?? decision.event?.provider).filter(isTelephonyWebhookProvider));
@@ -17408,6 +17409,11 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
17408
17409
  const duplicateOutcomeReasons = uniqueSorted3(duplicateDecisions.map((decision) => isRecord(decision.campaignOutcome) ? decision.campaignOutcome.reason : undefined).filter((reason) => typeof reason === "string"));
17409
17410
  const routeResults = decisions.filter((decision) => isRecord(decision.routeResult)).length;
17410
17411
  const missingSessionIds = decisions.filter((decision) => !decision.sessionId).length;
17412
+ const rejectedVerificationAttempts = verificationAttempts.filter((attempt) => attempt.rejected === true || attempt.status === 401 || attempt.verification?.ok === false && attempt.verification.reason === "invalid-signature");
17413
+ const rejectedVerificationProviders = uniqueSorted3(rejectedVerificationAttempts.map((attempt) => attempt.provider).filter(isTelephonyWebhookProvider));
17414
+ const replayRejectedVerificationAttempts = rejectedVerificationAttempts.filter((attempt) => attempt.replayRejected === true);
17415
+ const replayRejectedVerificationProviders = uniqueSorted3(replayRejectedVerificationAttempts.map((attempt) => attempt.provider).filter(isTelephonyWebhookProvider));
17416
+ const rejectedVerificationSideEffects = rejectedVerificationAttempts.reduce((total, attempt) => total + Math.max(0, attempt.sideEffects ?? 0), 0);
17411
17417
  if (input.minDecisions !== undefined && decisions.length < input.minDecisions) {
17412
17418
  issues.push(`Expected at least ${String(input.minDecisions)} telephony webhook decision(s), found ${String(decisions.length)}.`);
17413
17419
  }
@@ -17423,6 +17429,15 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
17423
17429
  if (input.maxDuplicateCampaignOutcomesApplied !== undefined && duplicateCampaignOutcomesApplied > input.maxDuplicateCampaignOutcomesApplied) {
17424
17430
  issues.push(`Expected at most ${String(input.maxDuplicateCampaignOutcomesApplied)} duplicate telephony webhook campaign outcome application(s), found ${String(duplicateCampaignOutcomesApplied)}.`);
17425
17431
  }
17432
+ if (input.minRejectedVerificationAttempts !== undefined && rejectedVerificationAttempts.length < input.minRejectedVerificationAttempts) {
17433
+ issues.push(`Expected at least ${String(input.minRejectedVerificationAttempts)} rejected telephony webhook verification attempt(s), found ${String(rejectedVerificationAttempts.length)}.`);
17434
+ }
17435
+ if (input.maxRejectedVerificationSideEffects !== undefined && rejectedVerificationSideEffects > input.maxRejectedVerificationSideEffects) {
17436
+ issues.push(`Expected at most ${String(input.maxRejectedVerificationSideEffects)} rejected telephony webhook side effect(s), found ${String(rejectedVerificationSideEffects)}.`);
17437
+ }
17438
+ if (input.minReplayRejectedVerificationAttempts !== undefined && replayRejectedVerificationAttempts.length < input.minReplayRejectedVerificationAttempts) {
17439
+ issues.push(`Expected at least ${String(input.minReplayRejectedVerificationAttempts)} replay-rejected telephony webhook verification attempt(s), found ${String(replayRejectedVerificationAttempts.length)}.`);
17440
+ }
17426
17441
  if (input.maxMissingSessionIds !== undefined && missingSessionIds > input.maxMissingSessionIds) {
17427
17442
  issues.push(`Expected at most ${String(input.maxMissingSessionIds)} telephony webhook decision(s) without sessionId, found ${String(missingSessionIds)}.`);
17428
17443
  }
@@ -17435,6 +17450,12 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
17435
17450
  for (const provider of findMissing3(duplicateProviders, input.requiredDuplicateProviders)) {
17436
17451
  issues.push(`Missing duplicate telephony webhook provider: ${provider}.`);
17437
17452
  }
17453
+ for (const provider of findMissing3(rejectedVerificationProviders, input.requiredRejectedVerificationProviders)) {
17454
+ issues.push(`Missing rejected telephony webhook verification provider: ${provider}.`);
17455
+ }
17456
+ for (const provider of findMissing3(replayRejectedVerificationProviders, input.requiredReplayRejectedVerificationProviders)) {
17457
+ issues.push(`Missing replay-rejected telephony webhook verification provider: ${provider}.`);
17458
+ }
17438
17459
  for (const action of findMissing3(actions, input.requiredActions)) {
17439
17460
  issues.push(`Missing telephony webhook action: ${action}.`);
17440
17461
  }
@@ -17455,8 +17476,14 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
17455
17476
  missingSessionIds,
17456
17477
  ok: issues.length === 0,
17457
17478
  providers,
17479
+ rejectedVerificationAttempts: rejectedVerificationAttempts.length,
17480
+ rejectedVerificationProviders,
17481
+ rejectedVerificationSideEffects,
17482
+ replayRejectedVerificationAttempts: replayRejectedVerificationAttempts.length,
17483
+ replayRejectedVerificationProviders,
17458
17484
  routeResults,
17459
- sources
17485
+ sources,
17486
+ verificationAttempts: verificationAttempts.length
17460
17487
  };
17461
17488
  };
17462
17489
  var assertVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
@@ -83,6 +83,15 @@ export type VoiceTelephonyWebhookNormalizationEvidenceDecision = {
83
83
  sessionId?: string;
84
84
  source?: VoiceTelephonyOutcomeDecision['source'] | string;
85
85
  };
86
+ export type VoiceTelephonyWebhookVerificationEvidenceAttempt = {
87
+ decisions?: number;
88
+ provider?: VoiceTelephonyWebhookProvider | string;
89
+ rejected?: boolean;
90
+ replayRejected?: boolean;
91
+ sideEffects?: number;
92
+ status?: number;
93
+ verification?: VoiceTelephonyWebhookVerificationResult;
94
+ };
86
95
  export type VoiceTelephonyWebhookNormalizationEvidenceInput = {
87
96
  decisions?: VoiceTelephonyWebhookNormalizationEvidenceDecision[];
88
97
  maxMissingSessionIds?: number;
@@ -91,11 +100,17 @@ export type VoiceTelephonyWebhookNormalizationEvidenceInput = {
91
100
  minDuplicateIdempotencyKeys?: number;
92
101
  minDuplicates?: number;
93
102
  maxDuplicateCampaignOutcomesApplied?: number;
103
+ maxRejectedVerificationSideEffects?: number;
104
+ minRejectedVerificationAttempts?: number;
105
+ minReplayRejectedVerificationAttempts?: number;
94
106
  requiredActions?: VoiceTelephonyOutcomeAction[];
95
107
  requiredDispositions?: VoiceCallDisposition[];
96
108
  requiredDuplicateProviders?: VoiceTelephonyWebhookProvider[];
97
109
  requiredProviders?: VoiceTelephonyWebhookProvider[];
110
+ requiredReplayRejectedVerificationProviders?: VoiceTelephonyWebhookProvider[];
111
+ requiredRejectedVerificationProviders?: VoiceTelephonyWebhookProvider[];
98
112
  requireRouteResults?: boolean;
113
+ verificationAttempts?: VoiceTelephonyWebhookVerificationEvidenceAttempt[];
99
114
  };
100
115
  export type VoiceTelephonyWebhookNormalizationEvidenceReport = {
101
116
  actions: VoiceTelephonyOutcomeAction[];
@@ -111,8 +126,14 @@ export type VoiceTelephonyWebhookNormalizationEvidenceReport = {
111
126
  missingSessionIds: number;
112
127
  ok: boolean;
113
128
  providers: VoiceTelephonyWebhookProvider[];
129
+ rejectedVerificationAttempts: number;
130
+ rejectedVerificationProviders: VoiceTelephonyWebhookProvider[];
131
+ rejectedVerificationSideEffects: number;
132
+ replayRejectedVerificationAttempts: number;
133
+ replayRejectedVerificationProviders: VoiceTelephonyWebhookProvider[];
114
134
  routeResults: number;
115
135
  sources: string[];
136
+ verificationAttempts: number;
116
137
  };
117
138
  export type VoiceTelephonyWebhookIdempotencyStore<TResult = unknown> = {
118
139
  get: (key: string) => Promise<StoredVoiceTelephonyWebhookDecision<TResult> | undefined> | StoredVoiceTelephonyWebhookDecision<TResult> | undefined;
@@ -8251,6 +8251,7 @@ var isCallDisposition = (value) => value === "completed" || value === "escalated
8251
8251
  var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
8252
8252
  const issues = [];
8253
8253
  const decisions = input.decisions ?? [];
8254
+ const verificationAttempts = input.verificationAttempts ?? [];
8254
8255
  const actions = uniqueSorted(decisions.map((decision) => decision.decision?.action ?? decision.action).filter(isTelephonyOutcomeAction));
8255
8256
  const dispositions = uniqueSorted(decisions.map((decision) => decision.decision?.disposition ?? decision.disposition).filter(isCallDisposition));
8256
8257
  const providers = uniqueSorted(decisions.map((decision) => decision.provider ?? decision.event?.provider).filter(isTelephonyWebhookProvider));
@@ -8263,6 +8264,11 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
8263
8264
  const duplicateOutcomeReasons = uniqueSorted(duplicateDecisions.map((decision) => isRecord(decision.campaignOutcome) ? decision.campaignOutcome.reason : undefined).filter((reason) => typeof reason === "string"));
8264
8265
  const routeResults = decisions.filter((decision) => isRecord(decision.routeResult)).length;
8265
8266
  const missingSessionIds = decisions.filter((decision) => !decision.sessionId).length;
8267
+ const rejectedVerificationAttempts = verificationAttempts.filter((attempt) => attempt.rejected === true || attempt.status === 401 || attempt.verification?.ok === false && attempt.verification.reason === "invalid-signature");
8268
+ const rejectedVerificationProviders = uniqueSorted(rejectedVerificationAttempts.map((attempt) => attempt.provider).filter(isTelephonyWebhookProvider));
8269
+ const replayRejectedVerificationAttempts = rejectedVerificationAttempts.filter((attempt) => attempt.replayRejected === true);
8270
+ const replayRejectedVerificationProviders = uniqueSorted(replayRejectedVerificationAttempts.map((attempt) => attempt.provider).filter(isTelephonyWebhookProvider));
8271
+ const rejectedVerificationSideEffects = rejectedVerificationAttempts.reduce((total, attempt) => total + Math.max(0, attempt.sideEffects ?? 0), 0);
8266
8272
  if (input.minDecisions !== undefined && decisions.length < input.minDecisions) {
8267
8273
  issues.push(`Expected at least ${String(input.minDecisions)} telephony webhook decision(s), found ${String(decisions.length)}.`);
8268
8274
  }
@@ -8278,6 +8284,15 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
8278
8284
  if (input.maxDuplicateCampaignOutcomesApplied !== undefined && duplicateCampaignOutcomesApplied > input.maxDuplicateCampaignOutcomesApplied) {
8279
8285
  issues.push(`Expected at most ${String(input.maxDuplicateCampaignOutcomesApplied)} duplicate telephony webhook campaign outcome application(s), found ${String(duplicateCampaignOutcomesApplied)}.`);
8280
8286
  }
8287
+ if (input.minRejectedVerificationAttempts !== undefined && rejectedVerificationAttempts.length < input.minRejectedVerificationAttempts) {
8288
+ issues.push(`Expected at least ${String(input.minRejectedVerificationAttempts)} rejected telephony webhook verification attempt(s), found ${String(rejectedVerificationAttempts.length)}.`);
8289
+ }
8290
+ if (input.maxRejectedVerificationSideEffects !== undefined && rejectedVerificationSideEffects > input.maxRejectedVerificationSideEffects) {
8291
+ issues.push(`Expected at most ${String(input.maxRejectedVerificationSideEffects)} rejected telephony webhook side effect(s), found ${String(rejectedVerificationSideEffects)}.`);
8292
+ }
8293
+ if (input.minReplayRejectedVerificationAttempts !== undefined && replayRejectedVerificationAttempts.length < input.minReplayRejectedVerificationAttempts) {
8294
+ issues.push(`Expected at least ${String(input.minReplayRejectedVerificationAttempts)} replay-rejected telephony webhook verification attempt(s), found ${String(replayRejectedVerificationAttempts.length)}.`);
8295
+ }
8281
8296
  if (input.maxMissingSessionIds !== undefined && missingSessionIds > input.maxMissingSessionIds) {
8282
8297
  issues.push(`Expected at most ${String(input.maxMissingSessionIds)} telephony webhook decision(s) without sessionId, found ${String(missingSessionIds)}.`);
8283
8298
  }
@@ -8290,6 +8305,12 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
8290
8305
  for (const provider of findMissing(duplicateProviders, input.requiredDuplicateProviders)) {
8291
8306
  issues.push(`Missing duplicate telephony webhook provider: ${provider}.`);
8292
8307
  }
8308
+ for (const provider of findMissing(rejectedVerificationProviders, input.requiredRejectedVerificationProviders)) {
8309
+ issues.push(`Missing rejected telephony webhook verification provider: ${provider}.`);
8310
+ }
8311
+ for (const provider of findMissing(replayRejectedVerificationProviders, input.requiredReplayRejectedVerificationProviders)) {
8312
+ issues.push(`Missing replay-rejected telephony webhook verification provider: ${provider}.`);
8313
+ }
8293
8314
  for (const action of findMissing(actions, input.requiredActions)) {
8294
8315
  issues.push(`Missing telephony webhook action: ${action}.`);
8295
8316
  }
@@ -8310,8 +8331,14 @@ var evaluateVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
8310
8331
  missingSessionIds,
8311
8332
  ok: issues.length === 0,
8312
8333
  providers,
8334
+ rejectedVerificationAttempts: rejectedVerificationAttempts.length,
8335
+ rejectedVerificationProviders,
8336
+ rejectedVerificationSideEffects,
8337
+ replayRejectedVerificationAttempts: replayRejectedVerificationAttempts.length,
8338
+ replayRejectedVerificationProviders,
8313
8339
  routeResults,
8314
- sources
8340
+ sources,
8341
+ verificationAttempts: verificationAttempts.length
8315
8342
  };
8316
8343
  };
8317
8344
  var assertVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.267",
3
+ "version": "0.0.22-beta.269",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",