Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f091454
feat!: replace axios with native fetch for cross-platform support
rhamzeh Mar 31, 2026
744a80e
chore: refactor to replace `any` with proper types
rhamzeh Mar 31, 2026
ae61409
chore(tests): add some tests for fetch-based HTTP client layer
rhamzeh Mar 31, 2026
1946a49
chore: update changelog & documentation
rhamzeh Mar 31, 2026
33d64f3
chore(deps): refresh package-lock.json after dropping axios
rhamzeh Mar 31, 2026
ef3a638
fix: fixes and refinements to the httpclient
rhamzeh Mar 31, 2026
79ee8af
fix: skip implicit timeout for responseType: "stream", default to "GE…
emilic Apr 6, 2026
76cb2af
fix: Remove dead Axios-era $response unwrapping from streamedListObje…
emilic Apr 6, 2026
e2e8878
fix: construct proper FgaApiAuthenticationError instead of mutating e…
emilic Apr 6, 2026
04ba14f
Merge branch 'main' into feat/drop-axios
rhamzeh May 7, 2026
8f515c6
chore: Revert "fix: construct proper FgaApiAuthenticationError instea…
rhamzeh May 7, 2026
61258b3
refactor: replace tiny-async-pool with native implementation
rhamzeh Apr 17, 2026
15938e6
refactor: move self-contained utils into utils/utils-lite
rhamzeh Apr 17, 2026
043257c
fix: use Math.random as a fallback for environments without crypto su…
rhamzeh Apr 17, 2026
6f6831d
chore: output CJS to dist/cjs/
rhamzeh Apr 17, 2026
09f6c2a
feat: add ESM build alongside CJS allowing for dual resolution
rhamzeh Apr 17, 2026
0f237f4
Merge branch 'main' into feat/drop-axios
emilic May 8, 2026
cb5f6cd
Merge branch 'feat/drop-axios' into feat/esm-modules
emilic May 8, 2026
30d25ec
chore: merge develop into feat/esm-modules, resolve conflicts
SoulPancake Jul 27, 2026
6eb83c3
chore(deps): fix audit failures via overrides
SoulPancake Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ yarn add @openfga/sdk

### Supported Runtimes

The SDK ships with both CommonJS and ES Module builds, and should work out of the box in Node.js, Deno, Cloudflare Workers, and modern bundlers.

```javascript
// CommonJS
const { OpenFgaClient } = require("@openfga/sdk");

// ES Modules
import { OpenFgaClient } from "@openfga/sdk";
```

For details on the supported Node.js versions and our support policy, see [SUPPORTED_RUNTIMES.md](./SUPPORTED_RUNTIMES.md).

