Skip to content

Conversation

@0zitro
Copy link

@0zitro 0zitro commented Sep 11, 2025

Description

What problem is being solved?

How is it being solved?

What changes are made to solve it?

References

followup openfga/api#233

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Summary by CodeRabbit

  • New Features

    • Filter stores by name when listing stores.
    • Idempotence options for writes: ignore duplicate writes or missing deletes.
    • Public batchCheck method with a simplified, consistent return type.
  • Documentation

    • Clarified batchCheck result ordering and recommended use of correlationId.
    • Documented idempotent behavior for write and delete operations.
  • Tests

    • Added coverage for listStores with a name filter.
  • Chores

    • Updated v0.9.0 date in the changelog.

@0zitro 0zitro requested review from a team as code owners September 11, 2025 16:12
@linux-foundation-easycla
Copy link

CLA Not Signed

@coderabbitai
Copy link

coderabbitai bot commented Sep 11, 2025

Walkthrough

Documentation updates, API surface extensions, and client enhancements: added an optional name filter to listStores across API/client layers; introduced idempotence flags for write requests via new enums; adjusted batchCheck return types; updated docs and CHANGELOG date; expanded tests and nocks to support query parameters.

Changes

Cohort / File(s) Summary of Changes
Documentation
CHANGELOG.md, README.md
Updated v0.9.0 date (2025-06-03 → 2025-06-04). Added BatchCheck note clarifying response ordering and correlationId usage.
API Surface: listStores and batchCheck
api.ts
Added optional name?: string to listStores across AxiosParamCreator/FP/Factory/Class; propagated query param. Changed batchCheck FP/Factory return types to Promise<CallResult<BatchCheckResponse>>. Added public OpenFgaApi.batchCheck(...). Updated doc blocks.
Models: Write idempotence enums
apiModel.ts
Added on_missing?: WriteRequestDeletesOnMissingEnum and on_duplicate?: WriteRequestWritesOnDuplicateEnum. Introduced corresponding enums with values 'error' and 'ignore'.
Client: listStores filter and write idempotence
client.ts
Extended PaginationOptions with name?: string. Added client enums for idempotence. Extended ClientWriteRequestOpts with idempotence flags; cast to API enums in write/delete paths. Passed options.name to API in listStores.
Tests: listStores with query and nock helper
tests/client.test.ts, tests/helpers/nocks.ts
Added test for listStores with name filter. Extended nock helper listStores to accept optional queryParams including name.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App as Application
  participant Client as FGA Client
  participant API as OpenFGA API Layer
  participant Server as OpenFGA Server

  rect rgba(220,235,255,0.3)
  note over App,API: listStores with optional name filter
  App->>Client: listStores({ pageSize?, continuationToken?, name? })
  Client->>API: listStores(pageSize?, continuationToken?, name?)
  API->>Server: GET /stores?{page_size,continuation_token,name}
  Server-->>API: 200 ListStoresResponse
  API-->>Client: CallResult<ListStoresResponse>
  Client-->>App: ListStoresResponse
  end
Loading
sequenceDiagram
  autonumber
  participant App as Application
  participant Client as FGA Client
  participant API as OpenFGA API Layer
  participant Server as OpenFGA Server

  rect rgba(220,255,220,0.3)
  note over App,API: Write with idempotence flags
  App->>Client: write({writes[], deletes[]}, {idempotence: {on_duplicate?, on_missing?}})
  Client->>Client: Map client enums → API enums
  Client->>API: write({writes{on_duplicate?}, deletes{on_missing?}})
  API->>Server: POST /stores/{id}/write
  alt duplicate/missing per flags
    Server-->>API: 200 OK (ignored per flag)
  else error behavior
    Server-->>API: 4xx Error
  end
  API-->>Client: CallResult<WriteResponse|Error>
  Client-->>App: Response
  end
Loading
sequenceDiagram
  autonumber
  participant App as Application
  participant API as OpenFGA API Layer
  participant Server as OpenFGA Server

  rect rgba(255,235,220,0.3)
  note over App,API: BatchCheck public API return type
  App->>API: batchCheck(storeId, body)
  API->>Server: POST /stores/{id}/batch-check
  Server-->>API: 200 BatchCheckResponse
  API-->>App: CallResult<BatchCheckResponse>
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately and concisely describes the primary change—adding idempotence support to the Write API via the on_duplicate and on_missing options—and aligns with the key code and API model changes in the PR (apiModel.ts, client.ts, and related tests/docs). It is specific, developer-focused, and suitable for scanning project history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
README.md (1)

