Skip to content

Commit

Permalink
feat: Release/3.x.x 20240427 (#271)
Browse files Browse the repository at this point in the history
* feat: add _experimentalCustomFetch config to override fetch (#245)

* feat: allow to provide custom fetch method to AbstractRestfulClient

* fix: allow to provide both fetch and fetch options

* refactor: init custom fetch in resolveFetch

* rename `customFetch` to `_experimentalCustomFetch`

i want to avoid taking any new namespaces while i think about the best way to do this

* use `_experimentalCustomFetch` instead of `customFetch` for fetch override

* test: added custom fetch test

---------

Co-authored-by: Luke Oliff <[email protected]>

* chore: Bump es5-ext from 0.10.62 to 0.10.64 (#250)

Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](medikoo/es5-ext@v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat: add get auth token details method to manage client (#262)

* chore: edit example for is_final and endpointing together with utterance end (#264)

* fix: add missing expiration_date to CreateProjectKeyResponse (#265)

* fix: update user agent to include JS or node (#269)

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Bartosz Jarocki <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: DamienDeepgram <[email protected]>
Co-authored-by: Lachlan Donald <[email protected]>
  • Loading branch information
5 people committed Apr 27, 2024
1 parent d2ade7b commit 7a76f75
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 22 deletions.
52 changes: 42 additions & 10 deletions examples/node-live/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
const {
createClient,
LiveTranscriptionEvents,
LiveTranscriptionEvent,
} = require("../../dist/main/index");
const { createClient, LiveTranscriptionEvents } = require("../../dist/main/index");
const fetch = require("cross-fetch");

const live = async () => {
const url = "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service";

const deepgram = createClient(process.env.DEEPGRAM_API_KEY);

// We will collect the is_final=true messages here so we can use them when the person finishes speaking
let is_finals = [];

const connection = deepgram.listen.live({
model: "nova-2",
utterance_end_ms: 1500,
language: "en-US",
// Apply smart formatting to the output
smart_format: true,
// To get UtteranceEnd, the following must be set:
interim_results: true,
utterance_end_ms: 1000,
vad_events: true,
// Time in milliseconds of silence to wait for before finalizing speech
endpointing: 300,
});

connection.on(LiveTranscriptionEvents.Open, () => {
Expand All @@ -22,19 +28,45 @@ const live = async () => {
});

connection.on(LiveTranscriptionEvents.Metadata, (data) => {
console.log(data);
console.log(`Deepgram Metadata: ${data}`);
});

connection.on(LiveTranscriptionEvents.Transcript, (data) => {
console.log(data.channel);
const sentence = data.channel.alternatives[0].transcript;

// Ignore empty transcripts
if (sentence.length == 0) {
return;
}
if (data.is_final) {
// We need to collect these and concatenate them together when we get a speech_final=true
// See docs: https://developers.deepgram.com/docs/understand-endpointing-interim-results
is_finals.push(sentence);

// Speech final means we have detected sufficent silence to consider this end of speech
// Speech final is the lowest latency result as it triggers as soon an the endpointing value has triggered
if (data.speech_final) {
const utterance = is_finals.join(" ");
console.log(`Speech Final: ${utterance}`);
is_finals = [];
} else {
// These are useful if you need real time captioning and update what the Interim Results produced
console.log(`Is Final: ${sentence}`);
}
} else {
// These are useful if you need real time captioning of what is being spoken
console.log(`Interim Results: ${sentence}`);
}
});

connection.on(LiveTranscriptionEvents.UtteranceEnd, (data) => {
console.log(data);
const utterance = is_finals.join(" ");
console.log(`Deepgram UtteranceEnd: ${utterance}`);
is_finals = [];
});

connection.on(LiveTranscriptionEvents.SpeechStarted, (data) => {
console.log(data);
// console.log("Deepgram SpeechStarted");
});

connection.on(LiveTranscriptionEvents.Error, (err) => {
Expand Down
35 changes: 32 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { isBrowser } from "./helpers";
import { DeepgramClientOptions } from "./types/DeepgramClientOptions";
import { FetchOptions } from "./types/Fetch";
import { version } from "./version";

export const NODE_VERSION = process.versions.node;

export const DEFAULT_HEADERS = {
"Content-Type": `application/json`,
"X-Client-Info": `@deepgram/sdk; ${isBrowser() ? "browser" : "server"}; v${version}`,
"User-Agent": `@deepgram/sdk/${version}`,
"User-Agent": `@deepgram/sdk/${version} ${isBrowser() ? "javascript" : `node/${NODE_VERSION}`}`,
};

export const DEFAULT_URL = "https://api.deepgram.com";
Expand All @@ -18,7 +21,7 @@ export const DEFAULT_FETCH_OPTIONS: FetchOptions = {
headers: DEFAULT_HEADERS,
};

export const DEFAULT_OPTIONS = {
export const DEFAULT_OPTIONS: DeepgramClientOptions = {
global: DEFAULT_GLOBAL_OPTIONS,
fetch: DEFAULT_FETCH_OPTIONS,
};
10 changes: 6 additions & 4 deletions src/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import crossFetch from "cross-fetch";
import { resolveHeadersConstructor } from "./helpers";
import type { Fetch } from "./types/Fetch";

export const resolveFetch = (): Fetch => {
export const resolveFetch = (customFetch?: Fetch): Fetch => {
let _fetch: Fetch;
if (typeof fetch === "undefined") {
if (customFetch) {
_fetch = customFetch;
} else if (typeof fetch === "undefined") {
_fetch = crossFetch as unknown as Fetch;
} else {
_fetch = fetch;
}
return (...args) => _fetch(...args);
};

export const fetchWithAuth = (apiKey: string): Fetch => {
const fetch = resolveFetch();
export const fetchWithAuth = (apiKey: string, customFetch?: Fetch): Fetch => {
const fetch = resolveFetch(customFetch);
const HeadersConstructor = resolveHeadersConstructor();

return async (input, init) => {
Expand Down
1 change: 1 addition & 0 deletions src/lib/types/CreateProjectKeyResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface CreateProjectKeyResponse {
scopes: string[];
tags?: string[];
created: string;
expiration_date?: string;
}
3 changes: 2 additions & 1 deletion src/lib/types/DeepgramClientOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FetchOptions } from "./Fetch";
import { Fetch, FetchOptions } from "./Fetch";

export interface DeepgramClientOptions {
global?: {
Expand All @@ -13,6 +13,7 @@ export interface DeepgramClientOptions {
url?: string;
};
fetch?: FetchOptions;
_experimentalCustomFetch?: Fetch;
restProxy?: {
url: null | string;
};
Expand Down
3 changes: 3 additions & 0 deletions src/lib/types/GetTokenDetailsResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface GetTokenDetailsResponse {
[key: string]: unknown;
}
1 change: 1 addition & 0 deletions src/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type {
export type { GetProjectUsageRequestsSchema } from "./GetProjectUsageRequestsSchema";
export type { GetProjectUsageSummarySchema } from "./GetProjectUsageSummarySchema";
export type { GetProjectUsageSummaryResponse } from "./GetProjectUsageSummaryResponse";
export type { GetTokenDetailsResponse } from "./GetTokenDetailsResponse";
export type {
ListOnPremCredentialsResponse,
OnPremCredentialResponse,
Expand Down
2 changes: 1 addition & 1 deletion src/packages/AbstractRestfulClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export abstract class AbstractRestfulClient extends AbstractClient {
);
}

this.fetch = fetchWithAuth(this.key);
this.fetch = fetchWithAuth(this.key, options._experimentalCustomFetch);
}

protected _getErrorMessage(err: any): string {
Expand Down
23 changes: 23 additions & 0 deletions src/packages/ManageClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,32 @@ import type {
UpdateProjectMemberScopeSchema,
UpdateProjectSchema,
VoidResponse,
GetTokenDetailsResponse,
} from "../lib/types";

export class ManageClient extends AbstractRestfulClient {
/**
* @see https://developers.deepgram.com/docs/authenticating#test-request
*/
async getTokenDetails(
endpoint = "v1/auth/token"
): Promise<DeepgramResponse<GetTokenDetailsResponse>> {
try {
const url = new URL(this.baseUrl);
url.pathname = endpoint;

const result: GetTokenDetailsResponse = await this.get(this.fetch as Fetch, url);

return { result, error: null };
} catch (error) {
if (isDeepgramError(error)) {
return { result: null, error };
}

throw error;
}
}

/**
* @see https://developers.deepgram.com/reference/get-projects
*/
Expand Down
19 changes: 18 additions & 1 deletion test/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createClient } from "../src";
import { DEFAULT_URL } from "../src/lib/constants";
import { expect } from "chai";
import { expect, assert } from "chai";
import { faker } from "@faker-js/faker";
import { stripTrailingSlash } from "../src/lib/helpers";
import DeepgramClient from "../src/DeepgramClient";
Expand Down Expand Up @@ -82,4 +82,21 @@ describe("testing creation of a deepgram client object", () => {

expect(client).is.instanceOf(DeepgramClient);
});

it("should use custom fetch when provided", async () => {
const fetch = async () => {
return new Response(JSON.stringify({ customFetch: true }));
};

const client = createClient(faker.string.alphanumeric(40), {
global: { url: "https://api.mock.deepgram.com" },
_experimentalCustomFetch: fetch,
});

const { result, error } = await client.manage.getProjectBalances(faker.string.uuid());

assert.isNull(error);
assert.isNotNull(result);
assert.containsAllDeepKeys(result, ["customFetch"]);
});
});

0 comments on commit 7a76f75

Please sign in to comment.