From ea2c7d95390812325fdf64c1aa409160f7099f2f Mon Sep 17 00:00:00 2001 From: agadzik Date: Mon, 15 May 2023 20:17:55 -0400 Subject: [PATCH] fix: add package.exports, add broswer implementation --- package.json | 13 ++--- src/{web-random-bytes.ts => index.browser.ts} | 8 +++- src/index.ts | 47 ++----------------- src/node-random-bytes.ts | 4 -- src/uid.ts | 39 +++++++++++++++ tsconfig.json | 1 + 6 files changed, 56 insertions(+), 56 deletions(-) rename src/{web-random-bytes.ts => index.browser.ts} (62%) delete mode 100644 src/node-random-bytes.ts create mode 100644 src/uid.ts diff --git a/package.json b/package.json index bfa8a7a..bbf12e3 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,7 @@ "license": "MIT", "description": "generates a cryptographically strong random uid", "repository": "vercel/uid-promise", - "main": "lib/cjs/index.js", - "module": "lib/esm/index.js", - "types": "lib/cjs/index.d.ts", + "types": "lib/types/index.d.ts", "packageManager": "pnpm@8.5.1", "engines": { "node": ">=18" @@ -14,14 +12,17 @@ "files": [ "lib" ], + "exports": { + "import": "./lib/esm/index.browser.js", + "default": "./lib/cjs/index.js" + }, "scripts": { "build": "pnpm build:cjs && pnpm build:esm", "build:cjs": "tsc", "build:esm": "tsc --module esnext --outDir ./lib/esm && echo '{ \"type\": \"module\" }' > ./lib/esm/package.json", - "test": "pnpm test:cjs && pnpm test:esm && pnpm test:webcrypto", + "test": "pnpm test:cjs && pnpm test:esm", "test:cjs": "pnpm build:cjs && node --test test/test.js", - "test:esm": "pnpm build:esm && node --test test/test-esm.mjs", - "test:webcrypto": "pnpm build:cjs && node --test --experimental-global-webcrypto test/test.js" + "test:esm": "pnpm build:esm && node --test test/test-esm.mjs" }, "devDependencies": { "@types/node": "20.1.3", diff --git a/src/web-random-bytes.ts b/src/index.browser.ts similarity index 62% rename from src/web-random-bytes.ts rename to src/index.browser.ts index 41748e0..a5eeef8 100644 --- a/src/web-random-bytes.ts +++ b/src/index.browser.ts @@ -1,6 +1,8 @@ -import type { RandomBytes } from './types'; +// the file extension is needed for ESM +import type { RandomBytes } from './types.js'; +import { generateUidFunction } from './uid.js'; -export const randomBytes: RandomBytes = (size, callback) => { +const randomBytes: RandomBytes = (size, callback) => { if (size < 0 || size > 65536) { throw new RangeError( 'The value of "size" is out of range. It must be >= 0 && <= 65536. Received ' + @@ -20,3 +22,5 @@ export const randomBytes: RandomBytes = (size, callback) => { return new Uint8Array(); }; + +export const uid = generateUidFunction(randomBytes); diff --git a/src/index.ts b/src/index.ts index cfbcf5e..d0d9141 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,45 +1,4 @@ -// the file extension is needed for ESM -import { UIDCHARS } from './chars.js'; +import { randomBytes } from 'node:crypto'; +import { generateUidFunction } from './uid.js'; -export const uid = (len: number) => - new Promise(async (resolve, reject) => { - if (!Number.isInteger(len)) { - reject( - new TypeError('You must supply a length integer to `uid-promise`.'), - ); - return; - } - - if (len <= 0) { - reject(new Error('You must supply a length integer greater than zero')); - return; - } - - const isWebCryptoFuncDefined = - typeof globalThis.crypto?.getRandomValues === 'function'; - - const randomBytes = isWebCryptoFuncDefined - ? // the file extensions are needed for ESM - await import('./web-random-bytes.js').then((mod) => mod.randomBytes) - : await import('./node-random-bytes.js').then((mod) => mod.randomBytes); - - randomBytes(len, (err, buf) => { - if (err) { - return reject(err); - } - const str = []; - let rand; - for (let i = 0; i < buf.length; i++) { - rand = buf[i]; - while (rand > 248) { - try { - rand = randomBytes(1)[0]; - } catch (err) { - reject(err); - } - } - str.push(UIDCHARS[rand % UIDCHARS.length]); - } - resolve(str.join('')); - }); - }); +export const uid = generateUidFunction(randomBytes); diff --git a/src/node-random-bytes.ts b/src/node-random-bytes.ts deleted file mode 100644 index e0a0ee0..0000000 --- a/src/node-random-bytes.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { RandomBytes } from './types'; -import { randomBytes as nodeRandomBytes } from 'crypto'; - -export const randomBytes: RandomBytes = nodeRandomBytes; diff --git a/src/uid.ts b/src/uid.ts new file mode 100644 index 0000000..45b2e35 --- /dev/null +++ b/src/uid.ts @@ -0,0 +1,39 @@ +// the file extension is needed for ESM +import { UIDCHARS } from './chars.js'; +import type { RandomBytes } from './types.js'; + +export const generateUidFunction = + (randomBytes: RandomBytes) => (len: number) => + new Promise(async (resolve, reject) => { + if (!Number.isInteger(len)) { + reject( + new TypeError('You must supply a length integer to `uid-promise`.'), + ); + return; + } + + if (len <= 0) { + reject(new Error('You must supply a length integer greater than zero')); + return; + } + + randomBytes(len, (err, buf) => { + if (err) { + return reject(err); + } + const str = []; + let rand; + for (let i = 0; i < buf.length; i++) { + rand = buf[i]; + while (rand > 248) { + try { + rand = randomBytes(1)[0]; + } catch (err) { + reject(err); + } + } + str.push(UIDCHARS[rand % UIDCHARS.length]); + } + resolve(str.join('')); + }); + }); diff --git a/tsconfig.json b/tsconfig.json index 3bcbec6..1e7913e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "declaration": true, + "declarationDir": "./lib/types", "esModuleInterop": true, "lib": ["esnext", "DOM"], "module": "commonjs",