471-474: Fix typo: “correliationId” → “correlationId”.

User-facing docs should be typo-free.

Apply:

-        // optional correliationId to associate request and response. One will be generated
+        // optional correlationId to associate request and response. One will be generated
🧹 Nitpick comments (8)
CHANGELOG.md (1)

4-6: Add Unreleased notes for new features introduced in this PR.

Please document the new Write API idempotence flags and ListStores name filter.

Proposed diff:

 ## [Unreleased](https://github.com/openfga/js-sdk/compare/v0.9.0...HEAD)
+
+- feat: add Write API idempotence options (`on_duplicate`, `on_missing`)
+- feat: ListStores supports optional `name` filter
+- docs: clarify BatchCheck result ordering and using `correlationId`
README.md (1)

452-453: Clarify correlationId constraints in the note.

Mention that correlation IDs must be unique per request and follow format limits (≤36 chars; letters, numbers, hyphens).

Proposed tweak:

-> **Note**: The order of `batchCheck` results is not guaranteed to match the order of the checks provided. Use `correlationId` to pair responses with requests.
+> **Note**: The order of `batchCheck` results is not guaranteed to match the order of the checks provided. Use a unique `correlationId` (≤36 chars, letters/numbers/hyphens) to pair responses with requests.
tests/helpers/nocks.ts (1)

70-76: Match query params as a subset to reduce test brittleness.

Exact object matching can break if additional params are sent later. Prefer subset matching.

Apply:

-    if (queryParams) {
-      mock.query(queryParams);
-    }
+    if (queryParams) {
+      mock.query(actual => Object.entries(queryParams!).every(([k, v]) => actual[k] === v));
+    }
client.ts (1)

335-336: listStores: plumbs name filter correctly.

Consider updating README “List Stores” section to show the name option.

Also applies to: 343-344

api.ts (4)

129-136: Fix malformed JSON in BatchCheck examples.

The examples are missing a comma after the object field, which breaks copy/paste. Apply across all repeated docblocks in this file.

-          "object": "document:2021-budget"          "relation": "reader",
+          "object": "document:2021-budget",          "relation": "reader",

Also applies to: 810-817, 1086-1093, 1286-1294


391-395: Polish the new listStores name parameter docs and ensure consistent threading.

LGTM on wiring name through all surfaces. Please fix a punctuation nit in the doc text.

- * @param {string} [name] The name parameter instructs the API to only include results that match that name.Multiple results may be returned. Only exact matches will be returned; substring matches and regexes will not be evaluated
+ * @param {string} [name] The name parameter instructs the API to only include results that match that name. Multiple results may be returned. Only exact matches will be returned; substring matches and regexes will not be evaluated.

Also applies to: 920-925, 1164-1170, 1378-1385


395-405: Handle empty-string name defensively (optional).

If name === "", we currently send ?name=. If the API treats empty as invalid, consider omitting it.

