@absolutejs/voice 0.0.22-beta.492 → 0.0.22-beta.493

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
@@ -86,6 +86,8 @@ export type { VoiceAgentUIInput, VoiceAgentUIState, } from "./agentState";
86
86
  export { createInMemoryDNCList, isPhoneOnDNC, isWithinCampaignWindow, normalizePhoneNumber, shouldRetryCampaignAttempt, summarizeVoiceCampaignDispositions, } from "./campaignControls";
87
87
  export type { VoiceCampaignDisposition, VoiceCampaignDispositionRetryPolicy, VoiceCampaignDispositionRetryRule, VoiceCampaignDispositionSummary, VoiceCampaignWindowCheckInput, VoiceDNCList, } from "./campaignControls";
88
88
  export { createVoiceBackchannelDriver } from "./backchannel";
89
+ export { createVoiceOAuth2TokenSource } from "./oauth2TokenSource";
90
+ export type { CreateVoiceOAuth2TokenSourceOptions, VoiceOAuth2TokenResponse, VoiceOAuth2TokenSource, } from "./oauth2TokenSource";
89
91
  export type { VoiceBackchannelCue, VoiceBackchannelDriver, VoiceBackchannelDriverOptions, } from "./backchannel";
90
92
  export { createVoiceIVRSession, describeVoiceIVRPlan, evaluateVoiceIVRPlan, } from "./ivrPlan";
91
93
  export type { VoiceIVRBranch, VoiceIVRDecision, VoiceIVRInput, VoiceIVRMatch, VoiceIVRPlan, VoiceIVRSession, } from "./ivrPlan";
package/dist/index.js CHANGED
@@ -35663,6 +35663,66 @@ var createVoiceBackchannelDriver = (options) => {
35663
35663
  }
35664
35664
  };
35665
35665
  };
35666
+ // src/oauth2TokenSource.ts
35667
+ var createVoiceOAuth2TokenSource = (options) => {
35668
+ const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
35669
+ const refreshSkewMs = (options.refreshSkewSeconds ?? 60) * 1000;
35670
+ let cached;
35671
+ let pending;
35672
+ const fetchToken = async () => {
35673
+ const body = new URLSearchParams;
35674
+ body.set("grant_type", options.grantType ?? "client_credentials");
35675
+ body.set("client_id", options.clientId);
35676
+ body.set("client_secret", options.clientSecret);
35677
+ if (options.scope) {
35678
+ body.set("scope", options.scope);
35679
+ }
35680
+ if (options.audience) {
35681
+ body.set("audience", options.audience);
35682
+ }
35683
+ const response = await fetchImpl(options.tokenUrl, {
35684
+ body: body.toString(),
35685
+ headers: {
35686
+ accept: "application/json",
35687
+ "content-type": "application/x-www-form-urlencoded"
35688
+ },
35689
+ method: "POST"
35690
+ });
35691
+ if (!response.ok) {
35692
+ const text = await response.text().catch(() => "");
35693
+ throw new Error(`OAuth2 token request failed: ${response.status} ${response.statusText}${text ? ` \u2014 ${text.slice(0, 200)}` : ""}`);
35694
+ }
35695
+ const json = await response.json();
35696
+ if (!json.access_token) {
35697
+ throw new Error("OAuth2 token response missing access_token");
35698
+ }
35699
+ const ttlMs = typeof json.expires_in === "number" && json.expires_in > 0 ? json.expires_in * 1000 : 5 * 60 * 1000;
35700
+ cached = {
35701
+ expiresAt: Date.now() + ttlMs,
35702
+ value: json.access_token
35703
+ };
35704
+ return json.access_token;
35705
+ };
35706
+ return {
35707
+ invalidate: () => {
35708
+ cached = undefined;
35709
+ pending = undefined;
35710
+ },
35711
+ token: async () => {
35712
+ const now = Date.now();
35713
+ if (cached && cached.expiresAt - refreshSkewMs > now) {
35714
+ return cached.value;
35715
+ }
35716
+ if (pending) {
35717
+ return pending;
35718
+ }
35719
+ pending = fetchToken().finally(() => {
35720
+ pending = undefined;
35721
+ });
35722
+ return pending;
35723
+ }
35724
+ };
35725
+ };
35666
35726
  // src/ivrPlan.ts
35667
35727
  var speechMatchesPattern = (pattern, speech) => {
35668
35728
  const normalized = speech.toLowerCase().trim();
@@ -47075,6 +47135,7 @@ export {
47075
47135
  createVoiceObservabilityExportRoutes,
47076
47136
  createVoiceObservabilityExportReplayRoutes,
47077
47137
  createVoiceOTELHTTPExporter,
47138
+ createVoiceOAuth2TokenSource,
47078
47139
  createVoiceMonitorWebhookNotifier,
47079
47140
  createVoiceMonitorSession,
47080
47141
  createVoiceMonitorRuntimeBinding,
@@ -0,0 +1,21 @@
1
+ export type VoiceOAuth2TokenResponse = {
2
+ access_token: string;
3
+ expires_in?: number;
4
+ token_type?: string;
5
+ };
6
+ export type VoiceOAuth2TokenSource = {
7
+ invalidate: () => void;
8
+ token: () => Promise<string>;
9
+ };
10
+ export type CreateVoiceOAuth2TokenSourceOptions = {
11
+ audience?: string;
12
+ clientId: string;
13
+ clientSecret: string;
14
+ fetch?: typeof fetch;
15
+ grantType?: "client_credentials";
16
+ /** seconds remaining before expiry to refresh proactively, default 60 */
17
+ refreshSkewSeconds?: number;
18
+ scope?: string;
19
+ tokenUrl: string;
20
+ };
21
+ export declare const createVoiceOAuth2TokenSource: (options: CreateVoiceOAuth2TokenSourceOptions) => VoiceOAuth2TokenSource;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.492",
3
+ "version": "0.0.22-beta.493",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",