@zervonex/baileys 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,102 +1,154 @@
1
- import { randomBytes } from 'crypto';
2
- import { getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidMetaAI, isLidUser, isPnUser, jidNormalizedUser } from '../WABinary/index.js';
3
- import { unixTimestampSeconds } from './generics.js';
4
- import { TC_TOKEN_INDEX_KEY } from './key-store.js';
1
+ import { randomBytes } from 'crypto'
2
+ import { getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidMetaAI, isLidUser, isPnUser, jidNormalizedUser } from '../WABinary/index.js'
3
+ import { unixTimestampSeconds } from './generics.js'
5
4
 
6
- const BOT_PHONE_REGEX = /^1313555\d{4}$|^131655500\d{2}$/;
7
- const TC_TOKEN_BUCKET_DURATION = 604800; // 7 days in seconds
8
- const TC_TOKEN_NUM_BUCKETS = 4; // ~28-day rolling window
5
+ // ─── Constants ────────────────────────────────────────────────────────────────
6
+ export const TC_TOKEN_INDEX_KEY = '__index'
7
+ const BOT_PHONE_REGEX = /^1313555\d{4}$|^131655500\d{2}$/
8
+ const TC_TOKEN_BUCKET_DURATION = 604800 // 7 days
9
+ const TC_TOKEN_NUM_BUCKETS = 4 // ~28-day rolling window
10
+ const TC_TOKEN_MIN_BYTES = 1
11
+ const TC_TOKEN_MAX_BYTES = 120 // DMW layer constraint
12
+ const TC_TOKEN_MAX_RECIPIENTS = 5 // feature flag 20606 default cap
9
13
 
10
- const currentBucket = () => Math.floor(Math.floor(Date.now() / 1000) / TC_TOKEN_BUCKET_DURATION);
11
- const generateTcToken = () => Buffer.concat([Buffer.from([0x04, 0x01, (Math.floor(unixTimestampSeconds() / TC_TOKEN_BUCKET_DURATION) - 2900) & 0xff]), randomBytes(8)]);
14
+ const currentBucket = () => Math.floor(unixTimestampSeconds() / TC_TOKEN_BUCKET_DURATION)
15
+ const generateTcToken = () => randomBytes(32) // local pre-seed fallback only; real tokens are server-issued
16
+
17
+ // ─── JID helpers ──────────────────────────────────────────────────────────────
12
18
 
13
19
  export const isRegularUser = jid => {
14
- if (!jid) return false;
15
- const user = jid.split('@')[0] ?? '';
16
- if (user === '0' || BOT_PHONE_REGEX.test(user) || isJidMetaAI(jid)) return false;
17
- return !!(isPnUser(jid) || isLidUser(jid) || isHostedPnUser(jid) || isHostedLidUser(jid) || jid.endsWith('@c.us'));
18
- };
20
+ if (!jid) return false
21
+ const user = jid.split('@')[0] ?? ''
22
+ if (user === '0' || BOT_PHONE_REGEX.test(user) || isJidMetaAI(jid)) return false
23
+ return !!(isPnUser(jid) || isLidUser(jid) || isHostedPnUser(jid) || isHostedLidUser(jid) || jid.endsWith('@c.us'))
24
+ }
25
+
26
+ // storage key is always LID when resolvable
27
+ export const resolveTcTokenJid = async (jid, getLIDForPN) =>
28
+ isLidUser(jid) ? jid : (await getLIDForPN(jid) || null)
29
+
30
+ // bidirectional — respects useLidForEncryption flag
31
+ export const resolveIssuanceJid = async (jid, issueToLid, getLIDForPN, getPNForLID) => {
32
+ if (issueToLid) return isLidUser(jid) ? jid : (await getLIDForPN(jid)) ?? jid
33
+ if (!isLidUser(jid)) return jid
34
+ return getPNForLID ? (await getPNForLID(jid)) ?? jid : jid
35
+ }
36
+
37
+ // ─── Expiry ───────────────────────────────────────────────────────────────────
19
38
 
20
39
  export const isTcTokenExpired = timestamp => {
21
- if (timestamp == null) return true;
22
- const ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp;
23
- return isNaN(ts) || ts < (currentBucket() - (TC_TOKEN_NUM_BUCKETS - 1)) * TC_TOKEN_BUCKET_DURATION;
24
- };
40
+ if (timestamp == null) return true
41
+ const ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
42
+ return isNaN(ts) || ts < (currentBucket() - (TC_TOKEN_NUM_BUCKETS - 1)) * TC_TOKEN_BUCKET_DURATION
43
+ }
25
44
 
45
+ // re-issue only if sender crossed into a new bucket since last issuance
26
46
  export const shouldSendNewTcToken = senderTimestamp => {
27
- if (senderTimestamp === undefined) return true;
28
- return currentBucket() > Math.floor(senderTimestamp / TC_TOKEN_BUCKET_DURATION);
29
- };
30
-
31
- export const resolveTcTokenJid = async (jid, getLIDForPN) => isLidUser(jid) ? jid : (await getLIDForPN(jid) || null);
47
+ if (senderTimestamp === undefined) return true
48
+ return currentBucket() > Math.floor(senderTimestamp / TC_TOKEN_BUCKET_DURATION)
49
+ }
32
50
 
33
- export const resolveIssuanceJid = async (jid, issueToLid, getLIDForPN, getPNForLID) => {
34
- if (issueToLid) return isLidUser(jid) ? jid : (await getLIDForPN(jid)) ?? jid;
35
- if (!isLidUser(jid)) return jid;
36
- return getPNForLID ? (await getPNForLID(jid)) ?? jid : jid;
37
- };
51
+ // ─── Index ────────────────────────────────────────────────────────────────────
38
52
 
39
53
  export const readTcTokenIndex = async keys => {
40
54
  for (const key of [TC_TOKEN_INDEX_KEY, 'index']) {
41
- const entry = (await keys.get('tctoken', [key]))[key];
42
- if (!entry?.token?.length) continue;
55
+ const entry = (await keys.get('tctoken', [key]))[key]
56
+ if (!entry?.token?.length) continue
43
57
  try {
44
- const parsed = JSON.parse(Buffer.from(entry.token).toString());
45
- if (!Array.isArray(parsed)) continue;
46
- return parsed.filter(j => typeof j === 'string' && j.length > 0 && j !== TC_TOKEN_INDEX_KEY && j !== 'index');
47
- } catch { continue; }
58
+ const parsed = JSON.parse(Buffer.from(entry.token).toString())
59
+ if (!Array.isArray(parsed)) continue
60
+ return parsed.filter(j => typeof j === 'string' && j.length > 0 && j !== TC_TOKEN_INDEX_KEY && j !== 'index')
61
+ } catch { continue }
48
62
  }
49
- return [];
50
- };
63
+ return []
64
+ }
51
65
 
52
66
  export const buildMergedTcTokenIndexWrite = async (keys, addedJids) => {
53
- const merged = new Set(await readTcTokenIndex(keys));
54
- for (const jid of addedJids) if (jid && jid !== TC_TOKEN_INDEX_KEY && jid !== 'index') merged.add(jid);
55
- return { [TC_TOKEN_INDEX_KEY]: { token: Buffer.from(JSON.stringify([...merged])) } };
56
- };
67
+ const merged = new Set(await readTcTokenIndex(keys))
68
+ for (const jid of addedJids) if (jid && jid !== TC_TOKEN_INDEX_KEY && jid !== 'index') merged.add(jid)
69
+ return { [TC_TOKEN_INDEX_KEY]: { token: Buffer.from(JSON.stringify([...merged])) } }
70
+ }
71
+
72
+ // ─── Pre-seed ─────────────────────────────────────────────────────────────────
57
73
 
58
74
  export const preSeedTcToken = async ({ authState, jid, getLIDForPN, logger }) => {
59
- const tcTokenJid = await resolveTcTokenJid(jid, getLIDForPN);
60
- const existing = await authState.keys.get('tctoken', [tcTokenJid]);
61
- if (existing[tcTokenJid]?.token?.length) return { token: existing[tcTokenJid].token, storageJid: tcTokenJid };
62
- const token = generateTcToken();
63
- const timestamp = String(unixTimestampSeconds());
64
- const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid]);
65
- await authState.keys.set({ tctoken: { [tcTokenJid]: { ...(existing[tcTokenJid] || {}), token, timestamp }, ...indexWrite } });
66
- logger?.debug({ jid, tcTokenJid }, 'pre-seeded locally generated tctoken');
67
- return { token, storageJid: tcTokenJid };
68
- };
75
+ const tcTokenJid = await resolveTcTokenJid(jid, getLIDForPN)
76
+ const existing = await authState.keys.get('tctoken', [tcTokenJid])
77
+ if (existing[tcTokenJid]?.token?.length) return { token: existing[tcTokenJid].token, storageJid: tcTokenJid }
78
+ const token = generateTcToken()
79
+ const timestamp = String(unixTimestampSeconds())
80
+ const indexWrite = await buildMergedTcTokenIndexWrite(authState.keys, [tcTokenJid])
81
+ await authState.keys.set({ tctoken: { [tcTokenJid]: { ...(existing[tcTokenJid] || {}), token, timestamp }, ...indexWrite } })
82
+ logger?.debug({ jid, tcTokenJid }, 'pre-seeded locally generated tctoken')
83
+ return { token, storageJid: tcTokenJid }
84
+ }
69
85
 
86
+ // ─── Outgoing nodes ───────────────────────────────────────────────────────────
87
+ // confirmed wire format: <tctoken>bytes</tctoken> — flat, identical to fanout format, no smax:any wrapper
88
+ // timestamp attr is internal only, never sent on wire
70
89
  export const buildTcTokenFromJid = async ({ authState, jid, baseContent = [], getLIDForPN }) => {
71
90
  try {
72
- const storageJid = await resolveTcTokenJid(jid, getLIDForPN);
73
- const entry = (await authState.keys.get('tctoken', [storageJid]))?.[storageJid];
74
- const { token: tcTokenBuffer, timestamp, senderTimestamp } = entry ?? {};
91
+ const storageJid = await resolveTcTokenJid(jid, getLIDForPN)
92
+ const entry = (await authState.keys.get('tctoken', [storageJid]))?.[storageJid]
93
+ const { token: tcTokenBuffer, timestamp, senderTimestamp } = entry ?? {}
75
94
  if (!tcTokenBuffer?.length || timestamp === undefined || isTcTokenExpired(timestamp)) {
76
95
  if (tcTokenBuffer) {
77
- const cleared = senderTimestamp !== undefined ? { token: Buffer.alloc(0), senderTimestamp } : null;
78
- await authState.keys.set({ tctoken: { [storageJid]: cleared } });
96
+ const cleared = senderTimestamp !== undefined ? { token: Buffer.alloc(0), senderTimestamp } : null
97
+ await authState.keys.set({ tctoken: { [storageJid]: cleared } })
79
98
  }
80
- return baseContent.length > 0 ? baseContent : undefined;
99
+ return baseContent.length > 0 ? baseContent : undefined
81
100
  }
82
- baseContent.push({ tag: 'tctoken', attrs: { t: String(timestamp) }, content: tcTokenBuffer });
83
- return baseContent;
84
- } catch { return baseContent.length > 0 ? baseContent : undefined; }
85
- };
101
+ if (tcTokenBuffer.length < TC_TOKEN_MIN_BYTES || tcTokenBuffer.length > TC_TOKEN_MAX_BYTES) return baseContent.length > 0 ? baseContent : undefined
102
+ baseContent.push({ tag: 'tctoken', attrs: {}, content: tcTokenBuffer })
103
+ return baseContent
104
+ } catch { return baseContent.length > 0 ? baseContent : undefined }
105
+ }
106
+
107
+ // fanout <to> node — confirmed wire format: <tctoken>bytes</tctoken> (no smax:any wrapper)
108
+ // enforces per-send JID dedup (EOC.A01 Set guard) and flag-20606 recipient cap
109
+ export const buildFanoutTcTokenNode = ({ tokenBuffer, recipientsSeen, userJid }) => {
110
+ if (
111
+ !tokenBuffer?.length
112
+ || tokenBuffer.length < TC_TOKEN_MIN_BYTES
113
+ || tokenBuffer.length > TC_TOKEN_MAX_BYTES
114
+ || recipientsSeen.size >= TC_TOKEN_MAX_RECIPIENTS
115
+ || recipientsSeen.has(userJid)
116
+ ) return null
117
+ recipientsSeen.add(userJid)
118
+ return { tag: 'tctoken', attrs: {}, content: tokenBuffer }
119
+ }
86
120
 