-    if (name !== undefined) {
+    if (name !== undefined && name !== "") {
       localVarQueryParameter["name"] = name;
     }

Also applies to: 417-419


680-687: Great: Write API idempotence is documented; minor copy edits.

Solid explanation and examples. Two tiny edits improve clarity.

- determine whether a relationship exists between an object and an user.
+ determine whether a relationship exists between an object and a user.
- the most restrictive action (error) will take precedence.
+ the most restrictive action ("error") will take precedence.

Also applies to: 1027-1034, 1242-1249, 1470-1478

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6c1c4f and e70931d.

📒 Files selected for processing (7)
  • CHANGELOG.md (1 hunks)
  • README.md (1 hunks)
  • api.ts (17 hunks)
  • apiModel.ts (2 hunks)
  • client.ts (5 hunks)
  • tests/client.test.ts (1 hunks)
  • tests/helpers/nocks.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tests/client.test.ts (2)
example/example1/example1.mjs (11)
  • store (31-31)
  • fgaClient (18-23)
  • fgaClient (38-38)
  • fgaClient (46-46)
  • fgaClient (50-50)
  • fgaClient (155-155)
  • fgaClient (159-159)
  • fgaClient (164-168)
  • fgaClient (179-186)
  • fgaClient (191-210)
  • fgaClient (236-236)
tests/helpers/default-config.ts (1)
  • defaultConfiguration (69-69)
client.ts (2)
common.ts (1)
  • PromiseResult (129-129)
apiModel.ts (1)
  • ListStoresResponse (868-881)
api.ts (3)
base.ts (1)
  • RequestArgs (29-32)
common.ts (3)
  • RequestArgs (43-46)
  • PromiseResult (129-129)
  • CallResult (125-127)
apiModel.ts (1)
  • ListStoresResponse (868-881)
🔇 Additional comments (11)
CHANGELOG.md (1)

8-8: Date bump looks fine.

No issues with updating the v0.9.0 date.

tests/client.test.ts (1)

114-132: LGTM: validates ListStores name filter is forwarded.

Nice coverage and assertion via nock scope.

apiModel.ts (4)

1923-1929: LGTM: adds deletes.on_missing option with clear semantics.


1931-1939: LGTM: enum for deletes.on_missing.


1952-1958: LGTM: adds writes.on_duplicate option with clear semantics.


1960-1968: LGTM: enum for writes.on_duplicate.

client.ts (4)

19-21: Type-only imports are correct here.

Safe since they’re used only for typing in casts.


132-132: PaginationOptions: adding name looks good.

Keeps backward compatibility; used only by listStores.


207-216: Public idempotence options: good API design; add tests to assert body mapping.

Please add tests that verify writes.on_duplicate and deletes.on_missing are included in the POST body for both transaction mode and chunked mode.

Proposed test additions:

  • Update helpers/nocks.write to validate request body includes writes.on_duplicate / deletes.on_missing when provided.
  • Add two tests: transaction (single call) and non-transaction (chunked) paths asserting those flags are sent.

522-524: Idempotence mapping to API body looks correct.

Casts to API enums are fine; fields only set when provided.

Also applies to: 528-530

api.ts (1)

471-478: No action on unrelated READ docs.

These appear to be formatting-only churn; nothing functionally tied to this PR.

Also applies to: 947-954, 1183-1190, 1401-1410

Comment on lines +192 to +200
export declare enum ClientWriteRequestWritesOnDuplicateEnum {
Error = "error",
Ignore = "ignore"
}
export declare enum ClientWriteRequestDeletesOnMissingEnum {
Error = "error",
Ignore = "ignore"
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Do not use declare enum in .ts source — exports won’t exist at runtime.

Consumers will likely import these enums as values. Use regular exported enums so runtime values are emitted.

Apply:

-export declare enum ClientWriteRequestWritesOnDuplicateEnum {
+export enum ClientWriteRequestWritesOnDuplicateEnum {
     Error = "error",
     Ignore = "ignore"
 }
-export declare enum ClientWriteRequestDeletesOnMissingEnum {
+export enum ClientWriteRequestDeletesOnMissingEnum {
     Error = "error",
     Ignore = "ignore"
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export declare enum ClientWriteRequestWritesOnDuplicateEnum {
Error = "error",
Ignore = "ignore"
}
export declare enum ClientWriteRequestDeletesOnMissingEnum {
Error = "error",
Ignore = "ignore"
}
export enum ClientWriteRequestWritesOnDuplicateEnum {
Error = "error",
Ignore = "ignore"
}
export enum ClientWriteRequestDeletesOnMissingEnum {
Error = "error",
Ignore = "ignore"
}
🤖 Prompt for AI Agents
In client.ts around lines 192 to 200, the enums are declared with "declare enum"
which emits no runtime values; replace those with regular exported enums (e.g.,
"export enum ClientWriteRequestWritesOnDuplicateEnum { ... }" and "export enum
ClientWriteRequestDeletesOnMissingEnum { ... }") so the enum values are emitted
into the compiled JS, update any imports/usages if needed, and run the
build/type-check to verify consumers can import the enums as runtime values.

@rhamzeh
Copy link
Member

rhamzeh commented Sep 12, 2025

Thanks @0zitro!

We'll create the JS SDK issue for this soon, just getting approvals from the rest of the team around the interface. The suggested interface (see openfga/sdk-generator#610) is similar to the one you've built but might need minor tweaking.

Some notes:

  • You may want to get a headstart on getting the CLA mentioned above signed, that way there will be no blocker once this is reviewed
  • FYI - do not make any changes in the models, those are autogenerated, and any custom changes you make in the will get wiped

@0zitro
Copy link
Author

0zitro commented Sep 15, 2025

@rhamzeh thanks for the feedback! This was actually meant more like a draft PR with an implementation sketch. Feel free to use the commit code as you wish, it's like 6 lines total. Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants