Socket
Socket
Sign inDemoInstall

@fuel-ts/errors

Package Overview
Dependencies
Maintainers
1
Versions
2366
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fuel-ts/errors - npm Package Compare versions

Comparing version 0.56.0 to 0.56.1

2

dist/index.global.js

@@ -26,3 +26,3 @@ "use strict";

FUEL_CORE: "0.20.4",
FUELS: "0.56.0"
FUELS: "0.56.1"
};

@@ -29,0 +29,0 @@ }

"use strict";
(() => {
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported');
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// ../../node_modules/.pnpm/lodash.upperfirst@4.3.1/node_modules/lodash.upperfirst/index.js
var require_lodash = __commonJS({
"../../node_modules/.pnpm/lodash.upperfirst@4.3.1/node_modules/lodash.upperfirst/index.js"(exports, module) {
var INFINITY = 1 / 0;
var symbolTag = "[object Symbol]";
var rsAstralRange = "\\ud800-\\udfff";
var rsComboMarksRange = "\\u0300-\\u036f\\ufe20-\\ufe23";
var rsComboSymbolsRange = "\\u20d0-\\u20f0";
var rsVarRange = "\\ufe0e\\ufe0f";
var rsAstral = "[" + rsAstralRange + "]";
var rsCombo = "[" + rsComboMarksRange + rsComboSymbolsRange + "]";
var rsFitz = "\\ud83c[\\udffb-\\udfff]";
var rsModifier = "(?:" + rsCombo + "|" + rsFitz + ")";
var rsNonAstral = "[^" + rsAstralRange + "]";
var rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}";
var rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]";
var rsZWJ = "\\u200d";
var reOptMod = rsModifier + "?";
var rsOptVar = "[" + rsVarRange + "]?";
var rsOptJoin = "(?:" + rsZWJ + "(?:" + [rsNonAstral, rsRegional, rsSurrPair].join("|") + ")" + rsOptVar + reOptMod + ")*";
var rsSeq = rsOptVar + reOptMod + rsOptJoin;
var rsSymbol = "(?:" + [rsNonAstral + rsCombo + "?", rsCombo, rsRegional, rsSurrPair, rsAstral].join("|") + ")";
var reUnicode = RegExp(rsFitz + "(?=" + rsFitz + ")|" + rsSymbol + rsSeq, "g");
var reHasUnicode = RegExp("[" + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + "]");
var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
var freeSelf = typeof self == "object" && self && self.Object === Object && self;
var root = freeGlobal || freeSelf || Function("return this")();
function asciiToArray(string) {
return string.split("");
}
function hasUnicode(string) {
return reHasUnicode.test(string);
}
function stringToArray(string) {
return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string);
}
function unicodeToArray(string) {
return string.match(reUnicode) || [];
}
var objectProto = Object.prototype;
var objectToString = objectProto.toString;
var Symbol2 = root.Symbol;
var symbolProto = Symbol2 ? Symbol2.prototype : void 0;
var symbolToString = symbolProto ? symbolProto.toString : void 0;
function baseSlice(array, start, end) {
var index = -1, length = array.length;
if (start < 0) {
start = -start > length ? 0 : length + start;
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : end - start >>> 0;
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
function baseToString(value) {
if (typeof value == "string") {
return value;
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : "";
}
var result = value + "";
return result == "0" && 1 / value == -INFINITY ? "-0" : result;
}
function castSlice(array, start, end) {
var length = array.length;
end = end === void 0 ? length : end;
return !start && end >= length ? array : baseSlice(array, start, end);
}
function createCaseFirst(methodName) {
return function(string) {
string = toString(string);
var strSymbols = hasUnicode(string) ? stringToArray(string) : void 0;
var chr = strSymbols ? strSymbols[0] : string.charAt(0);
var trailing = strSymbols ? castSlice(strSymbols, 1).join("") : string.slice(1);
return chr[methodName]() + trailing;
};
}
function isObjectLike(value) {
return !!value && typeof value == "object";
}
function isSymbol(value) {
return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag;
}
function toString(value) {
return value == null ? "" : baseToString(value);
}
var upperFirst2 = createCaseFirst("toUpperCase");
module.exports = upperFirst2;
}
});
// src/test-utils/expect-to-throw-fuel-error.ts
var import_types = __require("util/types");
// ../utils/dist/test-utils.mjs
var import_lodash = __toESM(require_lodash(), 1);
var safeExec = async (lambda) => {
let error;
let result;
try {
result = await lambda();
} catch (_error) {
error = _error;
}
return { error, result };
};
var version = "logger/5.7.0";
var _permanentCensorErrors = false;
var _censorErrors = false;
var LogLevels = { debug: 1, "default": 2, info: 2, warning: 3, error: 4, off: 5 };
var _logLevel = LogLevels["default"];
var _globalLogger = null;
function _checkNormalize() {
try {
const missing = [];
["NFD", "NFC", "NFKD", "NFKC"].forEach((form) => {
try {
if ("test".normalize(form) !== "test") {
throw new Error("bad normalize");
}
;
} catch (error) {
missing.push(form);
}
});
if (missing.length) {
throw new Error("missing " + missing.join(", "));
}
if (String.fromCharCode(233).normalize("NFD") !== String.fromCharCode(101, 769)) {
throw new Error("broken implementation");
}
} catch (error) {
return error.message;
}
return null;
}
var _normalizeError = _checkNormalize();
var LogLevel;
(function(LogLevel2) {
LogLevel2["DEBUG"] = "DEBUG";
LogLevel2["INFO"] = "INFO";
LogLevel2["WARNING"] = "WARNING";
LogLevel2["ERROR"] = "ERROR";
LogLevel2["OFF"] = "OFF";
})(LogLevel || (LogLevel = {}));
var ErrorCode;
(function(ErrorCode22) {
ErrorCode22["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
ErrorCode22["NOT_IMPLEMENTED"] = "NOT_IMPLEMENTED";
ErrorCode22["UNSUPPORTED_OPERATION"] = "UNSUPPORTED_OPERATION";
ErrorCode22["NETWORK_ERROR"] = "NETWORK_ERROR";
ErrorCode22["SERVER_ERROR"] = "SERVER_ERROR";
ErrorCode22["TIMEOUT"] = "TIMEOUT";
ErrorCode22["BUFFER_OVERRUN"] = "BUFFER_OVERRUN";
ErrorCode22["NUMERIC_FAULT"] = "NUMERIC_FAULT";
ErrorCode22["MISSING_NEW"] = "MISSING_NEW";
ErrorCode22["INVALID_ARGUMENT"] = "INVALID_ARGUMENT";
ErrorCode22["MISSING_ARGUMENT"] = "MISSING_ARGUMENT";
ErrorCode22["UNEXPECTED_ARGUMENT"] = "UNEXPECTED_ARGUMENT";
ErrorCode22["CALL_EXCEPTION"] = "CALL_EXCEPTION";
ErrorCode22["INSUFFICIENT_FUNDS"] = "INSUFFICIENT_FUNDS";
ErrorCode22["NONCE_EXPIRED"] = "NONCE_EXPIRED";
ErrorCode22["REPLACEMENT_UNDERPRICED"] = "REPLACEMENT_UNDERPRICED";
ErrorCode22["UNPREDICTABLE_GAS_LIMIT"] = "UNPREDICTABLE_GAS_LIMIT";
ErrorCode22["TRANSACTION_REPLACED"] = "TRANSACTION_REPLACED";
ErrorCode22["ACTION_REJECTED"] = "ACTION_REJECTED";
})(ErrorCode || (ErrorCode = {}));
var HEX = "0123456789abcdef";
var Logger = class {
constructor(version3) {
Object.defineProperty(this, "version", {
enumerable: true,
value: version3,
writable: false
});
}
_log(logLevel, args) {
const level = logLevel.toLowerCase();
if (LogLevels[level] == null) {
this.throwArgumentError("invalid log level name", "logLevel", logLevel);
}
if (_logLevel > LogLevels[level]) {
return;
}
console.log.apply(console, args);
}
debug(...args) {
this._log(Logger.levels.DEBUG, args);
}
info(...args) {
this._log(Logger.levels.INFO, args);
}
warn(...args) {
this._log(Logger.levels.WARNING, args);
}
makeError(message, code, params) {
if (_censorErrors) {
return this.makeError("censored error", code, {});
}
if (!code) {
code = Logger.errors.UNKNOWN_ERROR;
}
if (!params) {
params = {};
}
const messageDetails = [];
Object.keys(params).forEach((key) => {
const value = params[key];
try {
if (value instanceof Uint8Array) {
let hex = "";
for (let i = 0; i < value.length; i++) {
hex += HEX[value[i] >> 4];
hex += HEX[value[i] & 15];
}
messageDetails.push(key + "=Uint8Array(0x" + hex + ")");
} else {
messageDetails.push(key + "=" + JSON.stringify(value));
}
} catch (error2) {
messageDetails.push(key + "=" + JSON.stringify(params[key].toString()));
}
});
messageDetails.push(`code=${code}`);
messageDetails.push(`version=${this.version}`);
const reason = message;
let url = "";
switch (code) {
case ErrorCode.NUMERIC_FAULT: {
url = "NUMERIC_FAULT";
const fault = message;
switch (fault) {
case "overflow":
case "underflow":
case "division-by-zero":
url += "-" + fault;
break;
case "negative-power":
case "negative-width":
url += "-unsupported";
break;
case "unbound-bitwise-result":
url += "-unbound-result";
break;
}
break;
}
case ErrorCode.CALL_EXCEPTION:
case ErrorCode.INSUFFICIENT_FUNDS:
case ErrorCode.MISSING_NEW:
case ErrorCode.NONCE_EXPIRED:
case ErrorCode.REPLACEMENT_UNDERPRICED:
case ErrorCode.TRANSACTION_REPLACED:
case ErrorCode.UNPREDICTABLE_GAS_LIMIT:
url = code;
break;
}
if (url) {
message += " [ See: https://links.ethers.org/v5-errors-" + url + " ]";
}
if (messageDetails.length) {
message += " (" + messageDetails.join(", ") + ")";
}
const error = new Error(message);
error.reason = reason;
error.code = code;
Object.keys(params).forEach(function(key) {
error[key] = params[key];
});
return error;
}
throwError(message, code, params) {
throw this.makeError(message, code, params);
}
throwArgumentError(message, name, value) {
return this.throwError(message, Logger.errors.INVALID_ARGUMENT, {
argument: name,
value
});
}
assert(condition, message, code, params) {
if (!!condition) {
return;
}
this.throwError(message, code, params);
}
assertArgument(condition, message, name, value) {
if (!!condition) {
return;
}
this.throwArgumentError(message, name, value);
}
checkNormalize(message) {
if (message == null) {
message = "platform missing String.prototype.normalize";
}
if (_normalizeError) {
this.throwError("platform missing String.prototype.normalize", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "String.prototype.normalize",
form: _normalizeError
});
}
}
checkSafeUint53(value, message) {
if (typeof value !== "number") {
return;
}
if (message == null) {
message = "value not safe";
}
if (value < 0 || value >= 9007199254740991) {
this.throwError(message, Logger.errors.NUMERIC_FAULT, {
operation: "checkSafeInteger",
fault: "out-of-safe-range",
value
});
}
if (value % 1) {
this.throwError(message, Logger.errors.NUMERIC_FAULT, {
operation: "checkSafeInteger",
fault: "non-integer",
value
});
}
}
checkArgumentCount(count, expectedCount, message) {
if (message) {
message = ": " + message;
} else {
message = "";
}
if (count < expectedCount) {
this.throwError("missing argument" + message, Logger.errors.MISSING_ARGUMENT, {
count,
expectedCount
});
}
if (count > expectedCount) {
this.throwError("too many arguments" + message, Logger.errors.UNEXPECTED_ARGUMENT, {
count,
expectedCount
});
}
}
checkNew(target, kind) {
if (target === Object || target == null) {
this.throwError("missing new", Logger.errors.MISSING_NEW, { name: kind.name });
}
}
checkAbstract(target, kind) {
if (target === kind) {
this.throwError("cannot instantiate abstract class " + JSON.stringify(kind.name) + " directly; use a sub-class", Logger.errors.UNSUPPORTED_OPERATION, { name: target.name, operation: "new" });
} else if (target === Object || target == null) {
this.throwError("missing new", Logger.errors.MISSING_NEW, { name: kind.name });
}
}
static globalLogger() {
if (!_globalLogger) {
_globalLogger = new Logger(version);
}
return _globalLogger;
}
static setCensorship(censorship, permanent) {
if (!censorship && permanent) {
this.globalLogger().throwError("cannot permanently disable censorship", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "setCensorship"
});
}
if (_permanentCensorErrors) {
if (!censorship) {
return;
}
this.globalLogger().throwError("error censorship permanent", Logger.errors.UNSUPPORTED_OPERATION, {
operation: "setCensorship"
});
}
_censorErrors = !!censorship;
_permanentCensorErrors = !!permanent;
}
static setLogLevel(logLevel) {
const level = LogLevels[logLevel.toLowerCase()];
if (level == null) {
Logger.globalLogger().warn("invalid log level - " + logLevel);
return;
}
_logLevel = level;
}
static from(version3) {
return new Logger(version3);
}
};
Logger.errors = ErrorCode;
Logger.levels = LogLevel;
var version2 = "bytes/5.7.0";
var logger = new Logger(version2);
// src/error-codes.ts
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
ErrorCode2["INVALID_BECH32_ADDRESS"] = "invalid-bech32-address";
ErrorCode2["INVALID_URL"] = "invalid-url";
ErrorCode2["INSUFFICIENT_BALANCE"] = "insufficient-balance";
ErrorCode2["PARSE_FAILED"] = "parse-failed";
ErrorCode2["TRANSACTION_FAILED"] = "transaction-failed";
ErrorCode2["INVALID_MULTICALL"] = "invalid-multicall";
return ErrorCode2;
})(ErrorCode || {});
var ErrorCode2 = /* @__PURE__ */ ((ErrorCode3) => {
ErrorCode3["INVALID_BECH32_ADDRESS"] = "invalid-bech32-address";
ErrorCode3["INVALID_URL"] = "invalid-url";
ErrorCode3["INSUFFICIENT_BALANCE"] = "insufficient-balance";
ErrorCode3["PARSE_FAILED"] = "parse-failed";
ErrorCode3["TRANSACTION_FAILED"] = "transaction-failed";
ErrorCode3["INVALID_MULTICALL"] = "invalid-multicall";
return ErrorCode3;
})(ErrorCode2 || {});

