Skip to content

Commit 6a67a8a

Browse files
committed
TS: declare Uint8Array<ArrayBuffer> over generic Uint8Array (#20)
And add lint TS rule to enforce declaring `Uint8Array<ArrayBuffer>`. This change is to limit the need to downcast Uint8Array in output when using them with e.g. WebCrypto and Blobs, following an incompatible interface change between ArrayBuffer and ArrayBufferLike (enforced in TS v5.9).
1 parent fd575a3 commit 6a67a8a

File tree

6 files changed

+101
-83
lines changed

6 files changed

+101
-83
lines changed

.eslintrc.cjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ module.exports = {
2222
'@typescript-eslint',
2323
'chai-friendly',
2424
'import',
25-
'unicorn'
25+
'unicorn',
26+
'@protontech/enforce-uint8array-arraybuffer'
2627
],
2728

2829
'settings': {
@@ -139,6 +140,7 @@ module.exports = {
139140
'@typescript-eslint/no-unused-expressions': 0,
140141
'chai-friendly/no-unused-expressions': [2, { 'allowShortCircuit': true }],
141142
'unicorn/switch-case-braces': ['error', 'avoid'],
143+
'@protontech/enforce-uint8array-arraybuffer/enforce-uint8array-arraybuffer': 'error',
142144

143145
// Custom warnings:
144146
'no-console': 1

openpgp.d.ts

Lines changed: 68 additions & 68 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"@openpgp/seek-bzip": "^1.0.5-git",
7272
"@openpgp/tweetnacl": "^1.0.4-2",
7373
"@openpgp/web-stream-tools": "~0.1.3",
74+
"@protontech/eslint-plugin-enforce-uint8array-arraybuffer": "^1.0.0",
7475
"@rollup/plugin-alias": "^5.1.1",
7576
"@rollup/plugin-commonjs": "^28.0.6",
7677
"@rollup/plugin-node-resolve": "^16.0.1",

src/crypto/biginteger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const _0n = BigInt(0);
44
const _1n = BigInt(1);
55

6-
export function uint8ArrayToBigInt(bytes: Uint8Array) {
6+
export function uint8ArrayToBigInt(bytes: Uint8Array<ArrayBuffer>) {
77
const hexAlphabet = '0123456789ABCDEF';
88
let s = '';
99
bytes.forEach(v => {

test/typescript/definitions.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ import {
8484
// Encrypt binary message (unarmored)
8585
const binary = new Uint8Array([1, 2]);
8686
const binaryMessage = await createMessage({ binary });
87-
const encryptedBinary: Uint8Array = await encrypt({ encryptionKeys: publicKeys, message: binaryMessage, format: 'binary' });
87+
const encryptedBinary: Uint8Array<ArrayBuffer> = await encrypt({ encryptionKeys: publicKeys, message: binaryMessage, format: 'binary' });
8888
expect(encryptedBinary).to.be.instanceOf(Uint8Array);
8989

9090
// Decrypt text message (armored)
@@ -96,11 +96,11 @@ import {
9696
// Decrypt binary message (unarmored)
9797
const encryptedBinaryMessage = await readMessage({ binaryMessage: encryptedBinary });
9898
const decryptedBinary = await decrypt({ decryptionKeys: privateKeys, message: encryptedBinaryMessage, format: 'binary' });
99-
const decryptedBinaryData: Uint8Array = decryptedBinary.data;
99+
const decryptedBinaryData: Uint8Array<ArrayBuffer> = decryptedBinary.data;
100100
expect(decryptedBinaryData).to.deep.equal(binary);
101101

102102
// Encrypt message (inspect packets)
103-
const encryptedBinaryObject: Message<Uint8Array> = await encrypt({ encryptionKeys: publicKeys, message: binaryMessage, format: 'object' });
103+
const encryptedBinaryObject: Message<Uint8Array<ArrayBuffer>> = await encrypt({ encryptionKeys: publicKeys, message: binaryMessage, format: 'object' });
104104
expect(encryptedBinaryObject).to.be.instanceOf(Message);
105105
const encryptedTextObject: Message<string> = await encrypt({ encryptionKeys: publicKeys, message: textMessage, format: 'object' });
106106
expect(encryptedTextObject).to.be.instanceOf(Message);
@@ -138,10 +138,10 @@ import {
138138
const textSignedArmor: string = await sign({ signingKeys: privateKeys, message: textMessage });
139139
expect(textSignedArmor).to.include('-----BEGIN PGP MESSAGE-----');
140140
// Sign text message (unarmored)
141-
const textSignedBinary: Uint8Array = await sign({ signingKeys: privateKeys, message: binaryMessage, format: 'binary' });
141+
const textSignedBinary: Uint8Array<ArrayBuffer> = await sign({ signingKeys: privateKeys, message: binaryMessage, format: 'binary' });
142142
expect(textSignedBinary).to.be.instanceOf(Uint8Array);
143143
// Sign text and binary messages (inspect packages)
144-
const binarySignedObject: Message<Uint8Array> = await sign({ signingKeys: privateKeys, message: binaryMessage, format: 'object' });
144+
const binarySignedObject: Message<Uint8Array<ArrayBuffer>> = await sign({ signingKeys: privateKeys, message: binaryMessage, format: 'object' });
145145
expect(binarySignedObject).to.be.instanceOf(Message);
146146
const textSignedObject: Message<string> = await sign({ signingKeys: privateKeys, message: textMessage, format: 'object' });
147147
expect(textSignedObject).to.be.instanceOf(Message);
@@ -164,7 +164,7 @@ import {
164164
// Verify signed binary message (unarmored)
165165
const message = await readMessage({ binaryMessage: textSignedBinary });
166166
const verifiedBinary = await verify({ verificationKeys: publicKeys, message, format: 'binary' });
167-
const verifiedBinaryData: Uint8Array = verifiedBinary.data;
167+
const verifiedBinaryData: Uint8Array<ArrayBuffer> = verifiedBinary.data;
168168
expect(verifiedBinaryData).to.deep.equal(binary);
169169
await verify({ verificationKeys: privateKeys, message, format: 'binary' });
170170

@@ -209,7 +209,7 @@ import {
209209
// @ts-expect-error for passing text stream as binary data
210210
await createMessage({ binary: new WebReadableStream<string>() });
211211
// @ts-expect-error for passing binary stream as text data
212-
await createMessage({ text: new WebReadableStream<Uint8Array>() });
212+
await createMessage({ text: new WebReadableStream<Uint8Array<ArrayBuffer>>() });
213213

214214
// Streaming - encrypt text message (armored output)
215215
try {
@@ -221,19 +221,19 @@ import {
221221
const messageFromWebTextStream = await createMessage({ text: webTextStream });
222222
(await encrypt({ message: messageFromWebTextStream, passwords: 'password', format: 'armored' })) as WebStream<string>;
223223
messageFromWebTextStream.getText() as WebStream<string>;
224-
messageFromWebTextStream.getLiteralData() as WebStream<Uint8Array>;
224+
messageFromWebTextStream.getLiteralData() as WebStream<Uint8Array<ArrayBuffer>>;
225225

226226
// Streaming - encrypt binary message (binary output)
227227
try {
228228
const nodeBinaryStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file'));
229229
const messageFromNodeBinaryStream = await createMessage({ binary: nodeBinaryStream });
230-
(await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeWebStream<Uint8Array>;
230+
(await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeWebStream<Uint8Array<ArrayBuffer>>;
231231
} catch (err) {}
232-
const webBinaryStream = new WebReadableStream<Uint8Array>();
232+
const webBinaryStream = new WebReadableStream<Uint8Array<ArrayBuffer>>();
233233
const messageFromWebBinaryStream = await createMessage({ binary: webBinaryStream });
234-
(await encrypt({ message: messageFromWebBinaryStream, passwords: 'password', format: 'binary' })) as WebStream<Uint8Array>;
234+
(await encrypt({ message: messageFromWebBinaryStream, passwords: 'password', format: 'binary' })) as WebStream<Uint8Array<ArrayBuffer>>;
235235
messageFromWebBinaryStream.getText() as WebStream<string>;
236-
messageFromWebBinaryStream.getLiteralData() as WebStream<Uint8Array>;
236+
messageFromWebBinaryStream.getLiteralData() as WebStream<Uint8Array<ArrayBuffer>>;
237237

238238
console.log('TypeScript definitions are correct');
239239
})().catch(e => {

0 commit comments

Comments
 (0)