Skip to content

Commit e57cafc

Browse files
committed
feat(passkey-crypto): add @bitgo/passkey-crypto package
Pure cryptographic primitives for WebAuthn PRF-based key derivation: - derivePassword: converts ArrayBuffer PRF result to hex walletPassphrase - deriveEnterpriseSalt: HMAC-SHA256(baseSalt, enterpriseId) for cross-enterprise isolation TICKET: WCN-186
1 parent affc67f commit e57cafc

9 files changed

Lines changed: 266 additions & 3 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require: 'tsx'
2+
timeout: '20000'
3+
reporter: 'min'
4+
reporter-option:
5+
- 'cdn=true'
6+
- 'json=false'
7+
exit: true
8+
spec: ['test/unit/**/*.ts']
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@bitgo/passkey-crypto",
3+
"version": "1.0.0",
4+
"description": "Pure cryptographic primitives for BitGo passkey (WebAuthn PRF) key derivation",
5+
"main": "./dist/src/index.js",
6+
"types": "./dist/src/index.d.ts",
7+
"files": [
8+
"dist"
9+
],
10+
"scripts": {
11+
"build": "yarn tsc --build --incremental --verbose .",
12+
"fmt": "prettier --write .",
13+
"check-fmt": "prettier --check '**/*.{ts,js,json}'",
14+
"clean": "rm -r ./dist",
15+
"lint": "eslint --quiet .",
16+
"prepare": "npm run build",
17+
"test": "npm run unit-test",
18+
"unit-test": "mocha 'test/unit/**/*.ts'"
19+
},
20+
"author": "BitGo SDK Team <sdkteam@bitgo.com>",
21+
"license": "MIT",
22+
"repository": {
23+
"type": "git",
24+
"url": "https://github.com/BitGo/BitGoJS.git",
25+
"directory": "modules/passkey-crypto"
26+
},
27+
"lint-staged": {
28+
"*.{js,ts}": [
29+
"yarn prettier --write",
30+
"yarn eslint --fix"
31+
]
32+
},
33+
"publishConfig": {
34+
"access": "public"
35+
},
36+
"devDependencies": {
37+
"@types/node": "^18.0.0",
38+
"mocha": "^10.0.0",
39+
"ts-node": "^10.0.0",
40+
"typescript": "~5.4.5"
41+
}
42+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { createHmac } from 'crypto';
2+
3+
/**
4+
* Derives an enterprise-scoped salt to prevent cross-enterprise key reuse.
5+
*
6+
* Computes HMAC-SHA256(baseSalt, enterpriseId) as a hex string.
7+
* The baseSalt must always come from the server — never generate it client-side.
8+
*
9+
* @param baseSalt - Server-provided base salt
10+
* @param enterpriseId - Enterprise identifier
11+
* @returns Hex-encoded HMAC-SHA256 digest
12+
*/
13+
export function deriveEnterpriseSalt(baseSalt: string, enterpriseId: string): string {
14+
return createHmac('sha256', baseSalt).update(enterpriseId).digest('hex');
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Derives a wallet passphrase from a WebAuthn PRF result.
3+
*
4+
* The PRF output (ArrayBuffer) is hex-encoded and used directly as the
5+
* walletPassphrase for SJCL-based encryption (bitgo.encrypt).
6+
*
7+
* @param prfResult - Raw PRF output from WebAuthn credential assertion
8+
* @returns Lowercase hex string to use as walletPassphrase
9+
*/
10+
export function derivePassword(prfResult: ArrayBuffer): string {
11+
return Buffer.from(prfResult).toString('hex');
12+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { derivePassword } from './derivePassword';
2+
export { deriveEnterpriseSalt } from './deriveEnterpriseSalt';
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as assert from 'assert';
2+
import { createHmac } from 'crypto';
3+
import { deriveEnterpriseSalt } from '../../src';
4+
5+
describe('deriveEnterpriseSalt', function () {
6+
const BASE_SALT = 'server-provided-base-salt';
7+
const ENTERPRISE_ID = 'ent-abc123';
8+
9+
it('returns a hex string', function () {
10+
const result = deriveEnterpriseSalt(BASE_SALT, ENTERPRISE_ID);
11+
assert.match(result, /^[0-9a-f]+$/);
12+
});
13+
14+
it('returns a 64-character string (SHA-256 = 32 bytes = 64 hex chars)', function () {
15+
const result = deriveEnterpriseSalt(BASE_SALT, ENTERPRISE_ID);
16+
assert.strictEqual(result.length, 64);
17+
});
18+
19+
it('matches a known HMAC-SHA256 test vector', function () {
20+
const expected = createHmac('sha256', BASE_SALT).update(ENTERPRISE_ID).digest('hex');
21+
assert.strictEqual(deriveEnterpriseSalt(BASE_SALT, ENTERPRISE_ID), expected);
22+
});
23+
24+
it('is deterministic — same inputs produce same output', function () {
25+
assert.strictEqual(deriveEnterpriseSalt(BASE_SALT, ENTERPRISE_ID), deriveEnterpriseSalt(BASE_SALT, ENTERPRISE_ID));
26+
});
27+
28+
it('produces different output for different enterprise IDs', function () {
29+
const a = deriveEnterpriseSalt(BASE_SALT, 'ent-aaa');
30+
const b = deriveEnterpriseSalt(BASE_SALT, 'ent-bbb');
31+
assert.notStrictEqual(a, b);
32+
});
33+
34+
it('produces different output for different base salts', function () {
35+
const a = deriveEnterpriseSalt('salt-one', ENTERPRISE_ID);
36+
const b = deriveEnterpriseSalt('salt-two', ENTERPRISE_ID);
37+
assert.notStrictEqual(a, b);
38+
});
39+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as assert from 'assert';
2+
import { derivePassword } from '../../src';
3+
4+
describe('derivePassword', function () {
5+
it('converts an ArrayBuffer of zeros to a hex string of zeros', function () {
6+
const input = new ArrayBuffer(4);
7+
assert.strictEqual(derivePassword(input), '00000000');
8+
});
9+
10+
it('converts known bytes to expected hex', function () {
11+
const input = new Uint8Array([0xde, 0xad, 0xbe, 0xef]).buffer;
12+
assert.strictEqual(derivePassword(input), 'deadbeef');
13+
});
14+
15+
it('returns a lowercase hex string', function () {
16+
const input = new Uint8Array([0xab, 0xcd]).buffer;
17+
const result = derivePassword(input);
18+
assert.strictEqual(result, result.toLowerCase());
19+
});
20+
21+
it('returns a string of length 2x the input byte length', function () {
22+
const input = new ArrayBuffer(32);
23+
assert.strictEqual(derivePassword(input).length, 64);
24+
});
25+
26+
it('produces the same output for the same input (deterministic)', function () {
27+
const input = new Uint8Array([1, 2, 3, 4, 5]).buffer;
28+
assert.strictEqual(derivePassword(input), derivePassword(input));
29+
});
30+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "./dist",
5+
"rootDir": "./",
6+
"strictPropertyInitialization": false,
7+
"esModuleInterop": true,
8+
"typeRoots": ["../../types", "./node_modules/@types", "../../node_modules/@types"]
9+
},
10+
"include": ["src/**/*", "test/**/*"],
11+
"exclude": ["node_modules"]
12+
}

yarn.lock

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,13 @@
15211521
resolved "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.33.1.tgz"
15221522
integrity sha512-UnLHDY6KMmC+UXf3Ufyh+onE19xzEXjT4VZ504Acmk4PXxqyvG4cCPprlKUFnGUX7f0z8Or9MAOHXBx41uHBcg==
15231523

1524+
"@cspotcode/source-map-support@^0.8.0":
1525+
version "0.8.1"
1526+
resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
1527+
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
1528+
dependencies:
1529+
"@jridgewell/trace-mapping" "0.3.9"
1530+
15241531
"@csstools/postcss-cascade-layers@^1.1.1":
15251532
version "1.1.1"
15261533
resolved "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz"
@@ -3182,7 +3189,7 @@
31823189
"@jridgewell/sourcemap-codec" "^1.5.0"
31833190
"@jridgewell/trace-mapping" "^0.3.24"
31843191

3185-
"@jridgewell/resolve-uri@^3.1.0":
3192+
"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0":
31863193
version "3.1.2"
31873194
resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz"
31883195
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
@@ -3195,11 +3202,19 @@
31953202
"@jridgewell/gen-mapping" "^0.3.5"
31963203
"@jridgewell/trace-mapping" "^0.3.25"
31973204

3198-
"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
3205+
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
31993206
version "1.5.5"
32003207
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz"
32013208
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
32023209

3210+
"@jridgewell/trace-mapping@0.3.9":
3211+
version "0.3.9"
3212+
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
3213+
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
3214+
dependencies:
3215+
"@jridgewell/resolve-uri" "^3.0.3"
3216+
"@jridgewell/sourcemap-codec" "^1.4.10"
3217+
32033218
"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28":
32043219
version "0.3.30"
32053220
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz"
@@ -5842,6 +5857,26 @@
58425857
resolved "https://registry.npmjs.org/@tronweb3/google-protobuf/-/google-protobuf-3.21.4.tgz"
58435858
integrity sha512-joxgV4esCdyZ921AprMIG1T7HjkypquhbJ5qJti/priCBJhRE1z9GOxIEMvayxSVSRbMGIoJNE0Knrg3vpwM1w==
58445859

5860+
"@tsconfig/node10@^1.0.7":
5861+
version "1.0.12"
5862+
resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz#be57ceac1e4692b41be9de6be8c32a106636dba4"
5863+
integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==
5864+
5865+
"@tsconfig/node12@^1.0.7":
5866+
version "1.0.11"
5867+
resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
5868+
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
5869+
5870+
"@tsconfig/node14@^1.0.0":
5871+
version "1.0.3"
5872+
resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
5873+
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
5874+
5875+
"@tsconfig/node16@^1.0.2":
5876+
version "1.0.4"
5877+
resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
5878+
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
5879+
58455880
"@tufjs/canonical-json@1.0.0":
58465881
version "1.0.0"
58475882
resolved "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz"
@@ -6290,6 +6325,13 @@
62906325
resolved "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz"
62916326
integrity sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==
62926327

6328+
"@types/node@^18.0.0":
6329+
version "18.19.130"
6330+
resolved "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz#da4c6324793a79defb7a62cba3947ec5add00d59"
6331+
integrity sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==
6332+
dependencies:
6333+
undici-types "~5.26.4"
6334+
62936335
"@types/node@^18.0.4":
62946336
version "18.19.123"
62956337
resolved "https://registry.npmjs.org/@types/node/-/node-18.19.123.tgz"
@@ -7024,6 +7066,13 @@ acorn-walk@^8.0.0, acorn-walk@^8.0.2:
70247066
dependencies:
70257067
acorn "^8.11.0"
70267068

7069+
acorn-walk@^8.1.1:
7070+
version "8.3.5"
7071+
resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz#8a6b8ca8fc5b34685af15dabb44118663c296496"
7072+
integrity sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==
7073+
dependencies:
7074+
acorn "^8.11.0"
7075+
70277076
acorn@7.1.1:
70287077
version "7.1.1"
70297078
resolved "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz"
@@ -7044,6 +7093,11 @@ acorn@^8.0.4, acorn@^8.1.0, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0:
70447093
resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz"
70457094
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
70467095

7096+
acorn@^8.4.1:
7097+
version "8.16.0"
7098+
resolved "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a"
7099+
integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
7100+
70477101
add-stream@^1.0.0:
70487102
version "1.0.0"
70497103
resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz"
@@ -7245,6 +7299,11 @@ are-we-there-yet@^3.0.0:
72457299
delegates "^1.0.0"
72467300
readable-stream "^3.6.0"
72477301

7302+
arg@^4.1.0:
7303+
version "4.1.3"
7304+
resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
7305+
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
7306+
72487307
argparse@^1.0.10, argparse@^1.0.7:
72497308
version "1.0.10"
72507309
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
@@ -9494,6 +9553,11 @@ create-hmac@^1.1.0, create-hmac@^1.1.7:
94949553
safe-buffer "^5.0.1"
94959554
sha.js "^2.4.8"
94969555

9556+
create-require@^1.1.0:
9557+
version "1.1.1"
9558+
resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
9559+
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
9560+
94979561
cross-env@^7.0.3:
94989562
version "7.0.3"
94999563
resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz"
@@ -14817,6 +14881,11 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0:
1481714881
dependencies:
1481814882
semver "^6.0.0"
1481914883

14884+
make-error@^1.1.1:
14885+
version "1.3.6"
14886+
resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
14887+
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
14888+
1482014889
make-fetch-happen@15.0.2, make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.2:
1482114890
version "15.0.2"
1482214891
resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.2.tgz"
@@ -15354,7 +15423,7 @@ mocha@10.6.0:
1535415423
yargs-parser "^20.2.9"
1535515424
yargs-unparser "^2.0.0"
1535615425

15357-
mocha@^10.2.0:
15426+
mocha@^10.0.0, mocha@^10.2.0:
1535815427
version "10.8.2"
1535915428
resolved "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz"
1536015429
integrity sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==
@@ -20124,6 +20193,25 @@ ts-loader@^9.1.2:
2012420193
semver "^7.3.4"
2012520194
source-map "^0.7.4"
2012620195

20196+
ts-node@^10.0.0:
20197+
version "10.9.2"
20198+
resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f"
20199+
integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==
20200+
dependencies:
20201+
"@cspotcode/source-map-support" "^0.8.0"
20202+
"@tsconfig/node10" "^1.0.7"
20203+
"@tsconfig/node12" "^1.0.7"
20204+
"@tsconfig/node14" "^1.0.0"
20205+
"@tsconfig/node16" "^1.0.2"
20206+
acorn "^8.4.1"
20207+
acorn-walk "^8.1.1"
20208+
arg "^4.1.0"
20209+
create-require "^1.1.0"
20210+
diff "^4.0.1"
20211+
make-error "^1.1.1"
20212+
v8-compile-cache-lib "^3.0.1"
20213+
yn "3.1.1"
20214+
2012720215
ts-results@^3.2.1:
2012820216
version "3.3.0"
2012920217
resolved "https://registry.npmjs.org/ts-results/-/ts-results-3.3.0.tgz"
@@ -20421,6 +20509,11 @@ typescript@^4.2.4:
2042120509
resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz"
2042220510
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
2042320511

20512+
typescript@~5.4.5:
20513+
version "5.4.5"
20514+
resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
20515+
integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==
20516+
2042420517
"ua-parser-js@>0.7.30 <0.8.0", ua-parser-js@^0.7.30, ua-parser-js@^1.0.35:
2042520518
version "0.7.41"
2042620519
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz#9f6dee58c389e8afababa62a4a2dc22edb69a452"
@@ -20723,6 +20816,11 @@ uuid@^8.3.2:
2072320816
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
2072420817
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
2072520818

20819+
v8-compile-cache-lib@^3.0.1:
20820+
version "3.0.1"
20821+
resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
20822+
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
20823+
2072620824
v8-compile-cache@^2.0.3:
2072720825
version "2.4.0"
2072820826
resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz"
@@ -21544,6 +21642,11 @@ yeoman-generator@^5.6.1:
2154421642
sort-keys "^4.2.0"
2154521643
text-table "^0.2.0"
2154621644

21645+
yn@3.1.1:
21646+
version "3.1.1"
21647+
resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
21648+
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
21649+
2154721650
yocto-queue@^0.1.0:
2154821651
version "0.1.0"
2154921652
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"

0 commit comments

Comments
 (0)