Skip to content

Commit

Permalink
Merge pull request #51 from AssemblyAI/E07417BDFEA3614F5967B1520F8B2F61
Browse files Browse the repository at this point in the history
Sync from internal repo (YYYY/MM/DD)
  • Loading branch information
Swimburger committed May 15, 2024
2 parents 7981778 + e53b665 commit 78d1382
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 19 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# Changelog

## [4.4.2]
## [4.4.3] - 2024-05-09

- Add react-native exports that resolve to the browser version of the library.

## [4.4.2] - 2024-05-03

### Changed

- Caching is disabled for all HTTP request made by the SDK
- Accept data-URIs in `client.files.upload(dataUri)`, `client.transcripts.submit(audio: dataUri)`, `client.transcripts.transcribe(audio: dataUri)`.
- Change how the WebSocket libraries are imported for better compatibility across frameworks and runtimes.
The library no longer relies on a internal `#ws` import, and instead compiles the imports into the dist bundles.
Browser builds will use the native `WebSocket`, other builds will use the `ws` package.
Expand Down
96 changes: 96 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Contribute

We welcome contributions from the community.

## Create issues

Before you create an issue, check the [existing issues](https://github.com/AssemblyAI/assemblyai-node-sdk/issues) to see if someone's already created a similar one.

- If you find an existing issue, add any relevant information and upvote the issue using a thumb-up emoji (👍).
- If you don't find an issue, [create an issue](https://github.com/AssemblyAI/assemblyai-node-sdk/issues/new) so we can help you, and discuss solutions and next steps.

## Submit a PR

Before submitting a PR, to avoid wasting your valuable time, make sure you are aligned with the maintainers of the repository by discussing the desired changes in a GitHub issue.

To make changes, follow these steps:

1. Fork the repository and clone your own fork.
2. [Set up pnpm](https://pnpm.io/installation).
3. Run `pnpm install`.
4. Make your changes.

- Make the changes themselves.
- Add tests that verify your changes.
- Describe your changes in [CHANGELOG.md](./CHANGELOG.md).

1. Before committing your changes, run the following scripts:
- `pnpm format`
- `pnpm lint`
- `pnpm test` (see [run integration tests](#run-integration-tests))
- `pnpm build`
2. If linting and testing passes, commit your changes.
3. Submit your PR.

## Run integration tests

The integration tests require an upgraded AssemblyAI account.
The integration tests will use the AssemblyAI API and you'll be charged for your usage.
Reach out to us if you want some credits for running integration tests.

The integration tests require the following environment variables:

- `ASSEMBLYAI_API_KEY`: Your AssemblyAI API key
- `TEST_TRANSCRIPT_ID`: The transcript ID of a completed transcript your created
- `TEST_TRANSCRIPT_IDS`: One or more completed transcript IDs, separated by a comma `,`

You can set these environment variables in your shell, or by creating a _.env_ file with the following format:

```plaintext
ASSEMBLYAI_API_KEY=...
TEST_TRANSCRIPT_ID=...
TEST_TRANSCRIPT_IDS=...
```

## Generate types from OpenAPI and AsyncAPI spec

1. Configure the location of the OpenAPI and AsyncAPI spec as environment variables:
- `OPENAPI_SPEC`: Path or URL to the AssemblyAI OpenAPI spec
- `ASYNCAPI_SPEC`: Path or URL to the AssemblyAI AsyncAPI spec

2. Generate the types using `pnpm generate:types`.


## Notes about the JavaScript SDK

### Rollup

We use Rollup to build the JavaScript SDK.
Our Rollup configuration generates the following versions:
- node.{cjs,mjs}: The Node runtime version using CommonJS and ESModule syntax.
- bun.mjs: The Bun runtime version.
- deno.mjs: The Deno runtime version.
- browser: The browser runtime version that uses the native WebSocket instead of `ws`.
- browser.mjs: Using ESModule syntax, to be used by users using a bundler.
- assemblyai.umd?(.min).js: Using UMD syntax which creates, to be used directly from a script tag.
This script adds the SDK to the global `assemblyai` variable.
- index.cjs: The default version using CommonJS syntax.
- index.mjs: The default version using ESModule syntax.
- index.d.ts: The TypeScript types for the SDK.

### Package.json exports

When a user uses the SDK, the users' runtime will automatically choose the runtime-specific version
if defined in the package.json `exports` object, or fall back to the default version.

For example, Bun will use *bun.mjs* and Cloudflare Workers (workerd) will use *index.mjs*.

### Package.json imports

To make the SDK compatible with a variety of runtimes, we have to polyfill certain features.
We're doing this using package.json `imports`, which lets you define runtime-specific imports.
When these imports are TypeScript files, Rollup automatically includes the code in the output for the specified runtime.

When they are ordinary JavaScript files, Rollup leaves the private import in the output as is.
This works fine in most runtimes, but some runtimes like React Native/Expo do not support this.
Therefore, we should restrict ourselves to using only TypeScript code with package.json imports.
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,30 @@ const client = new AssemblyAI({

You can now use the `client` object to interact with the AssemblyAI API.

### Using a CDN

You can use automatic CDNs like [UNPKG](https://unpkg.com/) to load the library from a script tag.

- Replace `:version` with the desired version or `latest`.
- Remove `.min` to load the non-minified version.

```html
<script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.umd.min.js"></script>
```

The script creates a global `assemblyai` variable containing all the services.
Here's how you create a `RealtimeTranscriber` object.

```js
const { RealtimeTranscriber } = assemblyai;
const transcriber = new RealtimeTranscriber({
token: "[GENERATE TEMPORARY AUTH TOKEN IN YOUR API]",
...
});
```

For type support in your IDE, see [Reference types from JavaScript](./docs/reference-types-from-js.md).

## Speech-To-Text

### Transcribe audio and video files
Expand Down Expand Up @@ -229,24 +253,25 @@ const rt = client.realtime.transcriber({

> [!WARNING]
> Storing your API key in client-facing applications exposes your API key.
> Generate a temporary auth token on the server and pass it to your client.
> _Server code_:
> Generate a temporary auth token on the server and pass it to your client.
> _Server code_:
>
> ```typescript
> const token = await client.realtime.createTemporaryToken({ expires_in = 60 });
> // TODO: return token to client
> ```
>
> _Client code_:
>
> ```typescript
> import { RealtimeTranscriber } from "assemblyai";
> // TODO: implement getToken to retrieve token from server
> const token = await getToken();
> const rt = new RealtimeTranscriber({
> token
> token,
> });
> ```

You can configure the following events.

<!-- prettier-ignore -->
Expand Down Expand Up @@ -351,3 +376,7 @@ const response = await client.lemur.purgeRequestData(lemurResponse.request_id);
```

</details>

## Contributing

If you want to contribute to the JavaScript SDK, follow the guidelines in [CONTRIBUTING.md](./CONTRIBUTING.md).
27 changes: 27 additions & 0 deletions docs/reference-types-from-js.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Reference types from JavaScript

Types are automatically configured in most IDEs when you import the `assemblyai` module using `require` or `import`.
However, if you're using the _assemblyai.umd.js_ or _assemblyai.umd.min.js_ script,
you need to manually reference the types.

1. Install the `assemblyai` module locally.
2. Create an _assemblyai.d.ts_ file with the following content.
```typescript
import AssemblyAIModule from "assemblyai";
declare global {
const assemblyai: typeof AssemblyAIModule;
}
```
This will import the TypeScript types from the `assemblyai` module,
and configure them as the global `assemblyai` variable.
3. Reference the _assemblyai.d.ts_ file at the top of your script file.

```js
/// <reference path="assemblyai.d.ts" />
const { RealtimeTranscriber } = assemblyai;
...
```

Your IDE will load the types specified in the `<reference />` tag.

> [!INFO] > `/// <reference />` tags only work in script files, not script-blocks, and should be at the top of the file.
25 changes: 14 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "assemblyai",
"version": "4.4.2",
"version": "4.4.3",
"description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
"engines": {
"node": ">=18"
Expand All @@ -18,6 +18,7 @@
},
"workerd": "./dist/index.mjs",
"browser": "./dist/browser.mjs",
"react-native": "./dist/browser.mjs",
"node": {
"types": "./dist/index.d.ts",
"import": "./dist/node.mjs",
Expand Down Expand Up @@ -47,6 +48,8 @@
}
},
"type": "commonjs",
"react-native": "./dist/browser.mjs",
"browser": "./dist/browser.mjs",
"main": "./dist/index.cjs",
"require": "./dist/index.cjs",
"module": "./dist/index.mjs",
Expand All @@ -68,7 +71,7 @@
"test": "pnpm run test:unit && pnpm run test:integration",
"test:unit": "jest --config jest.unit.config.js --testTimeout 1000",
"test:integration": "jest --config jest.integration.config.js --testTimeout 360000",
"format": "prettier '**/*' --write",
"format": "prettier {*,**/*} --write --no-error-on-unmatched-pattern",
"generate:types": "tsx ./scripts/generate-types.ts && prettier 'src/types/*.generated.ts' --write",
"generate:reference": "typedoc",
"copybara:dry-run": "./copybara.sh dry_run --init-history",
Expand Down Expand Up @@ -97,16 +100,16 @@
"docs"
],
"devDependencies": {
"@babel/preset-env": "^7.24.0",
"@babel/preset-typescript": "^7.23.3",
"@babel/preset-env": "^7.24.5",
"@babel/preset-typescript": "^7.24.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@types/jest": "^29.5.12",
"@types/node": "^18.11.9",
"@types/node": "^18.19.32",
"@types/websocket": "^1.0.10",
"@types/ws": "^8.5.10",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"dotenv": "^16.4.5",
"eslint": "^8.57.0",
"eslint-plugin-tsdoc": "^0.2.17",
Expand All @@ -120,14 +123,14 @@
"prettier": "^3.2.5",
"publint": "^0.2.7",
"rimraf": "^5.0.5",
"rollup": "^4.13.0",
"rollup": "^4.17.2",
"ts-jest": "^29.1.2",
"tslib": "^2.5.3",
"typescript": "^5.4.2",
"typedoc": "^0.25.12",
"typedoc-plugin-extras": "^3.0.0"
"typedoc": "^0.25.13",
"typedoc-plugin-extras": "^3.0.0",
"typescript": "^5.4.5"
},
"dependencies": {
"ws": "^8.16.0"
"ws": "^8.17.0"
}
}
14 changes: 11 additions & 3 deletions scripts/generate-types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import openapiTS from "openapi-typescript";
import fs from "fs";
import "dotenv/config";

async function generateTypes(
apiSpecPath: string | undefined,
outputPath: string,
) {
if (!apiSpecPath) {
throw new Error("API spec path not provided.");
}

async function generateTypes(apiSpecPath: string, outputPath: string) {
const localPath = new URL(apiSpecPath, import.meta.url);
let output = await openapiTS(localPath, {
alphabetize: true,
Expand Down Expand Up @@ -90,5 +98,5 @@ type OneOf<T extends any[]> = T extends [infer Only] ? Only : T extends [infer A
fs.writeFileSync(outputPath, output);
}

generateTypes("../../spec/openapi.yml", "./src/types/openapi.generated.ts");
generateTypes("../../spec/asyncapi.yml", "./src/types/asyncapi.generated.ts");
generateTypes(process.env.OPENAPI_SPEC, "./src/types/openapi.generated.ts");
generateTypes(process.env.ASYNCAPI_SPEC, "./src/types/asyncapi.generated.ts");

0 comments on commit 78d1382

Please sign in to comment.