121
+ // ─── Incoming storage ─────────────────────────────────────────────────────────
122
+
123
+ // handles both IQ result and privacy_token notification (same <tokens> structure)
124
+ // wire format: <token type="trusted_contact" t="timestamp">bytes</token>
87
125
  export const storeTcTokensFromIqResult = async ({ result, fallbackJid, keys, getLIDForPN, onNewJidStored }) => {
88
- const tokensNode = getBinaryNodeChild(result, 'tokens');
89
- if (!tokensNode) return;
126
+ const tokensNode = getBinaryNodeChild(result, 'tokens')
127
+ if (!tokensNode) return
90
128
  for (const tokenNode of getBinaryNodeChildren(tokensNode, 'token')) {
91
- if (tokenNode.attrs.type !== 'trusted_contact' || !(tokenNode.content instanceof Uint8Array)) continue;
92
- const rawJid = jidNormalizedUser(fallbackJid || tokenNode.attrs.jid);
93
- if (!isRegularUser(rawJid)) continue;
94
- const storageJid = await resolveTcTokenJid(rawJid, getLIDForPN);
95
- const existingEntry = (await keys.get('tctoken', [storageJid]))[storageJid];
96
- const existingTs = existingEntry?.timestamp ? Number(existingEntry.timestamp) : 0;
97
- const incomingTs = tokenNode.attrs.t ? Number(tokenNode.attrs.t) : 0;
98
- if (!incomingTs || (existingTs > 0 && existingTs > incomingTs)) continue;
99
- await keys.set({ tctoken: { [storageJid]: { ...existingEntry, token: Buffer.from(tokenNode.content), timestamp: tokenNode.attrs.t } } });
100
- onNewJidStored?.(storageJid);
129
+ if (tokenNode.attrs.type !== 'trusted_contact') continue
130
+ if (!(tokenNode.content instanceof Uint8Array) || !tokenNode.content.length) continue
131
+ const tokenBytes = tokenNode.content
132
+ if (tokenBytes.length > TC_TOKEN_MAX_BYTES) continue
133
+ const rawJid = jidNormalizedUser(fallbackJid || tokenNode.attrs.jid)
134
+ if (!isRegularUser(rawJid)) continue
135
+ const storageJid = await resolveTcTokenJid(rawJid, getLIDForPN)
136
+ const existingEntry = (await keys.get('tctoken', [storageJid]))[storageJid]
137
+ const existingTs = existingEntry?.timestamp ? Number(existingEntry.timestamp) : 0
138
+ const incomingTs = tokenNode.attrs.t ? Number(tokenNode.attrs.t) : 0
139
+ if (!incomingTs || (existingTs > 0 && existingTs > incomingTs)) continue
140
+ await keys.set({ tctoken: { [storageJid]: { ...existingEntry, token: Buffer.from(tokenBytes), timestamp: tokenNode.attrs.t } } })
141
+ onNewJidStored?.(storageJid)
101
142
  }
102
- };
143
+ }
144
+
145
+ // ─── Content binding ──────────────────────────────────────────────────────────
146
+
147
+ // URL-type messages only — confirmed from AbstractC2052DmX.A00()
148
+ // wire format: <content_binding>bytes</content_binding> (flat, no wrapper)
149
+ export const buildContentBindingNode = ({ userJid, contentBindingMap, messageType }) => {
150
+ if (messageType !== 'url' || !contentBindingMap?.has(userJid)) return null
151
+ const bytes = contentBindingMap.get(userJid)
152
+ if (!bytes?.length) return null
153
+ return { tag: 'content_binding', attrs: {}, content: bytes }
154
+ }
package/lib/index.js CHANGED
@@ -1,58 +1,57 @@
1
- import gradient from 'gradient-string';
1
+ import gradient from 'gradient-string'
2
2
  import makeWASocket from './Socket/index.js'
3
3
 
