- 
                Notifications
    You must be signed in to change notification settings 
- Fork 22
feat: add streamedListObjects for unlimited object retrieval #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| WalkthroughThis PR adds a new streaming variant of the ListObjects API to the JavaScript SDK. It includes a new  Changes
 Sequence Diagram(s)sequenceDiagram
    actor User
    participant Client as OpenFgaClient
    participant API as OpenFgaApi
    participant HTTP as axios
    participant Server as OpenFGA Server
    participant Parser as parseNDJSONStream
    User->>Client: streamedListObjects(request)
    Client->>API: streamedListObjects()
    API->>HTTP: GET /stores/{id}/streamed-list-objects<br/>(responseType: stream, telemetry)
    HTTP->>Server: Request with streaming
    Server-->>HTTP: NDJSON stream (line-delimited JSON)
    HTTP-->>API: Response stream
    API-->>Client: Response.data (stream)
    Client->>Parser: parseNDJSONStream(stream)
    
    loop For each line in stream
        Parser->>Parser: UTF-8 decode, buffer, split on \\n
        Parser->>Parser: Parse JSON object
        Parser-->>Client: yield StreamedListObjectsResponse
    end
    
    Client-->>User: AsyncGenerator<StreamedListObjectsResponse>
    User->>User: Iterate and process results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes 
 Possibly related issues
 Suggested reviewers
 Pre-merge checks and finishing touches❌ Failed checks (1 warning)
 ✅ Passed checks (4 passed)
 ✨ Finishing touches
 🧪 Generate unit tests (beta)
 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment  | 
| Codecov Report❌ Patch coverage is  
 Additional details and impacted files@@            Coverage Diff             @@
##             main     #280      +/-   ##
==========================================
- Coverage   89.13%   86.62%   -2.51%     
==========================================
  Files          24       25       +1     
  Lines        1288     1436     +148     
  Branches      211      241      +30     
==========================================
+ Hits         1148     1244      +96     
- Misses         84      134      +50     
- Partials       56       58       +2     ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
 | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (10)
