feat(store-migrate): add @zapo-js/store-migrate for Baileys/whatsmeow store imports#47
feat(store-migrate): add @zapo-js/store-migrate for Baileys/whatsmeow store imports#47
Conversation
… 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.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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/bytesToBase64fromsrc/util/index.tsfor Buffer-free runtime base64 handling. - Introduce
packages/store-migratewith 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.
| const parsed = Number.parseInt(value, 10) | ||
| if (!Number.isFinite(parsed)) throw new Error(`whatsmeow.${field}: invalid numeric string`) | ||
| return parsed |
There was a problem hiding this comment.
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.
| const keyId = typeof id === 'string' ? base64ToBytes(id) : id | ||
| const timestamp = | ||
| typeof data.timestamp === 'string' | ||
| ? Number.parseInt(data.timestamp, 10) |
There was a problem hiding this comment.
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.
| ? Number.parseInt(data.timestamp, 10) | |
| ? (() => { | |
| const parsedTimestamp = Number.parseInt(data.timestamp, 10) | |
| return Number.isNaN(parsedTimestamp) ? 0 : parsedTimestamp | |
| })() |
| export interface BaileysADVSignedDeviceIdentity { | ||
| readonly details?: Uint8Array | ||
| readonly accountSignatureKey?: Uint8Array | ||
| readonly accountSignature?: Uint8Array | ||
| readonly deviceSignature?: Uint8Array | ||
| } |
There was a problem hiding this comment.
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.
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.