Skip to content

Commit

Permalink
feat: rebuilding config and class interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeocodes committed Jul 2, 2024
1 parent 5c51c53 commit 501d6d0
Show file tree
Hide file tree
Showing 19 changed files with 356 additions and 134 deletions.
14 changes: 14 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @file Automatically generated by barrelsby.
*/

export * from "./src/index";
export * from "./test/client.test";
export * from "./test/constants.test";
export * from "./test/errors.test";
export * from "./test/helpers.test";
export * from "./test/legacy.test";
export * from "./test/live.test";
export * from "./test/manage.test";
export * from "./test/onprem.test";
export * from "./test/prerecorded.test";
48 changes: 37 additions & 11 deletions src/DeepgramClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,91 @@ import { ReadClient } from "./packages/ReadClient";
import { SpeakClient } from "./packages/SpeakClient";

/**
* Deepgram Client.
* The DeepgramClient class provides access to various Deepgram API clients, including ListenClient, ManageClient, OnPremClient, ReadClient, and SpeakClient.
*
* An isomorphic Javascript client for interacting with the Deepgram API.
* @see https://developers.deepgram.com/docs/js-sdk
* @see https://github.com/deepgram/deepgram-js-sdk
*/
export default class DeepgramClient extends AbstractClient {
get listen(): ListenClient {
return new ListenClient(this.key, this.options);
return new ListenClient(this.options);
}

get manage(): ManageClient {
return new ManageClient(this.key, this.options);
return new ManageClient(this.options);
}

get onprem(): OnPremClient {
return new OnPremClient(this.key, this.options);
return new OnPremClient(this.options);
}

get read(): ReadClient {
return new ReadClient(this.key, this.options);
return new ReadClient(this.options);
}

get speak(): SpeakClient {
return new SpeakClient(this.key, this.options);
return new SpeakClient(this.options);
}

/**
* Major version fallback errors are below
*
* @see https://developers.deepgram.com/docs/js-sdk-v2-to-v3-migration-guide
* @deprecated
* @see https://dpgr.am/js-v3
*/
get transcription(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get projects(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get keys(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get members(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get scopes(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get invitation(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get usage(): any {
throw new DeepgramVersionError();
}

/**
* @deprecated
* @see https://dpgr.am/js-v3
*/
get billing(): any {
throw new DeepgramVersionError();
}
Expand Down
40 changes: 34 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import DeepgramClient from "./DeepgramClient";
import { DeepgramVersionError } from "./lib/errors";
import type { DeepgramClientOptions } from "./lib/types";
import { DeepgramClientOptions, IKeyFactory } from "./lib/types/DeepgramClientOptions";

/**
* Major version fallback error
* This class is deprecated and should not be used. It throws a `DeepgramVersionError` when instantiated.
*
* @deprecated
* @see https://dpgr.am/js-v3
*/
class Deepgram {
constructor(protected apiKey: string, protected apiUrl?: string, protected requireSSL?: boolean) {
Expand All @@ -12,11 +15,36 @@ class Deepgram {
}

/**
* Creates a new Deepgram Client.
* Creates a new Deepgram client instance.
*
* @param {DeepgramClientArgs} args - Arguments to pass to the Deepgram client constructor.
* @returns A new Deepgram client instance.
*/
const createClient = (apiKey: string, options: DeepgramClientOptions = {}): DeepgramClient => {
return new DeepgramClient(apiKey, options);
};
// Constructor overloads
function createClient(): DeepgramClient;
function createClient(key?: string | IKeyFactory): DeepgramClient;
function createClient(options?: DeepgramClientOptions): DeepgramClient;
function createClient(key?: string | IKeyFactory, options?: DeepgramClientOptions): DeepgramClient;

// Constructor implementation
function createClient(
keyOrOptions?: string | IKeyFactory | DeepgramClientOptions,
options?: DeepgramClientOptions
): DeepgramClient {
let resolvedOptions: DeepgramClientOptions = {};

if (typeof keyOrOptions === "string" || typeof keyOrOptions === "function") {
if (typeof options === "object") {
resolvedOptions = options;
}

resolvedOptions.key = keyOrOptions;
} else if (typeof keyOrOptions === "object") {
resolvedOptions = keyOrOptions;
}

return new DeepgramClient(resolvedOptions);
}

export { createClient, DeepgramClient, Deepgram };

Expand Down
29 changes: 21 additions & 8 deletions src/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
UrlSource,
TextSource,
AnalyzeSource,
LiveSchema,
TranscriptionSchema,
} from "./types";
import { Readable } from "stream";
import merge from "deepmerge";
Expand Down Expand Up @@ -83,16 +85,27 @@ export class CallbackUrl extends URL {
public callbackUrl = true;
}

export const convertProtocolToWs = (url: string | URL) => {
export const convertProtocolToWs = (url: string) => {
const convert = (string: string) => string.toLowerCase().replace(/(http)(s)?/gi, "ws$2");

if (url instanceof URL) {
return new URL(convert(url.toString()));
}
return convert(url);
};

if (typeof url === "string") {
return new URL(convert(url));
}
export const buildRequestUrl = (
endpoint: string,
baseUrl: string | URL,
transcriptionOptions: LiveSchema | TranscriptionSchema
): URL => {
const url = new URL(endpoint, baseUrl);
appendSearchParams(url.searchParams, transcriptionOptions);

throw new Error("URL must be a string or `URL` object");
return url;
};

export function isLiveSchema(arg: any): arg is LiveSchema {
return arg && typeof arg.interim_results !== "undefined";
}

export function isDeepgramClientOptions(arg: any): arg is DeepgramClientOptions {
return arg && typeof arg.global !== "undefined";
}
24 changes: 20 additions & 4 deletions src/lib/types/DeepgramClientOptions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { FetchOptions } from "./Fetch";

export type IKeyFactory = () => string;
export type IFetch = typeof fetch;
export type IWebSocket = typeof WebSocket;

/**
* Defines the arguments for creating a Deepgram client.
*
* The `DeepgramClientArgs` type represents the possible arguments that can be passed when creating a Deepgram client. It can be either:
*
* 1. An array with two elements:
* - The first element is a string or an `IKeyFactory` object, representing the API key.
* - The second element is a `DeepgramClientOptions` object, representing the configuration options for the Deepgram client.
* 2. An array with a single `DeepgramClientOptions` object, representing the configuration options for the Deepgram client.
*/

/**
* Configures the options for a Deepgram client.
*
Expand All @@ -11,7 +23,8 @@ export type IWebSocket = typeof WebSocket;
* The `global` namespace is used to configure options that apply globally to the Deepgram client. The other namespaces are used to configure options specific to different Deepgram API endpoints.
*/
export interface DeepgramClientOptions {
global?: NamespaceOptions;
key?: string | IKeyFactory;
global?: NamespaceOptions & { url?: string; headers?: { [index: string]: any } };
listen?: NamespaceOptions;
manage?: NamespaceOptions;
onprem?: NamespaceOptions;
Expand All @@ -29,13 +42,16 @@ export interface DeepgramClientOptions {
}

interface TransportFetchOptions extends TransportOptions, FetchOptions {}
interface TransportWebSocketOptions extends TransportOptions {
_nodeOnlyHeaders?: { [index: string]: any };
}

type TransportUrl = URL | string;
type TransportUrl = string;

interface TransportOptions {
url?: TransportUrl;
proxy?: {
url?: null | TransportUrl;
url: TransportUrl;
};
}

Expand All @@ -45,7 +61,7 @@ interface ITransport<C, O> {
}
export interface NamespaceOptions {
fetch?: ITransport<IFetch, TransportFetchOptions>;
websocket?: ITransport<IWebSocket, TransportOptions>;
websocket?: ITransport<IWebSocket, TransportWebSocketOptions>;
}

export type DefaultNamespaceOptions = {
Expand Down
82 changes: 75 additions & 7 deletions src/packages/AbstractClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import EventEmitter from "events";
import { DEFAULT_OPTIONS } from "../lib/constants";
import { DeepgramError } from "../lib/errors";
import { applyDefaults } from "../lib/helpers";
import { DeepgramClientOptions } from "../lib/types";
import merge from "deepmerge";
import {
DefaultClientOptions,
DefaultNamespaceOptions,
Expand All @@ -18,22 +20,74 @@ import {
*
* Subclasses of `AbstractClient` should implement the specific functionality for interacting with the Deepgram API.
*/
export abstract class AbstractClient {
public namespace: string = "global";
export abstract class AbstractClient extends EventEmitter {
protected factory: Function | undefined = undefined;
protected key: string;
protected namespaceOptions: DefaultNamespaceOptions;
protected options: DefaultClientOptions;
public namespace: string = "global";
public version: number = 1;

constructor(protected key: string, options: DeepgramClientOptions) {
this.key = key;
/**
* Constructs a new instance of the DeepgramClient class with the provided options.
*
* @param options - The options to configure the DeepgramClient instance.
* @param options.key - The Deepgram API key to use for authentication. If not provided, the `DEEPGRAM_API_KEY` environment variable will be used.
* @param options.global - Global options that apply to all requests made by the DeepgramClient instance.
* @param options.global.fetch - Options to configure the fetch requests made by the DeepgramClient instance.
* @param options.global.fetch.options - Additional options to pass to the fetch function, such as `url` and `headers`.
* @param options.namespace - Options specific to a particular namespace within the DeepgramClient instance.
*/
constructor(options: DeepgramClientOptions) {
super();

let key;

if (typeof options.key === "function") {
this.factory = options.key;
key = this.factory();
} else {
key = options.key;
}

if (!key) {
this.key = process.env.DEEPGRAM_API_KEY as string;
key = process.env.DEEPGRAM_API_KEY as string;
}

if (!this.key) {
throw new DeepgramError("A deepgram API key is required");
if (!key) {
throw new DeepgramError("A deepgram API key is required.");
}

this.key = key;

const convertLegacyOptions = (optionsArg: DeepgramClientOptions): DeepgramClientOptions => {
const newOptions: DeepgramClientOptions = {};

if (optionsArg.global?.url) {
newOptions.global = {
fetch: {
options: {
url: optionsArg.global.url,
},
},
};
}

if (optionsArg.global?.headers) {
newOptions.global = {
fetch: {
options: {
headers: optionsArg.global?.headers,
},
},
};
}

return merge(optionsArg, newOptions);
};

options = convertLegacyOptions(options);

/**
* Apply default options.
*/
Expand All @@ -50,4 +104,18 @@ export abstract class AbstractClient {
this.options.global!
);
}

public v(version: number = 1) {
this.version = version;

return this;
}

/**
* Determines whether the current instance should proxy requests.
* @returns {boolean} true if the current instance should proxy requests; otherwise, false
*/
get proxy(): boolean {
return this.key === "proxy" && !!this.namespaceOptions.fetch.options.proxy?.url;
}
}
Loading

0 comments on commit 501d6d0

Please sign in to comment.