## Getting Started
Expand All @@ -102,7 +112,7 @@ We strongly recommend you initialize the `OpenFgaClient` only once and then re-u
#### No Credentials

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand All @@ -114,7 +124,7 @@ const fgaClient = new OpenFgaClient({
#### API Token

```javascript
const { OpenFgaClient, CredentialsMethod } = require('@openfga/sdk'); // OR import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';
import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand All @@ -132,7 +142,7 @@ const fgaClient = new OpenFgaClient({
#### Client Credentials

```javascript
const { OpenFgaClient, CredentialsMethod } = require('@openfga/sdk'); // OR import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';
import { OpenFgaClient, CredentialsMethod } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand All @@ -157,7 +167,7 @@ const fgaClient = new OpenFgaClient({
You can set default headers that will be sent with every request during client initialization:

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
Expand Down Expand Up @@ -195,7 +205,7 @@ const result = await fgaClient.check({
The SDK uses the native `fetch` API by default. You can provide a custom `HttpClient` to control the underlying HTTP behavior.

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient(
{
Expand Down Expand Up @@ -954,7 +964,7 @@ This is useful when:
#### Example: Calling a Custom Endpoint with POST

```javascript
const { OpenFgaClient } = require('@openfga/sdk');
import { OpenFgaClient } from "@openfga/sdk";

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
Expand Down Expand Up @@ -1056,7 +1066,7 @@ To customize this behavior, create an object with `maxRetry` and `minWaitInMs` p
Apply your custom retry values by setting to `retryParams` on the configuration object passed to the `OpenFgaClient` call.

```javascript
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';
import { OpenFgaClient } from '@openfga/sdk';

const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required
Expand Down
14 changes: 7 additions & 7 deletions api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/


import { BaseAPI } from "./base";
import { BaseAPI } from "./base.js";
import {
DUMMY_BASE_URL,
setSearchParams,
Expand All @@ -28,12 +28,12 @@ import {
RequestBuilderParams,
RequestBuilderOptions,
RequestBuilder,
} from "./common";
} from "./common.js";

export type { HttpMethod, RequestBuilderParams, RequestBuilderOptions };
import { Configuration } from "./configuration";
import { Credentials } from "./credentials";
import { assertParamExists } from "./validation";
import { Configuration } from "./configuration.js";
import { Credentials } from "./credentials/index.js";
import { assertParamExists } from "./validation.js";

import {
AbortedMessageResponse,
Expand Down Expand Up @@ -122,8 +122,8 @@ import {
WriteRequest,
WriteRequestDeletes,
WriteRequestWrites,
} from "./apiModel";
import { TelemetryAttribute, TelemetryAttributes } from "./telemetry/attributes";
} from "./apiModel.js";
import { TelemetryAttribute, TelemetryAttributes } from "./telemetry/attributes.js";


/**
Expand Down
6 changes: 3 additions & 3 deletions base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Configuration, UserConfigurationParams } from "./configuration";
import { HttpClient } from "./common";
import { Credentials } from "./credentials";
import { Configuration, UserConfigurationParams } from "./configuration.js";
import { HttpClient } from "./common.js";
import { Credentials } from "./credentials/index.js";

const DEFAULT_CONNECTION_TIMEOUT_IN_MS = 10000;

Expand Down
24 changes: 12 additions & 12 deletions client.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import asyncPool = require("tiny-async-pool");
import { asyncPool } from "./utils/utils-lite/async-pool.js";

import { OpenFgaApi, HttpMethod, RequestBuilderParams, RequestBuilderOptions } from "./api";
import type { FgaResponse, HttpClient } from "./common";
import { OpenFgaApi, HttpMethod, RequestBuilderParams, RequestBuilderOptions } from "./api.js";
import type { FgaResponse, HttpClient } from "./common.js";
export type { HttpMethod, RequestBuilderParams, RequestBuilderOptions };
import {
Assertion,
Expand Down Expand Up @@ -40,19 +40,19 @@ import {
WriteRequest,
WriteRequestWritesOnDuplicate,
WriteRequestDeletesOnMissing,
} from "./apiModel";
import { BaseAPI } from "./base";
import { CallResult, PromiseResult } from "./common";
import { Configuration, RetryParams, UserConfigurationParams } from "./configuration";
import { FgaApiAuthenticationError, FgaRequiredParamError, FgaValidationError } from "./errors";
} from "./apiModel.js";
import { BaseAPI } from "./base.js";
import { CallResult, PromiseResult } from "./common.js";
import { Configuration, RetryParams, UserConfigurationParams } from "./configuration.js";
import { FgaApiAuthenticationError, FgaRequiredParamError, FgaValidationError } from "./errors.js";
import {
chunkArray,
generateRandomIdWithNonUniqueFallback,
setHeaderIfNotSet,
} from "./utils";
import { isWellFormedUlidString } from "./validation";
import SdkConstants from "./constants";
import { parseNDJSONStream } from "./streaming";
} from "./utils/index.js";
import { isWellFormedUlidString } from "./validation.js";
import SdkConstants from "./constants/index.js";
import { parseNDJSONStream } from "./streaming.js";

export type UserClientConfigurationParams = UserConfigurationParams & {
storeId?: string;
Expand Down
16 changes: 8 additions & 8 deletions common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Configuration, RetryParams } from "./configuration";
import SdkConstants from "./constants";
import type { Credentials } from "./credentials";
import { Configuration, RetryParams } from "./configuration.js";
import SdkConstants from "./constants/index.js";
import type { Credentials } from "./credentials/index.js";
import {
FgaApiError,
FgaApiInternalError,
Expand All @@ -11,11 +11,11 @@ import {
FgaError,
FgaValidationError,
HttpErrorContext,
} from "./errors";
import { setNotEnumerableProperty } from "./utils";
import { TelemetryAttribute, TelemetryAttributes } from "./telemetry/attributes";
import { TelemetryConfiguration } from "./telemetry/configuration";
import { TelemetryHistograms } from "./telemetry/histograms";
} from "./errors.js";
import { setNotEnumerableProperty } from "./utils/index.js";
import { TelemetryAttribute, TelemetryAttributes } from "./telemetry/attributes.js";
import { TelemetryConfiguration } from "./telemetry/configuration.js";
import { TelemetryHistograms } from "./telemetry/histograms.js";

/**
*
Expand Down
10 changes: 5 additions & 5 deletions configuration.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ApiTokenConfig, AuthCredentialsConfig, ClientCredentialsConfig, CredentialsMethod } from "./credentials/types";
import { FgaValidationError, } from "./errors";
import { assertParamExists, isWellFormedUriString } from "./validation";
import { TelemetryConfig, TelemetryConfiguration } from "./telemetry/configuration";
import SdkConstants from "./constants";
import { ApiTokenConfig, AuthCredentialsConfig, ClientCredentialsConfig, CredentialsMethod } from "./credentials/types.js";
import { FgaValidationError, } from "./errors.js";
import { assertParamExists, isWellFormedUriString } from "./validation.js";
import { TelemetryConfig, TelemetryConfiguration } from "./telemetry/configuration.js";
import SdkConstants from "./constants/index.js";

// default maximum number of retry
const DEFAULT_MAX_RETRY = SdkConstants.DefaultMaxRetry;
Expand Down
16 changes: 8 additions & 8 deletions credentials/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@

import * as jose from "jose";

import { assertParamExists, isWellFormedUriString } from "../validation";
import { FgaApiAuthenticationError, FgaApiError, FgaValidationError } from "../errors";
import { attemptHttpRequest, HttpClient } from "../common";
import { AuthCredentialsConfig, PrivateKeyJWTConfig, ClientCredentialsConfig, ClientSecretConfig, CredentialsMethod } from "./types";
import { TelemetryAttributes } from "../telemetry/attributes";
import { TelemetryCounters } from "../telemetry/counters";
import { TelemetryConfiguration } from "../telemetry/configuration";
import { assertParamExists, isWellFormedUriString } from "../validation.js";
import { FgaApiAuthenticationError, FgaApiError, FgaValidationError } from "../errors.js";
import { attemptHttpRequest, HttpClient } from "../common.js";
import { AuthCredentialsConfig, PrivateKeyJWTConfig, ClientCredentialsConfig, ClientSecretConfig, CredentialsMethod } from "./types.js";
import { TelemetryAttributes } from "../telemetry/attributes.js";
import { TelemetryCounters } from "../telemetry/counters.js";
import { TelemetryConfiguration } from "../telemetry/configuration.js";
import { randomUUID } from "crypto";
import SdkConstants from "../constants";
import SdkConstants from "../constants/index.js";
Comment on lines +21 to +24

interface ClientSecretRequest {
client_id: string;
Expand Down
4 changes: 2 additions & 2 deletions credentials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
*/


export * from "./credentials";
export * from "./types";
export * from "./credentials.js";
export * from "./types.js";
16 changes: 15 additions & 1 deletion errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,21 @@ import {
ErrorCode,
InternalErrorCode,
NotFoundErrorCode,
} from "./apiModel";
} from "./apiModel.js";

/**
* Context extracted from a failed HTTP request/response,
* used to construct SDK error classes without coupling to any HTTP library.
*/
export interface HttpErrorContext {
status?: number;
statusText?: string;
headers?: Record<string, string>;
data?: any;
requestUrl?: string;
requestMethod?: string;
requestData?: any;
}
Comment on lines +7 to +19

/**
* Context extracted from a failed HTTP request/response,
Expand Down
26 changes: 13 additions & 13 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
*/


export * from "./api";
export * from "./client";
export * from "./apiModel";
export { Configuration, UserConfigurationParams, GetDefaultRetryParams } from "./configuration";
export { Credentials, CredentialsMethod } from "./credentials";
export * from "./telemetry/attributes";
export * from "./telemetry/configuration";
export * from "./telemetry/counters";
export * from "./telemetry/histograms";
export * from "./telemetry/metrics";
export * from "./errors";
export { FgaResponse, HttpClient, CallResult, PromiseResult } from "./common";
export { parseNDJSONStream } from "./streaming";
export * from "./api.js";
export * from "./client.js";
export * from "./apiModel.js";
export { Configuration, UserConfigurationParams, GetDefaultRetryParams } from "./configuration.js";
export { Credentials, CredentialsMethod } from "./credentials/index.js";
export * from "./telemetry/attributes.js";
export * from "./telemetry/configuration.js";
export * from "./telemetry/counters.js";
export * from "./telemetry/histograms.js";
export * from "./telemetry/metrics.js";
export * from "./errors.js";
export { FgaResponse, HttpClient, CallResult, PromiseResult } from "./common.js";
export { parseNDJSONStream } from "./streaming.js";

Loading
Loading