Skip to content

RI-8219: Add Array read endpoints + key-info strategy#6064

Merged
pawelangelow merged 23 commits into
mainfrom
be/RI-8219/add-api-endpoints
Jun 17, 2026
Merged

RI-8219: Add Array read endpoints + key-info strategy#6064
pawelangelow merged 23 commits into
mainfrom
be/RI-8219/add-api-endpoints

Conversation

@pawelangelow

@pawelangelow pawelangelow commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

What

Backend slice of the Array data type read vertical (RI-8219).

  • ARGETRANGE cap: 1,000,000-element span guard so a start..end range can't be used to pull arbitrary memory; ARSCAN is exempt because it already skips empty slots.
  • ARSCAN reply normalisation: handles both the flat [idx, val, idx, val, …] and nested [[idx, val], …] shapes some clients surface, and drops malformed pairs so JSON.stringify never reaches the client as { index } with no value.
  • ArrayKeyInfoStrategy for the key-info pipeline: returns the standard TTL / size triple plus length (ARLEN, total addressable slots including gaps) and count (ARCOUNT, populated slots only). The two diverge for sparse arrays and the View tab surfaces both.

Testing

  • Bruno presets for every endpoint + a Seed Sample Data request that uploads fixtures/readings.txt through the existing bulk-import endpoint, populating the sparse readings array (indexes 0, 1, 5) that the happy-path presets target. Get Element (empty slot) documents the gap-preserving semantics (200 OK with value: null, not 404).

Note

Medium Risk
Large new browser surface against Redis with a validation breaking change on max index; mitigated by caps, tests, and read-only paths with standard ACL/404 handling.

Overview
Adds Browser Array read APIs (get-range, scan, get-length, get-count, get-next-index, get-element, get-elements) wired to Redis AR* commands, with DTOs that return u64 metrics as strings and gap slots as null on dense reads.

Safety and wire behavior: ARGETRANGE rejects spans over 1M elements; ARMGET / ARSCAN LIMIT use the same cap. ARSCAN normalizes flat vs nested Redis replies and drops incomplete pairs. RedisStringToBufferTransformer now passes null/undefined through so empty slots serialize correctly.

Key browser: New ArrayKeyInfoStrategy exposes length (ARLEN) and count (ARCOUNT) as strings; get-info OpenAPI is a oneOf with GetArrayKeyInfoResponse. IORedis registers the new array builtins for pipelines.

Breaking alignment: Valid array index max is 2^64 − 2 (not full u64) in API/UI validators, Bruno create docs, and tests. Bruno presets plus a readings bulk-import fixture exercise sparse arrays and empty-slot 200 + null semantics.

Reviewed by Cursor Bugbot for commit d3cdb3f. Bugbot is set up for automated code reviews on this repo. Configure here.

@pawelangelow pawelangelow self-assigned this Jun 15, 2026
@pawelangelow pawelangelow requested a review from a team as a code owner June 15, 2026 10:57
@jit-ci

jit-ci Bot commented Jun 15, 2026

Copy link
Copy Markdown

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe56b30c97

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76a49d6fee

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts Outdated
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Code Coverage - Backend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 92.99% 16101/17314
🟡 Branches 75.13% 5079/6760
🟢 Functions 87.32% 2494/2856
🟢 Lines 92.83% 15385/16574

Test suite run success

3580 tests passing in 317 suites.

Report generated by 🧪jest coverage report action from d3cdb3f

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Code Coverage - Integration Tests

Status Category Percentage Covered / Total
🟡 Statements 78.26% 17685/22596
🟡 Branches 60.91% 8140/13362
🟡 Functions 65.87% 2400/3643
🟡 Lines 77.82% 16631/21369

Expose the seven read-only endpoints for the Redis array data type
(POST /databases/:id/array/{get-range,scan,get-length,get-count,
get-next-index,get-element,get-elements}).

Indexes are handled as decimal strings end-to-end (validated via
IsArrayIndex) so unsigned 64-bit array indexes survive the wire and
controller layer without precision loss. ARGETRANGE enforces a hard
1,000,000-element span guard per the Redis docs; ARSCAN is exempt
because it already skips empty slots.

Adds 33 unit tests covering happy paths, WrongType, missing keys,
and ACL failures.

References: RI-8219
Adds a Bruno collection folder for the new Array endpoints with one
preset per route plus:

- Seed Sample Data — uploads fixtures/readings.txt via the existing
  POST /bulk-actions/import endpoint, seeding the sparse 'readings'
  array (indexes 0, 1, 5) that the happy-path presets target.
- Get Element (empty slot) — documents the gap-preserving semantics
  (200 OK with value: null on an unset index, not 404).

Requires Redis 8.8+ on the target database for the AR* commands.

References: RI-8219
- redis-string-to-buffer transformer: pass null/undefined through
  rather than throwing, matching the ASCII/UTF8 sibling transformers.
- ARSCAN pairing: accept both flat [idx, val, ...] and nested
  [[idx, val], ...] reply shapes; drop pairs with null/undefined
  halves so the populated-only contract is honored end-to-end.
Adds ArrayKeyInfoStrategy that pipelines TTL + ARLEN + ARCOUNT +
MEMORY USAGE so the array length and populated count appear in the
key details header (mirroring vector-set's vectorDim/quantType).
Registers the ar* commands as ioredis built-ins so they can be
issued via sendPipeline (sendCommand already handled them).

- GetKeyInfoResponse: + count?: number
- ArrayKeyInfoStrategy: pipelined fetch with size-skip when length
  exceeds MAX_KEY_SIZE (mirrors list/vector-set patterns)
- KeyInfoProvider / KeysModule: register the new strategy
- ioredis client: addBuiltinCommand for arget/armget/arlen/arcount/
  argetrange/arscan/arnext
@pawelangelow pawelangelow force-pushed the be/RI-8219/add-api-endpoints branch from 76a49d6 to f51748f Compare June 15, 2026 12:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3cf97b588b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f65e26d12f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts Outdated
Comment thread redisinsight/api/src/modules/browser/array/array.service.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca96558052

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts Outdated
ARGETRANGE / ARSCAN require start <= end. Match that contract at the
API boundary: validate the order in the service and return 400 if
reversed, instead of silently normalizing. Aligns with how every other
Redis range command behaves and removes ambiguity about how a reversed
reply would be ordered or paginated.
@pawelangelow pawelangelow force-pushed the be/RI-8219/add-api-endpoints branch from ca96558 to 9186271 Compare June 15, 2026 19:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9186271634

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/array.controller.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74bb22a61a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/keys/dto/get.keys-info.response.ts Outdated
Comment thread redisinsight/api/src/modules/browser/array/utils.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ccd26c98e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Addresses two review issues on the array read endpoints:

- toIndexString silently turned nil replies into the literal strings
  "null" / "undefined". Only getNextIndex guarded the helper; getLength,
  getCount, and ArrayKeyInfoStrategy fed nil straight through. Fixed at
  the helper: toIndexString now returns string | null (passing nil
  through as null), and a new toRequiredIndexString throws on nil for
  callers where the upstream key/type check guarantees a value.

- GetArrayMultiElementsDto accepted an unbounded indexes array. ARMGET
  is O(N) per the Redis docs, so a large list with the app's 512MB
  request body limit could tie up Redis. Capped at the same 1,000,000
  per-call limit ARGETRANGE/ARSCAN use, with the same 400 error path.

Bruno Get Elements doc updated to reflect the new cap. New unit tests
cover the nil pass-through (the exact regression codex flagged) and
the strict variant's throw-on-nil contract.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 42ddc13ebe

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/dto/get.array-range.response.ts Outdated
pawelangelow added a commit that referenced this pull request Jun 16, 2026
Covers the seven Array read endpoints landed in PR #6064:

- POST /array/get-range      (ARGETRANGE)
- POST /array/scan           (ARSCAN)
- POST /array/get-length     (ARLEN)
- POST /array/get-count      (ARCOUNT)
- POST /array/get-next-index (ARNEXT)
- POST /array/get-element    (ARGET)
- POST /array/get-elements   (ARMGET)

Locks in on the wire format the unit specs can't reach:

- decimal-string contract for length/count/scan-index/next-index
  (Joi.string().pattern(/^\d+$/) plus a u64 boundary case at index
  9223372036854775818 to catch silent numeric coercion);
- gap-preserving semantics — empty slots surface as JSON null in
  get-range / get-element / get-elements (and are skipped by scan);
- RedisStringToBufferTransformer null passthrough — encoding=buffer
  on an empty slot must stay JSON null, not a zero-length Buffer;
- explicit limit:null on scan is treated as omitted (regression
  guard for the `typeof limit === 'number'` gate);
- 400 cases hardened in PR #6064: ARRAY_RANGE_REVERSED, range > 1M
  (ARRAY_RANGE_TOO_LARGE), ARMGET @ArrayMinSize(1) and the
  @ArrayMaxSize(ARRAY_RANGE_MAX_ELEMENTS) cap, non-decimal and
  out-of-u64 indexes;
- WrongType, missing key, missing instance per endpoint;
- per-command ACL denials (-arget, -arlen, -arcount, -arnext,
  -armget, -argetrange, -arscan) gated by requirements('rte.acl').

Also extends keys/POST-databases-id-keys-get_info.test.ts with an
Array describe block (gated by rte.version>=8.8) that seeds a dense
and a sparse Array key and pins the new GetArrayKeyInfoResponse
oneOf branch — length === count for dense, length !== count for
sparse, both as decimal strings.
pawelangelow added a commit that referenced this pull request Jun 16, 2026
Covers the seven Array read endpoints landed in PR #6064:

- POST /array/get-range      (ARGETRANGE)
- POST /array/scan           (ARSCAN)
- POST /array/get-length     (ARLEN)
- POST /array/get-count      (ARCOUNT)
- POST /array/get-next-index (ARNEXT)
- POST /array/get-element    (ARGET)
- POST /array/get-elements   (ARMGET)

Locks in on the wire format the unit specs can't reach:

- decimal-string contract for length/count/scan-index/next-index
  (Joi.string().pattern(/^\d+$/) plus a u64 boundary case at index
  9223372036854775818 to catch silent numeric coercion);
- gap-preserving semantics — empty slots surface as JSON null in
  get-range / get-element / get-elements (and are skipped by scan);
- RedisStringToBufferTransformer null passthrough — encoding=buffer
  on an empty slot must stay JSON null, not a zero-length Buffer;
- explicit limit:null on scan is treated as omitted (regression
  guard for the `typeof limit === 'number'` gate);
- 400 cases hardened in PR #6064: ARRAY_RANGE_REVERSED, range > 1M
  (ARRAY_RANGE_TOO_LARGE), ARMGET @ArrayMinSize(1) and the
  @ArrayMaxSize(ARRAY_RANGE_MAX_ELEMENTS) cap, non-decimal and
  out-of-u64 indexes;
- WrongType, missing key, missing instance per endpoint;
- per-command ACL denials (-arget, -arlen, -arcount, -arnext,
  -armget, -argetrange, -arscan) gated by requirements('rte.acl').

Also extends keys/POST-databases-id-keys-get_info.test.ts with an
Array describe block (gated by rte.version>=8.8) that seeds a dense
and a sparse Array key and pins the new GetArrayKeyInfoResponse
oneOf branch — length === count for dense, length !== count for
sparse, both as decimal strings.
Comment thread redisinsight/api/src/modules/redis/client/ioredis/ioredis.client.ts Outdated
Comment thread redisinsight/api/src/modules/browser/keys/dto/get.array-key-info.response.ts Outdated
hasLimit ? [...baseArgs, 'LIMIT', limit] : [...baseArgs],
)) as unknown[];

// ARSCAN's wire shape varies by client: some clients surface a flat

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this correct? from the docs - https://redis.io/docs/latest/commands/arscan/

it seems to me like only the flat array structure is returned? I might be missing something

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch - I had to verify empirically because the docs and the wire don't agree. Tested against redis:8.8-alpine (same image as CI's oss-st-8 #6078):

RESP wire (source of truth) - redis-cli with --no-raw so it doesn't collapse nested arrays:

$ printf 'ARSCAN k 0 100\r\n' | redis-cli --no-raw
1) 1) (integer) 0
   2) "a"
2) 1) (integer) 1
   2) "b"
3) 1) (integer) 10
   2) "x"

That's *N of *2 — nested at the protocol level. Same on RESP2 and RESP3 (redis-cli -3). The plain redis-cli ARSCAN ... output in the docs (each value on its own line) is just redis-cli's default flat-print rendering — it walks any nested-array reply and prints each leaf on its own line, which makes it look flat in the "Examples" section.

ioredis (what our service sees) — c.sendCommand(new Command('ARSCAN', [key, '0', '100'])):

[ [ 0, <Buffer 61> ], [ 1, <Buffer 62> ], [ 10, <Buffer 78> ] ]

Also nested. That matched the CI failure exactly — the flat parser was building index: '0,20.1' strings from String(['0','20.1']) and value was undefined on every odd pair, which is why 6 of the scan tests collapsed to 1 element.

The Return-info section of the docs (Array reply: Flat array of index-value pairs) is wrong/outdated.

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts Outdated
ARSCAN's per-command page documents start > end as reverse iteration, not invalid input. Split the range guard so getRange still rejects reversed ranges (ARGETRANGE doesn't support them) but scan only enforces the abs-span cap and forwards start/end unchanged.
Comment thread redisinsight/api/src/modules/browser/array/utils.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ccfdf31ba

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/common/utils/array-index.helper.ts
Comment thread redisinsight/api/src/modules/browser/array/array.service.ts Outdated
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Code Coverage - Frontend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 83.19% 25307/30421
🟡 Branches 68.48% 10679/15594
🟡 Functions 78.3% 6797/8681
🟢 Lines 83.65% 24704/29533

Test suite run success

7182 tests passing in 816 suites.

Report generated by 🧪jest coverage report action from d3cdb3f

Empirical probe against Redis 8.8.0 confirms ARGETRANGE returns elements in reverse index order when start > end (matching ARSCAN and the /data-types/arrays page). Drop the pre-flight reversal rejection so both endpoints share a single span-cap validator and forward start/end to Redis unchanged.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 79b21819e3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread redisinsight/api/src/modules/browser/array/dto/get.array-range.response.ts Outdated
pawelangelow added a commit that referenced this pull request Jun 17, 2026
Covers the seven Array read endpoints landed in PR #6064:

- POST /array/get-range      (ARGETRANGE)
- POST /array/scan           (ARSCAN)
- POST /array/get-length     (ARLEN)
- POST /array/get-count      (ARCOUNT)
- POST /array/get-next-index (ARNEXT)
- POST /array/get-element    (ARGET)
- POST /array/get-elements   (ARMGET)

Locks in on the wire format the unit specs can't reach:

- decimal-string contract for length/count/scan-index/next-index
  (Joi.string().pattern(/^\d+$/) plus a u64 boundary case at index
  9223372036854775818 to catch silent numeric coercion);
- gap-preserving semantics — empty slots surface as JSON null in
  get-range / get-element / get-elements (and are skipped by scan);
- RedisStringToBufferTransformer null passthrough — encoding=buffer
  on an empty slot must stay JSON null, not a zero-length Buffer;
- explicit limit:null on scan is treated as omitted (regression
  guard for the `typeof limit === 'number'` gate);
- 400 cases hardened in PR #6064: ARRAY_RANGE_REVERSED, range > 1M
  (ARRAY_RANGE_TOO_LARGE), ARMGET @ArrayMinSize(1) and the
  @ArrayMaxSize(ARRAY_RANGE_MAX_ELEMENTS) cap, non-decimal and
  out-of-u64 indexes;
- WrongType, missing key, missing instance per endpoint;
- per-command ACL denials (-arget, -arlen, -arcount, -arnext,
  -armget, -argetrange, -arscan) gated by requirements('rte.acl').

Also extends keys/POST-databases-id-keys-get_info.test.ts with an
Array describe block (gated by rte.version>=8.8) that seeds a dense
and a sparse Array key and pins the new GetArrayKeyInfoResponse
oneOf branch — length === count for dense, length !== count for
sparse, both as decimal strings.
Redis 8.8 returns ARSCAN results as [[index, value], ...] nested
entries, while some earlier builds surface a flat [index, value, ...]
reply. Detect the shape by sniffing the first element and normalize
both into the same populated-only contract.
pawelangelow added a commit that referenced this pull request Jun 17, 2026
Covers the seven Array read endpoints landed in PR #6064:

- POST /array/get-range      (ARGETRANGE)
- POST /array/scan           (ARSCAN)
- POST /array/get-length     (ARLEN)
- POST /array/get-count      (ARCOUNT)
- POST /array/get-next-index (ARNEXT)
- POST /array/get-element    (ARGET)
- POST /array/get-elements   (ARMGET)

Locks in on the wire format the unit specs can't reach:

- decimal-string contract for length/count/scan-index/next-index
  (Joi.string().pattern(/^\d+$/) plus a u64 boundary case at index
  9223372036854775818 to catch silent numeric coercion);
- gap-preserving semantics — empty slots surface as JSON null in
  get-range / get-element / get-elements (and are skipped by scan);
- RedisStringToBufferTransformer null passthrough — encoding=buffer
  on an empty slot must stay JSON null, not a zero-length Buffer;
- explicit limit:null on scan is treated as omitted (regression
  guard for the `typeof limit === 'number'` gate);
- 400 cases hardened in PR #6064: ARRAY_RANGE_REVERSED, range > 1M
  (ARRAY_RANGE_TOO_LARGE), ARMGET @ArrayMinSize(1) and the
  @ArrayMaxSize(ARRAY_RANGE_MAX_ELEMENTS) cap, non-decimal and
  out-of-u64 indexes;
- WrongType, missing key, missing instance per endpoint;
- per-command ACL denials (-arget, -arlen, -arcount, -arnext,
  -armget, -argetrange, -arscan) gated by requirements('rte.acl').

Also extends keys/POST-databases-id-keys-get_info.test.ts with an
Array describe block (gated by rte.version>=8.8) that seeds a dense
and a sparse Array key and pins the new GetArrayKeyInfoResponse
oneOf branch — length === count for dense, length !== count for
sparse, both as decimal strings.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fd4df8d. Configure here.

Comment thread redisinsight/api/src/modules/browser/array/array.service.ts Outdated
pawelangelow added a commit that referenced this pull request Jun 17, 2026
Covers the seven Array read endpoints landed in PR #6064:

- POST /array/get-range      (ARGETRANGE)
- POST /array/scan           (ARSCAN)
- POST /array/get-length     (ARLEN)
- POST /array/get-count      (ARCOUNT)
- POST /array/get-next-index (ARNEXT)
- POST /array/get-element    (ARGET)
- POST /array/get-elements   (ARMGET)

Locks in on the wire format the unit specs can't reach:

- decimal-string contract for length/count/scan-index/next-index
  (Joi.string().pattern(/^\d+$/) plus a u64 boundary case at index
  9223372036854775818 to catch silent numeric coercion);
- gap-preserving semantics — empty slots surface as JSON null in
  get-range / get-element / get-elements (and are skipped by scan);
- RedisStringToBufferTransformer null passthrough — encoding=buffer
  on an empty slot must stay JSON null, not a zero-length Buffer;
- explicit limit:null on scan is treated as omitted (regression
  guard for the `typeof limit === 'number'` gate);
- 400 cases hardened in PR #6064: ARRAY_RANGE_REVERSED, range > 1M
  (ARRAY_RANGE_TOO_LARGE), ARMGET @ArrayMinSize(1) and the
  @ArrayMaxSize(ARRAY_RANGE_MAX_ELEMENTS) cap, non-decimal and
  out-of-u64 indexes;
- WrongType, missing key, missing instance per endpoint;
- per-command ACL denials (-arget, -arlen, -arcount, -arnext,
  -armget, -argetrange, -arscan) gated by requirements('rte.acl').

Also extends keys/POST-databases-id-keys-get_info.test.ts with an
Array describe block (gated by rte.version>=8.8) that seeds a dense
and a sparse Array key and pins the new GetArrayKeyInfoResponse
oneOf branch — length === count for dense, length !== count for
sparse, both as decimal strings.
@pawelangelow pawelangelow merged commit 9bcd495 into main Jun 17, 2026
30 checks passed
@pawelangelow pawelangelow deleted the be/RI-8219/add-api-endpoints branch June 17, 2026 10:30
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