4
- const banner = `
5
- ╔══════════════════════════════════════════════════════════════════╗
6
- ║ ║
7
- ║ ███╗ ██╗███████╗██╗ ██╗██╗ ██╗███████╗ ║
8
- ║ ████╗ ██║██╔════╝╚██╗██╔╝██║ ██║██╔════╝ ║
9
- ║ ██╔██╗ ██║█████╗ ╚███╔╝ ██║ ██║███████╗ ║
10
- ║ ██║╚██╗██║██╔══╝ ██╔██╗ ██║ ██║╚════██║ ║
11
- ║ ██║ ╚████║███████╗██╔╝ ██╗╚██████╔╝███████║ ║
12
- ║ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ║
13
- ║ ║
14
- ║ ████████╗███████╗ ██████╗██╗ ██╗ ║
15
- ║ ╚══██╔══╝██╔════╝██╔════╝██║ ██║ ║
16
- ║ ██║ █████╗ ██║ ███████║ ║
17
- ║ ██║ ██╔══╝ ██║ ██╔══██║ ║
18
- ║ ██║ ███████╗╚██████╗██║ ██║ ║
19
- ║ ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝ ║
20
- ║ ║
21
- ║ ██████╗ ██████╗ ██████╗ ║
22
- ║ ██╔══██╗██╔══██╗██╔═══██╗ ║
23
- ║ ██████╔╝██████╔╝██║ ██║ ║
24
- ║ ██╔═══╝ ██╔══██╗██║ ██║ ║
25
- ║ ██║ ██║ ██║╚██████╔╝ ║
26
- ║ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ║
27
- ║ ║
28
- ╚══════════════════════════════════════════════════════════════════╝
29
- `;
4
+ const banner = [
5
+ '╭───────────────────────────────────────────────────────────────────────────────────────────╮',
6
+ '│ │',
7
+ '│ [][][][][] [][][][][] [][][][] [] [] [][][] [] [] [][][][][] [] [] │',
8
+ '│ [] [] [] [] [] [] [] [] [][] [] [] [] [] │',
9
+ '│ [] [] [] [] [] [] [] [] [] [] [] [] [] [] │',
10
+ '│ [] [][][][] [][][][] [] [] [] [] [] [] [] [][][][] [] │',
11
+ '│ [] [] [] [] [] [] [] [] [] [][] [] [] [] │',
12
+ '│ [] [] [] [] [] [] [] [] [] [] [] [] │',
13
+ '│ [][][][][] [][][][][] [] [] [] [][][] [] [] [][][][][] [] [] │',
14
+ '│ │',
15
+ '├───────────────────────────────────────────────────────────────────────────────────────────┤',
16
+ '│ │',
17
+ '│ [][][][] [][][] [][][][][] [] [][][][][] [] [] [][][][] │',
18
+ '│ [] [] [] [] [] [] [] [] [] [] │',
19
+ '│ [] [] [] [] [] [] [] [] [] [] │',
20
+ '│ [][][][] [][][][][] [] [] [][][][] [] [][][] │',
21
+ '│ [] [] [] [] [] [] [] [] [] │',
22
+ '│ [] [] [] [] [] [] [] [] [] │',
23
+ '│ [][][][] [] [] [][][][][] [][][][][] [][][][][] [] [][][][] │',
24
+ '│ │',
25
+ '╰───────────────────────────────────────────────────────────────────────────────────────────╯',
26
+ ].join('\n')
30
27
 
31
- const info = `
32
- ┌───────────────────────────────────────────────────────────────────────┐
33
- │ 📦 Package: @zervonex/baileys │
34
- │ 🔖 Version: 3.0.1 │
35
- │ ⚡ Status: Production Ready │
36
- ├───────────────────────────────────────────────────────────────────────┤
37
- │ 🚀 Advanced WhatsApp Web API Client │
38
- │ ✨ Interactive Buttons • Products • Events • Media │
39
- │ 🔐 End-to-End Encryption • Multi-Device Support │
40
- │ 📱 Business API • Channels • Status Updates │
41
- ├───────────────────────────────────────────────────────────────────────┤
42
- │ 💡 Built by NexusTech Pro Team │
43
- │ 📚 Docs: github.com/nexustechpro2/baileys │
44
- │ 💬 Support: Join our community for updates & assistance │
45
- └───────────────────────────────────────────────────────────────────────┘
46
- `;
28
+ const info = [
29
+ '╭──────────────────────────────────────────────────────────────╮',
30
+ '│ │',
31
+ '│ ◆ Package › @zervonex/baileys │',
32
+ '│ ◆ Version › 3.0.2 │',
33
+ '│ ◆ Status › Production Ready │',
34
+ '│ │',
35
+ '├──────────────────────────── ◇◆◇ ─────────────────────────────┤',
36
+ '│ │',
37
+ '│ ✦ WhatsApp Web API Client │',
38
+ '│ ✦ Interactive Buttons · Products · Events · Media │',
39
+ '│ ✦ End-to-End Encryption · Multi-Device Support │',
40
+ '│ ✦ Business API · Channels · Status Updates │',
41
+ '│ │',
42
+ '├──────────────────────────── ◇◆◇ ─────────────────────────────┤',
43
+ '│ │',
44
+ '│ ◈ Built by › zervonex Team │',
45
+ '│ ◈ Formerly › @nexustechpro/baileys │',
46
+ '│ ◈ Docs › github.com/nexustechpro2/baileys │',
47
+ '│ ◈ Support › Join our community for updates │',
48
+ '│ │',
49
+ '╰──────────────────────────────────────────────────────────────╯',
50
+ ].join('\n')
47
51
 