apiModel.ts (1)
864-876: Clarify docstring: SDK-yielded type vs wire shape.The client parses NDJSON lines like
{ result: { object } }and yields{ object }. Consider adjusting the comment to “Element yielded by streamedListObjects” to avoid implying this is the on-the-wire shape. Otherwise the interface looks good.example/streamed-list-objects-local/README.md (1)
5-7: Align Node version and add browser note.
- Change “Node.js 18+” to match SDK minimum (e.g., “Node.js ≥16.15.0”, unless 18+ is explicitly required here).
- Add: “Not supported in browsers; uses Node Readable streams.”
Please confirm whether any example dependency requires Node 18+ specifically (e.g., APIs not in Node 16.15).
common.ts (1)
353-418: Harden streaming request: headers default, NDJSON Accept, cancellation, telemetry parity.
- Ensure
headersexists before auth header injection.- Set
Accept: application/x-ndjsonif not provided.- Allow
AbortSignalpassthrough (so callers can cancel).- Optionally record request-body attributes (parity with non-stream paths, if/when added there).
Apply this diff:
export const createStreamingRequestFunction = function (axiosArgs: RequestArgs, axiosInstance: AxiosInstance, configuration: Configuration, credentials: Credentials, methodAttributes: Record<string, string | number> = {}) { configuration.isValid(); @@ - return async (axios: AxiosInstance = axiosInstance): Promise<any> => { - await setBearerAuthToObject(axiosArgs.options.headers, credentials!); + return async (axios: AxiosInstance = axiosInstance): Promise<any> => { + // ensure headers object + axiosArgs.options.headers = axiosArgs.options.headers || {}; + await setBearerAuthToObject(axiosArgs.options.headers, credentials!); @@ - const axiosRequestArgs = { ...axiosArgs.options, responseType: "stream", url: url }; + // default NDJSON accept unless caller overrides + if (!axiosArgs.options.headers["Accept"]) { + axiosArgs.options.headers["Accept"] = "application/x-ndjson"; + } + const axiosRequestArgs = { ...axiosArgs.options, responseType: "stream", url }; @@ - attributes = TelemetryAttributes.fromResponse({ + attributes = TelemetryAttributes.fromResponse({ response, attributes, });Optional: If you add
signal?: AbortSignalto client options, pass it viaaxiosArgs.options.signal.Please confirm the server’s preferred Accept header for streamed list objects (e.g.,
application/x-ndjson). If different, we should set it accordingly.tests/helpers/nocks.ts (1)
249-264: Simulate chunked NDJSON to better exercise the parser.Current mock emits a single large chunk. Emit smaller chunks to surface boundary/chunking bugs in tests.
- return nock(basePath) - .post(`/stores/${storeId}/streamed-list-objects`) - .reply(200, () => Readable.from([ndjsonResponse]), { - "Content-Type": "application/x-ndjson" - }); + return nock(basePath) + .post(`/stores/${storeId}/streamed-list-objects`) + .reply(200, () => { + // send ~32-byte chunks to simulate real streaming + const chunks = Array.from(ndjsonResponse.matchAll(/.{1,32}/gs), m => m[0]); + return Readable.from(chunks); + }, { + "Content-Type": "application/x-ndjson" + });example/streamed-list-objects-local/streamedListObjectsLocal.mjs (1)
55-57: Ensure store cleanup in a finally block.If an earlier step throws, the store may be orphaned. Move deleteStore into finally and guard on storeId.
Example:
let storeId; try { // ... create store, set storeId, do work ... } finally { if (storeId) { await new OpenFgaClient(new ClientConfiguration({ apiUrl, storeId })).deleteStore().catch(() => {}); } }api.ts (2)
387-425: Be explicit about NDJSON in request headers.Setting Accept helps interoperability and test clarity.
- const localVarHeaderParameter = {} as any; + const localVarHeaderParameter = {} as any; + localVarHeaderParameter["Accept"] = "application/x-ndjson";
955-970: Align telemetry with other methods.Include store id and body-derived attributes for consistency.
- return createStreamingRequestFunction(localVarAxiosArgs, globalAxios, configuration, credentials, { - [TelemetryAttribute.FgaClientRequestMethod]: "StreamedListObjects" - }); + return createStreamingRequestFunction(localVarAxiosArgs, globalAxios, configuration, credentials, { + [TelemetryAttribute.FgaClientRequestMethod]: "StreamedListObjects", + [TelemetryAttribute.FgaClientRequestStoreId]: storeId ?? "", + ...TelemetryAttributes.fromRequestBody(body), + });example/streamed-list-objects/README.md (1)
16-22: Doc: mention building the SDK or using the published package.Examples import from ../../dist; advise building first or installing from npm.
Suggested snippet:
# From repo root pnpm install pnpm build cd example/streamed-list-objects node streamedListObjects.mjsexample/streamed-list-objects/streamedListObjects.mjs (2)
19-36: writeTuples drops remainder; handle non-multiples of 100.If quantity isn’t divisible by 100, the tail is lost.
- const chunks = Math.floor(quantity / 100); + const chunks = Math.floor(quantity / 100); + const remainder = quantity % 100; @@ for (let chunk = 0; chunk < chunks; ++chunk) { const tuples = []; for (let t = 0; t < 100; ++t) { tuples.push({ user: "user:anne", relation: "owner", object: `document:${chunk * 100 + t}` }); } await fgaClient.writeTuples(tuples); } + if (remainder) { + const tuples = []; + for (let t = 0; t < remainder; ++t) { + tuples.push({ + user: "user:anne", + relation: "owner", + object: `document:${chunks * 100 + t}` + }); + } + await fgaClient.writeTuples(tuples); + }
94-99: Ensure cleanup in finally.Move deleteStore into finally and guard on storeId to avoid orphaned stores on errors.
Example:
let storeId; try { storeId = await createStore(fgaClient); // ... } finally { if (storeId) await fgaClient.deleteStore().catch(() => {}); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
- CHANGELOG.md(1 hunks)
- api.ts(5 hunks)
- apiModel.ts(1 hunks)
- client.ts(3 hunks)
- common.ts(1 hunks)
- example/streamed-list-objects-local/README.md(1 hunks)
- example/streamed-list-objects-local/streamedListObjectsLocal.mjs(1 hunks)
- example/streamed-list-objects/README.md(1 hunks)
- example/streamed-list-objects/model.json(1 hunks)
- example/streamed-list-objects/streamedListObjects.mjs(1 hunks)
- index.ts(1 hunks)
- streaming.ts(1 hunks)
- tests/helpers/nocks.ts(2 hunks)
- tests/streaming.test.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
example/streamed-list-objects/streamedListObjects.mjs (2)
client.ts (4)
createStore(324-326)
writeTuples(568-572)
streamedListObjects(825-845)
listObjects(797-807)example/streamed-list-objects-local/streamedListObjectsLocal.mjs (2)
model(13-29)
storeId(9-9)
tests/helpers/nocks.ts (1)
tests/helpers/default-config.ts (1)
defaultConfiguration(56-56)
streaming.ts (1)
index.ts (1)
parseNDJSONStream(27-27)
client.ts (2)
apiModel.ts (1)
StreamedListObjectsResponse(869-876)streaming.ts (1)
parseNDJSONStream(96-168)
api.ts (3)
apiModel.ts (1)
ListObjectsRequest(804-847)common.ts (6)
RequestArgs(30-33)
DUMMY_BASE_URL(23-23)
setSearchParams(51-66)
serializeDataIfNeeded(88-96)
toPathString(102-104)
createStreamingRequestFunction(353-418)validation.ts (1)
assertParamExists(8-12)
example/streamed-list-objects-local/streamedListObjectsLocal.mjs (1)
client.ts (2)
OpenFgaClient(233-945)
ClientConfiguration(59-92)
tests/streaming.test.ts (1)
streaming.ts (1)
parseNDJSONStream(96-168)
common.ts (4)
base.ts (1)
RequestArgs(15-18)configuration.ts (1)
Configuration(58-202)telemetry/attributes.ts (1)
TelemetryAttributes(35-130)telemetry/histograms.ts (1)
TelemetryHistograms(20-32)
🔇 Additional comments (10)
client.ts (1)
24-25: Imports look correct.Also applies to: 52-53
common.ts (1)
345-347: No functional change here.tests/helpers/nocks.ts (1)
3-4: LGTM: Node stream import fits the streaming mock.api.ts (1)
1442-1454: OO wrapper wiring looks correct.index.ts (1)
27-27: LGTM: public export of parseNDJSONStream.example/streamed-list-objects/model.json (1)
1-251: LGTM: model is coherent and matches example relations.tests/streaming.test.ts (4)
14-19: LGTM! Well-organized test suite structure.The imports and test suite organization are clean and appropriate for testing the NDJSON streaming parser.
20-96: Excellent coverage of core parsing scenarios.These tests cover the fundamental NDJSON parsing cases effectively. The chunked data test (lines 48-65) is particularly valuable as it validates the buffering logic when JSON objects are split across stream chunks—a critical real-world scenario.
98-162: Comprehensive input type coverage.These tests validate the parser's flexibility with different input types (Buffer, string, async iterable). The test for JSON without a trailing newline (lines 109-117) is particularly important as it validates the final buffer flush logic. The
as anytype casts are acceptable here to test the parser's runtime behavior with various input types.
164-257: Thorough async generator protocol and cleanup testing.These tests rigorously validate the async iterator implementation, including error handling, early cancellation, buffering behavior, and proper cleanup of event listeners. The listener cleanup assertions (lines 193-195, 241-243) are particularly valuable for preventing memory leaks. While these tests exercise internal implementation details, the guarantees they provide about correctness and resource management justify their inclusion.
Updates JavaScript SDK templates to support the streaming API endpoint for unlimited object retrieval. Templates now handle streaming operations differently using vendor extension conditionals. Changes: - Add streaming.mustache template with NDJSON parser for Node.js - Update api.mustache to import createStreamingRequestFunction - Update apiInner.mustache with x-fga-streaming vendor extension logic - Uses createStreamingRequestFunction for streaming ops - Returns Promise<any> instead of PromiseResult<T> - Simplified telemetry (method name only) - Update index.mustache to export parseNDJSONStream - Update config.overrides.json with streaming file + feature flag - Add README documentation for Streamed List Objects API - Update API endpoints table with streaming endpoint Implementation: - Conditional template logic based on x-fga-streaming vendor extension - Preserves telemetry while returning raw Node.js stream - Aligned with Python SDK template patterns Dependencies: - Requires x-fga-streaming: true in OpenAPI spec (openfga/api) Related: - Fixes #76 (JavaScript SDK) - Implements openfga/js-sdk#236 - Related PR: openfga/js-sdk#280
Updates JavaScript SDK templates to support the streaming API endpoint for unlimited object retrieval. Templates now handle streaming operations differently using vendor extension conditionals. Changes: - Add streaming.mustache template with NDJSON parser for Node.js - Update api.mustache to import createStreamingRequestFunction - Update apiInner.mustache with x-fga-streaming vendor extension logic - Uses createStreamingRequestFunction for streaming ops - Returns Promise<any> instead of PromiseResult<T> - Simplified telemetry (method name only) - Update index.mustache to export parseNDJSONStream - Update config.overrides.json with streaming file + feature flag - Add README documentation for Streamed List Objects API - Update API endpoints table with streaming endpoint Implementation: - Conditional template logic based on x-fga-streaming vendor extension - Preserves telemetry while returning raw Node.js stream - Aligned with Python SDK template patterns - Fixed error propagation in async iterator adapter - Widened parseNDJSONStream type signature for better DX Dependencies: - Requires x-fga-streaming: true in OpenAPI spec (openfga/api) Related: - Fixes #76 (JavaScript SDK) - Implements openfga/js-sdk#236 - Related PR: openfga/js-sdk#280
Updates JavaScript SDK templates to support the streaming API endpoint for unlimited object retrieval. Templates now handle streaming operations differently using vendor extension conditionals. Templates Modified (7 files): - Add streaming.mustache template with NDJSON parser for Node.js - Update api.mustache to import createStreamingRequestFunction - Update apiInner.mustache with x-fga-streaming vendor extension logic - Uses createStreamingRequestFunction for streaming ops - Returns Promise<any> instead of PromiseResult<T> - Simplified telemetry (method name only) - Update index.mustache to export parseNDJSONStream - Update config.overrides.json with streaming file + feature flag - Add README_calling_api.mustache documentation for Streamed List Objects - Add README_api_endpoints.mustache table entry for streaming endpoint Implementation: - Conditional template logic based on x-fga-streaming vendor extension - Preserves telemetry while returning raw Node.js stream - Aligned with Python SDK template patterns - Fixed error propagation in async iterator adapter - Widened parseNDJSONStream type signature for better DX - Added guard to prevent onEnd processing after error state Generated SDK Verification: - ✅ streaming.ts generated with all error handling fixes - ✅ parseNDJSONStream exported from index.ts - ✅ StreamedListObjectsResponse interface in apiModel.ts -⚠️ streamedListObjects method uses regular handling (needs x-fga-streaming: true in spec) Dependencies: - Requires x-fga-streaming: true vendor extension in OpenAPI spec (openfga/api) - Without vendor extension, method is generated but uses wrong request handler Related: - Fixes #76 (JavaScript SDK) - Implements openfga/js-sdk#236 - Related PR: openfga/js-sdk#280
Adds NDJSON streaming parser template to support streamedListObjects in the JavaScript SDK. Templates provide the parsing utility; actual streaming implementation remains in custom code (client.ts, common.ts) in js-sdk repo. Templates Added/Modified (5 files): - streaming.mustache (NEW) - NDJSON parser for Node.js streams - Proper error propagation (pending promises reject on error) - onEnd guard prevents processing after error state - Widened type signature (Readable|AsyncIterable|string|Buffer) - index.mustache - Export parseNDJSONStream utility - config.overrides.json - Register streaming.mustache + supportsStreamedListObjects flag - README_calling_api.mustache - Add Streamed List Objects usage documentation - README_api_endpoints.mustache - Add endpoint to API table Architecture: - Templates generate utilities and basic API methods - Custom code in js-sdk handles actual streaming (client.ts, common.ts) - No OpenAPI spec changes required Tested: - Generated streaming.ts includes all error handling fixes - parseNDJSONStream exported correctly - Custom js-sdk code works with generated utilities Related: - Fixes #76 (JavaScript SDK) - Implements openfga/js-sdk#236 - Related PR: openfga/js-sdk#280
Adds streamedListObjects method for retrieving unlimited objects via the streaming API endpoint. Node.js-only implementation with resilient NDJSON parsing, proper error handling, and automatic resource cleanup. Requires OpenFGA server v1.2.0+ Features: - Streams beyond 1000-object limit (tested with 2000 objects) - Memory-efficient incremental results via async generators - Automatic stream cleanup prevents connection leaks - Proper error propagation through async iterators - Flexible input types (Readable|AsyncIterable|string|Buffer|Uint8Array) - Telemetry maintained through streaming request helper Implementation: - streaming.ts: NDJSON parser with robust error handling - common.ts: createStreamingRequestFunction for axios streaming - client.ts: streamedListObjects() async generator wrapper - Error handling: Pending promises reject on error, onEnd guarded - Resource management: Stream destruction in return()/throw()/finally - Type safety: Wide signature eliminates unnecessary casts Testing (153/153 tests passing): - 17 streaming tests (parsing, errors, cleanup, edge cases) - 95% coverage on streaming.ts - Live tested: 3-object and 2000-object streaming verified Examples: - example/streamed-list-objects: Full model with 2000 tuples - example/streamed-list-objects-local: Minimal local setup Related: - Fixes #236 - Parent issue: openfga/sdk-generator#76 - Related PR: openfga/sdk-generator#654 (templates)
Adds NDJSON streaming parser template to support streamedListObjects in the JavaScript SDK. Templates provide parsing utilities; actual streaming logic remains in custom code (client.ts, common.ts) maintained in js-sdk repository. Templates Added/Modified (5 files): - streaming.mustache (NEW): NDJSON parser for Node.js streams - Proper error propagation (reject pending promises on error) - onEnd guard prevents processing after error - Uint8Array handling alongside string/Buffer - Stream destruction in return()/throw() methods - Widened type signature for better DX - index.mustache: Export parseNDJSONStream utility - config.overrides.json: Register streaming + supportsStreamedListObjects flag - README_calling_api.mustache: Usage documentation - README_api_endpoints.mustache: API endpoint table entry Architecture: - Templates generate utilities (streaming.ts, exports) - Custom js-sdk code implements streaming (common.ts, client.ts) - No OpenAPI spec changes required Generated & Verified: - streaming.ts includes all error handling fixes - parseNDJSONStream exported correctly - Works with custom js-sdk streaming implementation Related: - Fixes #76 (JavaScript SDK) - Implements openfga/js-sdk#236 - Related PR: openfga/js-sdk#280
3db22bb    to
    0c2a0ab      
    Compare
  
    | - feat: add support for handling Retry-After header (#267) | ||
| - feat: streamedListObjects (streaming ListObjects) - Node.js only | ||
| - Enables retrieving >1000 objects beyond standard listObjects limit | ||
| - Requires OpenFGA server [v1.2.0+](https://github.com/openfga/openfga/releases/tag/v1.2.0) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this requirement?
| - feat: streamedListObjects (streaming ListObjects) - Node.js only | ||
| - Enables retrieving >1000 objects beyond standard listObjects limit | ||
| - Requires OpenFGA server [v1.2.0+](https://github.com/openfga/openfga/releases/tag/v1.2.0) | ||
| - Uses axios streaming via API layer with preserved telemetry | ||
| - Resilient NDJSON parsing (supports async-iterable and event-based streams) | ||
| - Parses chunked data across multiple reads; handles Buffer/string inputs | ||
| - Adds example for usage: `example/streamed-list-objects` | ||
| - Adds example for local usage: `example/streamed-list-objects-local` | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are too detailed for the changelog - replace them with a link to the documentation in Readme
E.g.
- feat: add support for [StreamedListObjects](https://openfga.dev/api/service#/Relationship%20Queries/StreamedListObjects) with streaming semantics. See [documentation](https://github.com/openfga/js-sdk/blob/main/README.md#streamed-list-objects) for more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also can you add that section to the README under List Objects
Streamed List Objects
The Streamed ListObjects API is very similar to the the ListObjects API, with two differences:
- Instead of collecting all objects before returning a response, it streams them to the client as they are collected.
- *The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.
const options = {};
// To override the authorization model id for this request
options.authorizationModelId = "01GXSA8YR785C4FYS3C0RTG7B1";
const objects = [];
for await (const response of fga.streamedListObjects(
    { user: "user:anne", relation: "can_read", type: "document" },
    { consistency: ConsistencyPreference.HigherConsistency }
)) {
    objects.push(response.object);
}
// objects = ["document:0192ab2a-d83f-756d-9397-c5ed9f3cb69a"]| @@ -0,0 +1,62 @@ | |||
| import { ClientConfiguration, OpenFgaClient, ConsistencyPreference } from "../../dist/index.js"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need two examples for this, let's stick to this one only - or the other one only
Also can you add the package.json for the example?
| for await (const _ of fga.streamedListObjects( | ||
| { user: "user:anne", relation: "can_read", type: "document" }, | ||
| { consistency: ConsistencyPreference.HigherConsistency } | ||
| )) { | ||
| count++; | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of just appending the count, can you get the object? Just to showcase to folks looking at this example?
It can be something like:
| for await (const _ of fga.streamedListObjects( | |
| { user: "user:anne", relation: "can_read", type: "document" }, | |
| { consistency: ConsistencyPreference.HigherConsistency } | |
| )) { | |
| count++; | |
| } | |
| for await (const response of fga.streamedListObjects( | |
| { user: "user:anne", relation: "can_read", type: "document" }, | |
| { consistency: ConsistencyPreference.HigherConsistency } | |
| )) { | |
| console.log(`- ${response.object}`) | |
| count++; | |
| } | 
| const model = { | ||
| schema_version: "1.1", | ||
| type_definitions: [ | ||
| { type: "user" }, | ||
| { | ||
| type: "document", | ||
| relations: { can_read: { this: {} } }, | ||
| metadata: { | ||
| relations: { | ||
| can_read: { | ||
| directly_related_user_types: [{ type: "user" }] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the syntax transformer here:
| const model = { | |
| schema_version: "1.1", | |
| type_definitions: [ | |
| { type: "user" }, | |
| { | |
| type: "document", | |
| relations: { can_read: { this: {} } }, | |
| metadata: { | |
| relations: { | |
| can_read: { | |
| directly_related_user_types: [{ type: "user" }] | |
| } | |
| } | |
| } | |
| } | |
| ] | |
| }; | |
| const dslString = ` | |
| model | |
| schema 1.1 | |
| type user | |
| type document | |
| relations | |
| can_read: [user] | |
| `; | |
| const model = transformer.transformDSLToJSONObject(dslString); | 
| @@ -0,0 +1,33 @@ | |||
| # Streamed List Objects Example | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this example I think
| @@ -0,0 +1,251 @@ | |||
| { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a complex model for this example? Can we stay simple like in the first one.
| * @param {number} [options.retryParams.minWaitInMs] - Override the minimum wait before a retry is initiated | ||
| * @returns {AsyncGenerator<StreamedListObjectsResponse>} An async generator that yields objects as they are received | ||
| */ | ||
| async *streamedListObjects(body: ClientListObjectsRequest, options: ClientRequestOptsWithConsistency = {}): AsyncGenerator<StreamedListObjectsResponse> { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add the relevant tests to client.test.js?
Note include in the tests, tests for:
- retry handling
- custom headers
- error handling
| This example demonstrates using the js-sdk `streamedListObjects` API against a locally running OpenFGA server that you manage yourself. | ||
|  | ||
| Prerequisites: | ||
| - Node.js 18+ | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this?
| Can you also review @SoulPancake's PR here: openfga/go-sdk#252 Ideally both would have the same semantics, example, tests, config options, README, etc.. | 
| - feat: add support for handling Retry-After header (#267) | ||
| - feat: streamedListObjects (streaming ListObjects) - Node.js only | ||
| - Enables retrieving >1000 objects beyond standard listObjects limit | ||
| - Requires OpenFGA server [v1.2.0+](https://github.com/openfga/openfga/releases/tag/v1.2.0) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not wrong, this was the release with the streamed list objects in the API
https://github.com/openfga/openfga/releases/tag/v0.2.0
openfga/api@75e70de
Maybe some improvements were added later in the release mentioned
Summary
Adds
streamedListObjectsmethod for retrieving unlimited objects via the streaming API. Node.js-only implementation with NDJSON parsing, error handling, and automatic resource cleanup.Requires OpenFGA server v1.2.0+
Fixes #236
Changes
streaming.tswith NDJSON parser for Node.js streamsStreamedListObjectsResponseinterface toapiModel.tsOpenFgaClient.streamedListObjects()async generator methodcreateStreamingRequestFunctiontocommon.tsfor streaming requestsparseNDJSONStreamfromindex.tsImplementation
Usage
Testing
All 153 tests passing (10/10 suites)
Related