@@ -30,3 +446,3 @@ // ../versions/dist/index.mjs

FUEL_CORE: "0.20.4",
FUELS: "0.56.0"
FUELS: "0.56.1"
};

@@ -37,36 +453,27 @@ }

// src/test-utils/expect-to-throw-fuel-error.ts
var errorCodes = Object.values(ErrorCode);
function assertExpectations(thrownError, expectedError) {
if (!errorCodes.includes(thrownError.code)) {
throw new Error("Thrown error code is not a valid FuelError code.");
var codes = Object.values(ErrorCode2);
var expectToThrowFuelError = async (lambda, expectedError) => {
if (!expectedError.code) {
throw new Error("Expected error must contain a code.");
}
if (!errorCodes.includes(expectedError.code)) {
if (!codes.includes(expectedError.code)) {
throw new Error(`Expected error code '${expectedError.code}' is not a valid FuelError code.`);
}
expect(thrownError.name).toEqual("FuelError");
Object.getOwnPropertyNames(expectedError).filter((x) => x !== "stack").forEach((key) => {
expect(thrownError?.[key]).toStrictEqual(expectedError[key]);
});
}
function expectToThrowFuelError(lambda, expectedError) {
if ((0, import_types.isAsyncFunction)(lambda)) {
const promise = lambda();
return promise.then(
() => {
throw new Error("Passed-in lambda didn't throw.");
},
(e) => {
assertExpectations(e, expectedError);
}
const { error: thrownError } = await safeExec(lambda);
if (!thrownError) {
throw new Error(`Passed-in lambda didn't throw.`);
}
const thrownErrorStr = `Thrown error >>> ${thrownError.toString()}`;
if (!thrownError.code) {
throw new Error(`Thrown error must contain a code. ${thrownErrorStr}`);
}
if (!codes.includes(thrownError.code)) {
throw new Error(
`Thrown error code '${thrownError.code}' is not a valid FuelError code. ${thrownErrorStr}`
);
}
try {
lambda();
} catch (e) {
assertExpectations(e, expectedError);
return;
}
throw new Error("Passed-in lambda didn't throw.");
}
expect(thrownError.name).toEqual("FuelError");
expect(thrownError).toMatchObject(expectedError);
};
})();
//# sourceMappingURL=test-utils.global.js.map

@@ -28,3 +28,3 @@ "use strict";

// src/test-utils/expect-to-throw-fuel-error.ts
var import_types = require("util/types");
var import_test_utils = require("@fuel-ts/utils/test-utils");

@@ -46,35 +46,26 @@ // src/error-codes.ts

// src/test-utils/expect-to-throw-fuel-error.ts
var errorCodes = Object.values(ErrorCode);
function assertExpectations(thrownError, expectedError) {
if (!errorCodes.includes(thrownError.code)) {
throw new Error("Thrown error code is not a valid FuelError code.");
var codes = Object.values(ErrorCode);
var expectToThrowFuelError = async (lambda, expectedError) => {
if (!expectedError.code) {
throw new Error("Expected error must contain a code.");
}
if (!errorCodes.includes(expectedError.code)) {
if (!codes.includes(expectedError.code)) {
throw new Error(`Expected error code '${expectedError.code}' is not a valid FuelError code.`);
}
expect(thrownError.name).toEqual("FuelError");
Object.getOwnPropertyNames(expectedError).filter((x) => x !== "stack").forEach((key) => {
expect(thrownError?.[key]).toStrictEqual(expectedError[key]);
});
}
function expectToThrowFuelError(lambda, expectedError) {
if ((0, import_types.isAsyncFunction)(lambda)) {
const promise = lambda();
return promise.then(
() => {
throw new Error("Passed-in lambda didn't throw.");
},
(e) => {
assertExpectations(e, expectedError);
}
const { error: thrownError } = await (0, import_test_utils.safeExec)(lambda);
if (!thrownError) {
throw new Error(`Passed-in lambda didn't throw.`);
}
const thrownErrorStr = `Thrown error >>> ${thrownError.toString()}`;
if (!thrownError.code) {
throw new Error(`Thrown error must contain a code. ${thrownErrorStr}`);
}
if (!codes.includes(thrownError.code)) {
throw new Error(
`Thrown error code '${thrownError.code}' is not a valid FuelError code. ${thrownErrorStr}`
);
}
try {
lambda();
} catch (e) {
assertExpectations(e, expectedError);
return;
}
throw new Error("Passed-in lambda didn't throw.");
}
expect(thrownError.name).toEqual("FuelError");
expect(thrownError).toMatchObject(expectedError);
};
// Annotate the CommonJS export names for ESM import in node:

@@ -81,0 +72,0 @@ 0 && (module.exports = {

import type { FuelError } from '../index';
declare function assertExpectations(thrownError: FuelError, expectedError: FuelError | (Partial<FuelError> & Required<Pick<FuelError, 'code'>>)): void;
export declare function expectToThrowFuelError<Fn extends () => unknown, R extends Promise<void> | void = ReturnType<Fn> extends Promise<unknown> ? Promise<void> : void>(lambda: Fn, expectedError: Parameters<typeof assertExpectations>[1]): R;
type ExpectedFuelError = Partial<FuelError> & Required<Pick<FuelError, 'code'>>;
export declare const expectToThrowFuelError: (lambda: () => unknown, expectedError: ExpectedFuelError) => Promise<void>;
export {};
//# sourceMappingURL=expect-to-throw-fuel-error.d.ts.map
{
"name": "@fuel-ts/errors",
"version": "0.56.0",
"version": "0.56.1",
"description": "Error class and error codes that the fuels-ts library throws",

@@ -33,4 +33,4 @@ "author": "Fuel Labs <contact@fuel.sh> (https://fuel.network/)",

"dependencies": {
"@fuel-ts/utils": "0.56.0",
"@fuel-ts/versions": "0.56.0"
"@fuel-ts/utils": "0.56.1",
"@fuel-ts/versions": "0.56.1"
},

@@ -37,0 +37,0 @@ "scripts": {

@@ -13,3 +13,4 @@ # `@fuel-ts/errors`

- [Internal usage](#internal-usage)
- [Internal usage](#external-usage)
- [Test utilities](#test-utilities)
- [External usage](#external-usage)
- [Contributing](#contributing)

@@ -49,2 +50,28 @@ - [Changelog](#changelog)

### Test Utilities
You can use the `expectToThrowFuelError` test utility when asserting errors.
```ts
// can also be imported from `fuels` when using the umbrella package
import { expectToThrowFuelError } from "@fuel-ts/errors/test-utils";
import { myFn } from "...";
describe('this and that' () => {
const code = FuelError.CODES.INVALID_URL;
it("should throw FuelError", async () => {
const expected = new FuelError(code);
await expectToThrowFuelError(() => myFn(), expected);
});
it("should throw something else", async () => {
const expected = new FuelError(code);
const fn = () => expectToThrowFuelError(() => myFn(), expected)
await expect(fn).rejects.toThrow('Something else');
});
})
```
### External usage

@@ -75,3 +102,3 @@

(function main() {
function main() {
try {

@@ -84,3 +111,3 @@ const p = new Provider("0004:tƨoʜlɒɔol//:qttʜ");

}
})();
);
```

@@ -87,0 +114,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc