Skip to content

feat(store-migrate): add @zapo-js/store-migrate for Baileys/whatsmeow store imports#47

Draft
vinikjkkj wants to merge 3 commits intomasterfrom
feat/store-migrate
Draft

feat(store-migrate): add @zapo-js/store-migrate for Baileys/whatsmeow store imports#47
vinikjkkj wants to merge 3 commits intomasterfrom
feat/store-migrate

Conversation

@vinikjkkj
Copy link
Copy Markdown
Owner

@vinikjkkj vinikjkkj commented May 1, 2026

Pure conversion functions that take Baileys' AuthenticationCreds + serialized session/sender-key structs (plain JS objects, not proto bytes) and whatsmeow's SQL row shapes, returning zapo store inputs. Zero I/O — callers do their own filesystem/SQL/Redis reads and store writes.

Baileys session conversion translates the libsignal-node SessionRecord struct into zapo's SignalSessionRecord, picking the open entry as current and demoting closed history into prevSessions; out-of-order messageKeys are dropped (Baileys keeps raw HKDF seeds, zapo expects pre-derived cipher/mac/iv triples). whatsmeow paths share the libsignal proto wire format, so RecordStructure / SenderKeyRecordStructure bytes decode natively via existing zapo helpers.

Re-exports base64ToBytes/bytesToBase64 from zapo-js/util so packages can avoid Buffer in runtime code.

… store imports

Pure conversion functions that take Baileys' AuthenticationCreds + serialized
session/sender-key structs (plain JS objects, not proto bytes) and whatsmeow's
SQL row shapes, returning zapo store inputs. Zero I/O — callers do their own
filesystem/SQL/Redis reads and store writes.

Baileys session conversion translates the libsignal-node SessionRecord struct
into zapo's SignalSessionRecord, picking the open entry as current and demoting
closed history into prevSessions; out-of-order messageKeys are dropped (Baileys
keeps raw HKDF seeds, zapo expects pre-derived cipher/mac/iv triples).
whatsmeow paths share the libsignal proto wire format, so RecordStructure /
SenderKeyRecordStructure bytes decode natively via existing zapo helpers.

Re-exports base64ToBytes/bytesToBase64 from zapo-js/util so packages can avoid
Buffer in runtime code per AGENTS.md §7.1.
@vinikjkkj vinikjkkj requested a review from Copilot May 1, 2026 19:00
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 37d3228d-62cc-4ab3-9465-fc9db9fb7e13

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/store-migrate

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.

@vinikjkkj
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new @zapo-js/store-migrate package that provides pure (zero I/O) conversion helpers to import Baileys and whatsmeow auth/store shapes into zapo-js store inputs, plus supporting utilities and tests. It also exposes base64 helpers via the main zapo-js/util barrel and wires the new package into ESLint’s TS project list.

Changes:

  • Export base64ToBytes / bytesToBase64 from src/util/index.ts for Buffer-free runtime base64 handling.
  • Introduce packages/store-migrate with Baileys + whatsmeow converters (sessions, sender keys, creds, appstate, contacts, privacy tokens, etc.) and shared utilities (address parsing, BufferJSON reviver, key derivation, numeric coercion).
  • Add comprehensive Node test coverage for the new conversion helpers and register the package tsconfig in eslint.config.js.

Reviewed changes

