@toil/qrcode-rs
Version:
⚡ Fast qrcode-rust bindings for bun.sh
100 lines (82 loc) • 2.44 kB
text/typescript
import path from "node:path";
import { dlopen, FFIType, suffix } from "bun:ffi";
function getPlatform() {
if (process.platform === "win32" && process.arch === "x64") {
return "x86_64-windows";
}
if (process.platform === "linux" && ["arm64", "x64"].includes(process.arch)) {
return process.arch === "arm64" ? "aarch64-linux" : "x86_64-linux";
}
throw new Error("Running on unsupported platform");
}
const libPath = path.join(
__dirname,
"..",
"build",
getPlatform(),
`qrcode_rs.${suffix}`
);
const lib = dlopen(libPath, {
qrcode: {
args: [FFIType.cstring],
returns: FFIType.cstring,
},
qrcode_str: {
args: [FFIType.cstring],
returns: FFIType.cstring,
},
});
const enc = new TextEncoder();
export enum QRCodeError {
/**
* The data is too long to encode into a QR code for the given version
*/
DataTooLong = "data too long",
/**
* The provided version / error correction level combination is invalid
*/
InvalidVersion = "invalid version",
/**
* Some characters in the data cannot be supported by the provided QR code version
*/
UnsupportedCharacterSet = "unsupported character set",
/**
* The provided ECI designator is invalid. A valid designator should be between 0 and 999999.
*/
InvalidEciDesignator = "invalid ECI designator",
/**
* A character not belonging to the character set is found.
*/
InvalidCharacter = "invalid character",
/**
* Custom error with invalid utf8 text
*/
InvalidUtf8Sequence = "invalid UTF-8 sequence",
}
function throwOnError(resultStr: string) {
if (Object.values(QRCodeError).includes(resultStr as QRCodeError)) {
throw new Error(resultStr);
}
if (resultStr.includes("invalid utf-8 sequence")) {
throw new Error(QRCodeError.InvalidUtf8Sequence);
}
return true;
}
export function qrcode(text: string): null | string {
if (!text) {
return null;
}
const result = lib.symbols.qrcode(enc.encode(`${text}\0`));
const resultStr = result.toString();
throwOnError(resultStr);
return `data:image/png;base64,${resultStr}`;
}
export function qrcodeString(text: string) {
if (!text) {
return null;
}
const result = lib.symbols.qrcode_str(enc.encode(`${text}\0`));
const resultStr = result.toString();
throwOnError(resultStr);
return resultStr;
}