@speechmatics/batch-client
Version:
Javascript client for the Speechmatics batch jobs API
451 lines (425 loc) • 14.3 kB
JavaScript
import { z } from 'zod';
const ErrorResponseErrorEnum = {
BadRequest: "Bad Request",
FileExpired: "File Expired",
Forbidden: "Forbidden",
ResourceLocked: "Resource Locked",
FormatNotSupported: "Format Not Supported",
InternalServerError: "Internal Server Error",
JobError: "Job error",
JobExpired: "Job Expired",
JobInProgress: "Job In Progress",
JobIsNotOfTypeAlignment: "Job is not of type alignment",
JobIsNotOfTypeTranscription: "Job is not of type transcription",
JobNotFound: "Job not found",
JobRejected: "Job rejected",
JobRejectedDueToInvalidAudio: "Job rejected due to invalid audio",
JobRejectedDueToInvalidText: "Job rejected due to invalid text",
MalformedRequest: "Malformed request",
MissingCallback: "Missing callback",
MissingDataFile: "Missing data_file",
MissingTextFile: "Missing text_file",
NoLanguageSelected: "No language selected",
NotImplemented: "Not Implemented",
PermissionDenied: "Permission Denied",
RequestedProductNotAvailable: "Requested product not available",
TranscriptionNotReady: "Transcription not ready",
LogFileNotAvailable: "Log file not available",
RequestedEarlyAccessReleaseNotAvailable: "Requested Early Access Release not available",
UnprocessableEntity: "Unprocessable Entity"
};
var __defProp$1 = Object.defineProperty;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
const ErrorResponseSchema = z.object({
code: z.number(),
detail: z.optional(z.string()),
error: z.nativeEnum(ErrorResponseErrorEnum)
});
class SpeechmaticsResponseError extends Error {
constructor(errorResponse) {
var __super = (...args) => {
super(...args);
__publicField$1(this, "response");
__publicField$1(this, "error");
return this;
};
const parse = ErrorResponseSchema.safeParse(errorResponse);
if (parse.success) {
__super(parse.data.error);
this.response = parse.data;
this.error = parse.data.error;
this.name = "SpeechmaticsResponseError";
} else {
throw new SpeechmaticsUnexpectedResponse(void 0, errorResponse);
}
}
}
const InternalErrorEnum = {
ConfigurationError: "Configuration error",
NetworkError: "Network error",
UnsupportedEnvironment: "Unsupported environment",
UnexpectedMessage: "Unexpected message",
UnexpectedResponse: "Unexpected response",
InvalidTypeError: "Invalid type error"
};
class SpeechmaticsInternalError extends Error {
// e.g. a caught error or response
constructor(error, message, cause) {
super(message ?? error);
__publicField$1(this, "error");
__publicField$1(this, "cause");
this.name = "SpeechmaticsInternalError";
this.error = error;
this.cause = cause;
}
}
class SpeechmaticsConfigurationError extends SpeechmaticsInternalError {
constructor(message) {
super(InternalErrorEnum.ConfigurationError, message);
this.name = "SpeechmaticsConfigurationError";
}
}
class SpeechmaticsNetworkError extends SpeechmaticsInternalError {
constructor(message, cause) {
super(InternalErrorEnum.NetworkError, message, cause);
this.name = "SpeechmaticsNetworkError";
}
}
class SpeechmaticsUnsupportedEnvironment extends SpeechmaticsInternalError {
constructor(message) {
super(InternalErrorEnum.UnsupportedEnvironment, message);
this.name = "SpeechmaticsUnsupportedEnvironment";
}
}
class SpeechmaticsUnexpectedMessage extends SpeechmaticsInternalError {
constructor(message) {
super(InternalErrorEnum.UnexpectedMessage, message);
this.name = "SpeechmaticsUnexpectedMessage";
}
}
class SpeechmaticsUnexpectedResponse extends SpeechmaticsInternalError {
constructor(message, response) {
super(InternalErrorEnum.UnexpectedResponse, message, response);
this.name = "SpeechmaticsUnexpectedResponse";
}
}
class SpeechmaticsInvalidTypeError extends SpeechmaticsInternalError {
constructor(message, cause) {
super(InternalErrorEnum.InvalidTypeError, message, cause);
this.name = "SpeechmaticsInvalidTypeError";
}
}
async function request(apiKey, url, path, method = "POST", payload, params, contentType) {
const requestOptions = {
method,
headers: {
...contentType ? { "Content-Type": contentType } : {},
Authorization: `Bearer ${apiKey}`
},
body: payload
};
const parsedUrl = new URL(path, url);
let fullUrl = addSDKInfoToRequestUrl(parsedUrl.href);
if (params) {
fullUrl = addQueryParamsToUrl(fullUrl, params);
}
let response;
try {
response = await fetch(fullUrl, requestOptions);
} catch (err) {
throw new SpeechmaticsNetworkError(`Error fetching from ${path}`, err);
}
if (!response.ok) {
const responseJson = await response.json();
throw new SpeechmaticsResponseError(responseJson);
}
const isPlain = contentType === "text/plain";
let result;
if (isPlain) {
try {
result = await response.text();
} catch (err) {
throw new SpeechmaticsInvalidTypeError(
"Failed to parse response text",
err
);
}
} else {
try {
result = await response.json();
} catch (err) {
throw new SpeechmaticsInvalidTypeError(
"Failed to parse response JSON",
err
);
}
}
return result;
}
const SM_SDK_PARAM_NAME = "sm-sdk";
const SM_APP_PARAM_NAME = "sm-app";
function getSmSDKVersion() {
return `js-${"5.1.0"}`;
}
function addQueryParamsToUrl(url, queryParams) {
const parsedUrl = new URL(url);
const params = new URLSearchParams(parsedUrl.search);
for (const key of Object.keys(queryParams)) {
const value = queryParams[key];
if (value !== void 0) params.append(key, `${value}`);
}
parsedUrl.search = params.toString();
return parsedUrl.href;
}
function addSDKInfoToRequestUrl(url) {
return addQueryParamsToUrl(url, { [SM_SDK_PARAM_NAME]: getSmSDKVersion() });
}
function poll(cb, interval = 500, timeout = 60 * 1e3) {
return new Promise((resolve, reject) => {
let pollInterval = void 0;
const errTimeout = setTimeout(() => {
typeof pollInterval !== "undefined" && clearInterval(pollInterval);
reject(new Error(`Exceeded timeout of ${timeout} ms`));
}, timeout);
pollInterval = setInterval(() => {
cb().then((resolved) => {
if (resolved) {
clearTimeout(errTimeout);
clearInterval(pollInterval);
resolve();
}
}).catch((err) => {
clearTimeout(errTimeout);
clearInterval(pollInterval);
reject(err);
});
}, interval);
});
}
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
class BatchClient {
constructor({
apiKey,
apiUrl,
appId
}) {
__publicField(this, "apiKey");
__publicField(this, "apiUrl");
__publicField(this, "appId");
this.apiKey = apiKey;
this.apiUrl = apiUrl ?? "https://asr.api.speechmatics.com/v2";
this.appId = appId;
}
async get(endpoint, contentType, queryParams) {
return await request(
this.apiKey,
this.apiUrl,
endpoint,
"GET",
null,
{ ...queryParams, [SM_APP_PARAM_NAME]: this.appId },
contentType
);
}
async post(endpoint, body = null, contentType) {
return await request(
this.apiKey,
this.apiUrl,
endpoint,
"POST",
body,
{ [SM_APP_PARAM_NAME]: this.appId },
contentType
);
}
async delete(endpoint, params) {
return request(this.apiKey, this.apiUrl, endpoint, "DELETE", null, {
...params,
[SM_APP_PARAM_NAME]: this.appId
});
}
/**
* The main method for transcribing audio files. It takes a url or a buffer and returns a promise with a transcript.
*
*
* @param config TranscribeConfig
* @returns Promise<RetrieveTranscriptResponse>. A promise that resolves to a transcript.
*/
async transcribe(input, jobConfig, format, timeoutMS) {
const submitResponse = await this.createTranscriptionJob(input, jobConfig);
if (submitResponse === null || submitResponse === void 0) {
throw "Error: submitResponse is undefined";
}
await poll(
async () => {
const { job } = await this.getJob(submitResponse.id);
if (job.status === "rejected") {
throw job.errors;
}
return job.status === "done";
},
3e3,
// repeat every 3 seconds
timeoutMS ?? 15 * 60 * 1e3
// 15 minutes timeout default
);
return await this.getJobResult(submitResponse.id, format);
}
async createTranscriptionJob(input, jobConfig) {
const config = {
...jobConfig,
type: "transcription"
};
const formData = new FormData();
if ("url" in input) {
config.fetch_data = input;
} else if ("data" in input) {
formData.append("data_file", input.data, input.fileName);
} else {
formData.append("data_file", input);
}
formData.append("config", JSON.stringify(config));
return this.post("/v2/jobs", formData);
}
async listJobs(filters = {}) {
return this.get("/v2/jobs", "application/json", { ...filters });
}
async getJob(id) {
return this.get(`/v2/jobs/${id}`, "application/json");
}
async deleteJob(id, force = false) {
const params = force ? { force } : void 0;
return this.delete(`/v2/jobs/${id}`, params);
}
async getJobResult(jobId, format = "json-v2") {
const params = { format: format === "text" ? "txt" : format };
const contentType = format === "json-v2" ? "application/json" : "text/plain";
return this.get(`/v2/jobs/${jobId}/transcript`, contentType, params);
}
async getDataFile(jobId) {
return this.get(`/v2/jobs/${jobId}/data`, "application/json");
}
async getFeatureDiscovery() {
return this.get("/v1/discovery/features");
}
}
const AutoChaptersResultErrorTypeEnum = {
AutoChaptersFailed: "auto_chapters_failed",
UnsupportedLanguage: "unsupported_language"
};
const JobDetailsStatusEnum = {
Running: "running",
Done: "done",
Rejected: "rejected",
Deleted: "deleted",
Expired: "expired"
};
const JobMode = {
Batch: "batch"
};
const JobType = {
Alignment: "alignment",
Transcription: "transcription"
};
const LanguageIdentificationConfigLowConfidenceActionEnum = {
Allow: "allow",
Reject: "reject",
UseDefaultLanguage: "use_default_language"
};
const LanguageIdentificationResultErrorEnum = {
LowConfidence: "LOW_CONFIDENCE",
UnexpectedLanguage: "UNEXPECTED_LANGUAGE",
NoSpeech: "NO_SPEECH",
FileUnreadable: "FILE_UNREADABLE",
Other: "OTHER"
};
const LanguagePackInfoWritingDirectionEnum = {
LeftToRight: "left-to-right",
RightToLeft: "right-to-left"
};
const NotificationConfigContentsEnum = {
Jobinfo: "jobinfo",
Transcript: "transcript",
TranscriptJsonV2: "transcript.json-v2",
TranscriptTxt: "transcript.txt",
TranscriptSrt: "transcript.srt",
Alignment: "alignment",
AlignmentWordStartAndEnd: "alignment.word_start_and_end",
AlignmentOnePerLine: "alignment.one_per_line",
Data: "data",
Text: "text"
};
const NotificationConfigMethodEnum = {
Post: "post",
Put: "put"
};
const OperatingPoint = {
Standard: "standard",
Enhanced: "enhanced"
};
const RecognitionDisplayDirectionEnum = {
Ltr: "ltr",
Rtl: "rtl"
};
const RecognitionResultTypeEnum = {
Word: "word",
Punctuation: "punctuation",
Entity: "entity"
};
const RecognitionResultAttachesToEnum = {
Previous: "previous",
Next: "next",
Both: "both",
None: "none"
};
const SentimentAnalysisErrorTypeEnum = {
SentimentAnalysisFailed: "sentiment_analysis_failed",
UnsupportedLanguage: "unsupported_language"
};
const SpokenFormRecognitionResultTypeEnum = {
Word: "word",
Punctuation: "punctuation"
};
const SummarizationConfigContentTypeEnum = {
Auto: "auto",
Informative: "informative",
Conversational: "conversational"
};
const SummarizationConfigSummaryLengthEnum = {
Brief: "brief",
Detailed: "detailed"
};
const SummarizationConfigSummaryTypeEnum = {
Paragraphs: "paragraphs",
Bullets: "bullets"
};
const SummarizationErrorTypeEnum = {
SummarizationFailed: "summarization_failed",
UnsupportedLanguage: "unsupported_language"
};
const TopicDetectionErrorTypeEnum = {
TopicDetectionFailed: "topic_detection_failed",
UnsupportedListOfTopics: "unsupported_list_of_topics",
UnsupportedLanguage: "unsupported_language"
};
const TranscriptionConfigDiarizationEnum = {
None: "none",
Speaker: "speaker",
Channel: "channel"
};
const TranscriptionConfigMaxDelayModeEnum = {
Fixed: "fixed",
Flexible: "flexible"
};
const TranslationErrorTypeEnum = {
TranslationFailed: "translation_failed",
UnsupportedTranslationPair: "unsupported_translation_pair"
};
const WrittenFormRecognitionResultTypeEnum = {
Word: "word"
};
export { AutoChaptersResultErrorTypeEnum, BatchClient, ErrorResponseErrorEnum, InternalErrorEnum, JobDetailsStatusEnum, JobMode, JobType, LanguageIdentificationConfigLowConfidenceActionEnum, LanguageIdentificationResultErrorEnum, LanguagePackInfoWritingDirectionEnum, NotificationConfigContentsEnum, NotificationConfigMethodEnum, OperatingPoint, RecognitionDisplayDirectionEnum, RecognitionResultAttachesToEnum, RecognitionResultTypeEnum, SentimentAnalysisErrorTypeEnum, SpeechmaticsConfigurationError, SpeechmaticsInvalidTypeError, SpeechmaticsNetworkError, SpeechmaticsResponseError, SpeechmaticsUnexpectedMessage, SpeechmaticsUnexpectedResponse, SpeechmaticsUnsupportedEnvironment, SpokenFormRecognitionResultTypeEnum, SummarizationConfigContentTypeEnum, SummarizationConfigSummaryLengthEnum, SummarizationConfigSummaryTypeEnum, SummarizationErrorTypeEnum, TopicDetectionErrorTypeEnum, TranscriptionConfigDiarizationEnum, TranscriptionConfigMaxDelayModeEnum, TranslationErrorTypeEnum, WrittenFormRecognitionResultTypeEnum };
//# sourceMappingURL=index.mjs.map