48
- // Print banner with gradient
49
- console.log(gradient(['#00D4FF', '#0099FF', '#00D4FF'])(banner));
50
-
51
- // Print info with gradient
52
- console.log(gradient(['#FFD700', '#FF6B6B', '#4ECDC4'])(info));
53
-
54
- // Startup message
55
- console.log(gradient(['#00FF88', '#FFFFFF'])('\n🎯 Initializing Baileys Socket Connection...\n'));
52
+ console.log(gradient(['#00FFFF', '#00BFFF', '#7B2FBE', '#FF6EC7', '#00FFFF'])(banner))
53
+ console.log(gradient(['#FFD700', '#FFA500', '#FF6EC7', '#FFD700'])(info))
54
+ console.log(gradient(['#00FF88', '#FFFFFF'])('\n🎯 Initializing Baileys Socket Connection...\n'))
56
55
 
57
56
  export * from '../WAProto/index.js'
58
57
  export * from './Utils/index.js'
@@ -65,4 +64,4 @@ export * from './WAUSync/index.js'
65
64
  export * from './Socket/index.js'
66
65
  export * from './Builders/index.js'
67
66
  export { makeWASocket }
68
- export default makeWASocket
67
+ export default makeWASocket
package/package.json CHANGED
@@ -2,15 +2,19 @@
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@zervonex/baileys",
4
4
  "type": "module",
5
- "version": "3.0.1",
5
+ "version": "3.0.2",
6
6
  "description": "Advanced WhatsApp Web API built on Baileys — interactive messages, buttons, carousels, products, events, payments, polls, albums, sticker packs and more.",
7
7
  "keywords": [
8
8
  "baileys",
9
9
  "baileys-mod",
10
10
  "baileys-fork",
11
11
  "nexus",
12
- "nexusbot",
12
+ "zervonex",
13
13
  "nexustech",
14
+ "nexustechpro",
15
+ "zervo",
16
+ "zervonex baileys",
17
+ "Zervonex",
14
18
  "zervonex",
15
19
  "baileys-advanced",
16
20
  "whiskeysockets",
@@ -152,7 +156,7 @@
152
156
  "eslint": "^9",
153
157
  "eslint-config-prettier": "^10.1.2",
154
158
  "eslint-plugin-prettier": "^5.4.0",
155
- "jest": "^30.0.5",
159
+ "jest": "^25.0.0",
156
160
  "jimp": "^1.6.0",
157
161
  "jiti": "^2.4.2",
158
162
  "json": "^11.0.0",
@@ -161,10 +165,10 @@
161
165
  "pino-pretty": "^13.1.1",
162
166
  "prettier": "^3.5.3",
163
167
  "protobufjs-cli": "^1.1.3",
164
- "release-it": "^15.10.3",
165
- "ts-jest": "^29.4.0",
168
+ "release-it": "^21.1.1",
169
+ "ts-jest": "^27.0.3",
166
170
  "ts-node": "^10.9.2",
167
- "tsc-esm-fix": "^3.1.2",
171
+ "tsc-esm-fix": "^2.20.27",
168
172
  "tsup": "^8.5.1",
169
173
  "tsx": "^4.20.3",
170
174
  "typedoc": "^0.27.9",
@@ -1,3 +0,0 @@
1
- // ─── Key Store Helpers ─────────────────────────────────────────────────────────
2
- // Single source of truth for blob key names — change here, changes everywhere
3
- export const TC_TOKEN_INDEX_KEY = '__index'