Copilot reviewed 44 out of 45 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/util/index.ts Re-exports base64 encode/decode utilities from @util/bytes.
eslint.config.js Adds packages/store-migrate/tsconfig.json to TS ESLint project/resolver lists.
packages/store-migrate/package.json New package manifest, exports map, and build/typecheck/test scripts.
packages/store-migrate/tsconfig.json Package TS config for typechecking with monorepo path aliases.
packages/store-migrate/tsconfig.build.cjs.json Package TS build config (CJS) emitting dist/ + d.ts/maps.
packages/store-migrate/src/index.ts Package entrypoint re-exporting Baileys/whatsmeow modules + utils.
packages/store-migrate/src/util/keys.ts X25519 private→keypair derivation helper.
packages/store-migrate/src/util/buffer-json.ts JSON reviver for Baileys BufferJSON objects to Uint8Array.
packages/store-migrate/src/util/address.ts Libsignal address string parsing + default server inference.
packages/store-migrate/src/whatsmeow/index.ts whatsmeow conversion exports + row shape types.
packages/store-migrate/src/whatsmeow/types.ts whatsmeow SQL row type definitions (driver-friendly unions).
packages/store-migrate/src/whatsmeow/numeric.ts Numeric/boolean coercion helpers for DB row values.
packages/store-migrate/src/whatsmeow/creds.ts Converts whatsmeow device row into WaAuthCredentials.
packages/store-migrate/src/whatsmeow/keys.ts Converts whatsmeow prekeys + identity keys.
packages/store-migrate/src/whatsmeow/session.ts Decodes whatsmeow session proto bytes into zapo session record.
packages/store-migrate/src/whatsmeow/sender-key.ts Decodes whatsmeow sender-key proto bytes into zapo sender-key record.
packages/store-migrate/src/whatsmeow/appstate.ts Converts appstate sync keys and versions (mutation MAC join).
packages/store-migrate/src/whatsmeow/contact.ts Converts contact rows into WaStoredContactRecord.
packages/store-migrate/src/whatsmeow/privacy-token.ts Converts privacy token rows into WaStoredPrivacyTokenRecord.
packages/store-migrate/src/whatsmeow/message-secret.ts Converts message-secret row into zapo WaMessageSecretEntry.
packages/store-migrate/src/baileys/index.ts Baileys conversion exports + types.
packages/store-migrate/src/baileys/types.ts Baileys JSON-parsed auth/session/sender-key structural types.
packages/store-migrate/src/baileys/coerce.ts Coerces Baileys base64-or-bytes fields to Uint8Array.
packages/store-migrate/src/baileys/creds.ts Converts Baileys creds into WaAuthCredentials.
packages/store-migrate/src/baileys/keys.ts Converts Baileys prekeys + identity keys.
packages/store-migrate/src/baileys/session.ts Converts Baileys libsignal-node serialized session objects into zapo session records.
packages/store-migrate/src/baileys/sender-key.ts Converts Baileys sender-key state array into a single zapo sender-key record.
packages/store-migrate/src/baileys/appstate.ts Converts Baileys appstate sync keys + LT hash state into zapo shapes.
packages/store-migrate/src/baileys/privacy-token.ts Converts Baileys trusted-contact token entry into zapo record.
packages/store-migrate/src/baileys/device-list.ts Wraps Baileys device list into zapo snapshot shape.
packages/store-migrate/src/tests/address.test.ts Tests for libsignal address parsing + server inference.
packages/store-migrate/src/tests/buffer-json.test.ts Tests for BufferJSON reviver behavior.
packages/store-migrate/src/tests/baileys-creds.test.ts Fixture-based Baileys creds conversion test.
packages/store-migrate/src/tests/baileys-keys.test.ts Tests for Baileys key conversions.
packages/store-migrate/src/tests/baileys-session.test.ts Tests for Baileys session conversion including prevSessions selection.
packages/store-migrate/src/tests/baileys-sender-key.test.ts Tests for Baileys sender-key conversion + coercion behavior.
packages/store-migrate/src/tests/baileys-appstate.test.ts Tests for Baileys appstate conversion (keyId/timestamp + index map rekey).
packages/store-migrate/src/tests/baileys-misc.test.ts Tests for Baileys misc converters (tc token, device list).
packages/store-migrate/src/tests/whatsmeow-creds.test.ts Tests for whatsmeow creds conversion + bigint handling.
packages/store-migrate/src/tests/whatsmeow-keys.test.ts Tests for whatsmeow key conversions + boolean coercion.
packages/store-migrate/src/tests/whatsmeow-session.test.ts Tests for whatsmeow proto session/sender-key decode + address parsing.
packages/store-migrate/src/tests/whatsmeow-appstate.test.ts Tests for whatsmeow appstate converters (fingerprint decode + mutation join).
packages/store-migrate/src/tests/whatsmeow-misc.test.ts Tests for whatsmeow misc converters (contact/privacy token/message secret).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +16
const parsed = Number.parseInt(value, 10)
if (!Number.isFinite(parsed)) throw new Error(`whatsmeow.${field}: invalid numeric string`)
return parsed
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

toNumber accepts numeric strings but doesn’t guard against values beyond Number.MAX_SAFE_INTEGER. For inputs like '9007199254740993' this will silently lose precision. Consider parsing strings as BigInt (or validating Number.isSafeInteger(parsed) and matching a BigInt(value) check) and throwing when the value exceeds the safe integer range, consistent with the bigint branch.

Copilot uses AI. Check for mistakes.
const keyId = typeof id === 'string' ? base64ToBytes(id) : id
const timestamp =
typeof data.timestamp === 'string'
? Number.parseInt(data.timestamp, 10)
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

convertBaileysAppStateSyncKey can return timestamp: NaN when data.timestamp is a non-numeric string (since parseInt is unchecked). Since WaAppStateSyncKey.timestamp is required, this should either throw on invalid strings or fall back to a safe default (e.g., 0) after validation.

Suggested change
? Number.parseInt(data.timestamp, 10)
? (() => {
const parsedTimestamp = Number.parseInt(data.timestamp, 10)
return Number.isNaN(parsedTimestamp) ? 0 : parsedTimestamp
})()

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +31
export interface BaileysADVSignedDeviceIdentity {
readonly details?: Uint8Array
readonly accountSignatureKey?: Uint8Array
readonly accountSignature?: Uint8Array
readonly deviceSignature?: Uint8Array
}
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

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

BaileysADVSignedDeviceIdentity fields are typed as Uint8Array, but the included Baileys fixture uses base64 strings for details, accountSignatureKey, accountSignature, and deviceSignature (and bufferJsonReviver won’t convert plain strings). To match real Baileys JSON shapes for callers, these should accept string | Uint8Array (e.g., reuse MaybeBytes) or be explicitly documented/normalized during conversion.

Copilot uses AI. Check for mistakes.
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