Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

axiom-api

Package Overview
Dependencies
Maintainers
1
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

axiom-api - npm Package Compare versions

Comparing version 0.0.48 to 0.1.0

12

build/AxiomAPI.d.ts

@@ -9,11 +9,3 @@ import AxiomObject from "./AxiomObject";

import SignedMessage from "./SignedMessage";
export { AxiomObject, Channel, Database, KeyPair, Node, Peer, Sequence, SignedMessage };
export default class AxiomAPI {
network: string;
verbose: boolean;
constructor(options?: {
network?: string;
verbose?: boolean;
});
createNode(): Node;
}
export { AxiomObject, Channel, Database, KeyPair, Peer, Sequence, SignedMessage };
export default Node;

@@ -16,5 +16,3 @@ "use strict";

exports.KeyPair = KeyPair_1.default;
var NetworkConfig_1 = __importDefault(require("./NetworkConfig"));
var Node_1 = __importDefault(require("./Node"));
exports.Node = Node_1.default;
var Peer_1 = __importDefault(require("./Peer"));

@@ -26,15 +24,3 @@ exports.Peer = Peer_1.default;

exports.SignedMessage = SignedMessage_1.default;
var AxiomAPI = /** @class */ (function () {
function AxiomAPI(options) {
options = options || {};
this.network = options.network || "alpha";
this.verbose = !!options.verbose;
}
AxiomAPI.prototype.createNode = function () {
var config = new NetworkConfig_1.default(this.network);
return new Node_1.default(null, config.bootstrap, this.verbose);
};
return AxiomAPI;
}());
exports.default = AxiomAPI;
exports.default = Node_1.default;
//# sourceMappingURL=AxiomAPI.js.map

6

build/BasicPeer.d.ts
export default interface BasicPeer {
onClose(callback: () => void): void;
onConnect(callback: () => void): void;
onData(callback: (any: any) => void): void;
onError(callback: (Error: any) => void): void;
onSignal(callback: (any: any) => void): void;
onData(callback: (data: any) => void): void;
onError(callback: (error: Error) => void): void;
onSignal(callback: (sig: any) => void): void;
signal(sig: any): void;

@@ -8,0 +8,0 @@ send(data: any): void;

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

var OPTIONAL = {
wrtc: null
wrtc: undefined
};

@@ -12,0 +12,0 @@ if (typeof global === "object") {

export default class Cipher {
static keyFromPassword(password: any, salt: any): any;
static makeIV(): any;
static makeSalt(): any;
static encrypt(password: any, iv: any, salt: any, plaintext: any): any;
static decrypt(password: any, iv: any, salt: any, ciphertext: any): any;
static keyFromPassword(password: string, salt: string): string;
static makeIV(): string;
static makeSalt(): string;
static encrypt(password: string, iv: string, salt: string, plaintext: string): string;
static decrypt(password: string, iv: string, salt: string, ciphertext: string): string;
}
"use strict";
// A wrapper for AES encryption and decryption
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var forge = __importStar(require("node-forge"));
var node_forge_1 = __importDefault(require("node-forge"));
var Cipher = /** @class */ (function () {

@@ -17,11 +13,11 @@ function Cipher() {

var keySize = 32;
return forge.pkcs5.pbkdf2(password, salt, 1000, keySize);
return node_forge_1.default.pkcs5.pbkdf2(password, salt, 1000, keySize);
};
// Returns a new hex-encoded initialization vector
Cipher.makeIV = function () {
return forge.util.bytesToHex(forge.random.getBytes(16));
return node_forge_1.default.util.bytesToHex(node_forge_1.default.random.getBytes(16));
};
// Returns a new hex-encoded salt
Cipher.makeSalt = function () {
return forge.util.bytesToHex(forge.random.getBytes(8));
return node_forge_1.default.util.bytesToHex(node_forge_1.default.random.getBytes(8));
};

@@ -31,7 +27,7 @@ // Encrypts some utf8 plaintext with AES.

Cipher.encrypt = function (password, iv, salt, plaintext) {
iv = forge.util.hexToBytes(iv);
salt = forge.util.hexToBytes(salt);
var input = forge.util.createBuffer(plaintext, "utf8");
iv = node_forge_1.default.util.hexToBytes(iv);
salt = node_forge_1.default.util.hexToBytes(salt);
var input = node_forge_1.default.util.createBuffer(plaintext, "utf8");
var key = Cipher.keyFromPassword(password, salt);
var cipher = forge.cipher.createCipher("AES-CBC", key);
var cipher = node_forge_1.default.cipher.createCipher("AES-CBC", key);
cipher.start({ iv: iv });

@@ -47,8 +43,8 @@ cipher.update(input);

Cipher.decrypt = function (password, iv, salt, ciphertext) {
iv = forge.util.hexToBytes(iv);
salt = forge.util.hexToBytes(salt);
var bytes = forge.util.hexToBytes(ciphertext);
var buffer = forge.util.createBuffer(bytes);
iv = node_forge_1.default.util.hexToBytes(iv);
salt = node_forge_1.default.util.hexToBytes(salt);
var bytes = node_forge_1.default.util.hexToBytes(ciphertext);
var buffer = node_forge_1.default.util.createBuffer(bytes);
var key = Cipher.keyFromPassword(password, salt);
var decipher = forge.cipher.createDecipher("AES-CBC", key);
var decipher = node_forge_1.default.cipher.createDecipher("AES-CBC", key);
decipher.start({ iv: iv });

@@ -58,3 +54,4 @@ decipher.update(buffer);

try {
var answer = decipher.output.toString("utf8");
// Decipher output string conversion always assumes utf-8
var answer = decipher.output.toString();
if (answer == "") {

@@ -61,0 +58,0 @@ return null;

@@ -19,8 +19,8 @@ import AxiomObject from "./AxiomObject";

db: any;
filterer: (AxiomObject: any) => boolean;
filterer: (obj: AxiomObject) => boolean;
callbacks: DatabaseCallback[];
constructor(name: string, channel: Channel, node?: Node, prefix?: string);
setFilter(filterer: (AxiomObject: any) => boolean): void;
applyFilter(filterer: (AxiomObject: any) => boolean): Promise<void>;
useFilter(filterer: (AxiomObject: any) => boolean): Promise<void>;
setFilter(filterer: (obj: AxiomObject) => boolean): void;
applyFilter(filterer: (obj: AxiomObject) => boolean): Promise<void>;
useFilter(filterer: (obj: AxiomObject) => boolean): Promise<void>;
allSignedMessages(): Promise<SignedMessage[]>;

@@ -27,0 +27,0 @@ onMessage(callback: DatabaseCallback): Promise<void>;

@@ -249,3 +249,7 @@ "use strict";

};
// Convert a SignedMessage to a form storable in PouchDB
// Convert a SignedMessage to a form storable in PouchDB.
// Of the top-level fields, most of them are the user-generated data.
// There is also _id, which is the object id, aka
// "owner:objectName".
// There is also metadata, which we reserve the right to add junk to in the future.
// TODO: Throw an error if the message is invalid

@@ -262,4 +266,2 @@ Database.prototype.signedMessageToDocument = function (sm) {

type: sm.message.type,
channel: sm.message.channel,
database: sm.message.database,
signature: sm.signature

@@ -304,4 +306,4 @@ } });

var messageContent = {
channel: doc.metadata.channel,
database: doc.metadata.database,
channel: this.channel.name,
database: this.name,
timestamp: doc.metadata.timestamp,

@@ -308,0 +310,0 @@ name: name

@@ -1,31 +0,33 @@

import Message from "./Message";
declare module "node-forge" {
namespace md {
namespace sha512 {
namespace sha256 {
function create(): md.MessageDigest;
}
}
}
}
export default class KeyPair {
publicKey: Uint8Array;
privateKey: Uint8Array;
constructor(publicKey: any, privateKey: any);
constructor(publicKey: Uint8Array, privateKey: Uint8Array);
inspect(): string;
static fromPrivateKey(priv: any): KeyPair;
static fromPrivateKey(priv: string): KeyPair;
static fromPlain(j: any): KeyPair;
static fromSerialized(s: any): KeyPair;
static fromSerialized(s: string): KeyPair;
static fromRandom(): KeyPair;
static fromSecretPhrase(phrase: any): KeyPair;
static fromSecretPhrase(phrase: string): KeyPair;
plain(): {
public: string;
private: any;
private: string;
};
serialize(): String;
sign(string: any): String;
signOperation(type: any, operation: any): {
operation: any;
type: any;
signature: String;
};
signOperationMessage(opm: any): Message;
static verifySignature(publicKey: any, message: any, signature: any): boolean;
serialize(): string;
sign(s: string): string;
static verifySignature(publicKey: string, message: string, signature: string): boolean;
static isValidPublicKey(key: string): boolean;
static isValidHexString(key: string): boolean;
static decodePublicKey(input: any): Uint8Array;
static encodePublicKey(key: any): string;
static decodePublicKey(input: string): Uint8Array;
static encodePublicKey(key: Uint8Array): string;
getPublicKey(): string;
getPrivateKey(): any;
getPrivateKey(): string;
}

@@ -5,20 +5,2 @@ "use strict";

// a "private key". We try to name things "private key" when possible here.
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -29,7 +11,5 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

var base64_js_1 = require("base64-js");
var nacl = __importStar(require("tweetnacl"));
var forge = __importStar(require("node-forge"));
var tweetnacl_1 = __importDefault(require("tweetnacl"));
var node_forge_1 = require("node-forge");
var text_encoding_shim_1 = require("text-encoding-shim");
var stringify = require("json-stable-stringify");
var Message_1 = __importDefault(require("./Message"));
// Decodes a Uint8Array from a base64 string.

@@ -76,3 +56,3 @@ // Adds = padding at the end, which our library requires but some do not.

}
// Creates a forge sha512/256 hash object from bytes
// Creates a forge sha512/256 message digest from bytes
function forgeHash(bytes) {

@@ -84,3 +64,3 @@ // Convert bytes to the format for bytes that forge wants

}
var hash = forge.md.sha512.sha256.create();
var hash = node_forge_1.md.sha512.sha256.create();
hash.update(s);

@@ -126,6 +106,6 @@ return hash;

var bytes = base64Decode(priv);
var keys = nacl.sign.keyPair.fromSecretKey(bytes);
var keys = tweetnacl_1.default.sign.keyPair.fromSecretKey(bytes);
return new KeyPair(keys.publicKey, keys.secretKey);
};
// The "plain" format is a plain object with 'public' and 'private' keys
// The "plain" format should be a plain object with 'public' and 'private' keys
KeyPair.fromPlain = function (j) {

@@ -151,3 +131,3 @@ var publicString = j.public || j.Public;

KeyPair.fromRandom = function () {
var keys = nacl.sign.keyPair();
var keys = tweetnacl_1.default.sign.keyPair();
return new KeyPair(keys.publicKey, keys.secretKey);

@@ -160,3 +140,3 @@ };

var seed = sha512_256(bytes);
var keys = nacl.sign.keyPair.fromSeed(seed);
var keys = tweetnacl_1.default.sign.keyPair.fromSeed(seed);
return new KeyPair(keys.publicKey, keys.secretKey);

@@ -179,40 +159,7 @@ };

// Signatures are returned in base64 encoding.
KeyPair.prototype.sign = function (string) {
var bytes = new text_encoding_shim_1.TextEncoder("utf-8").encode(string);
var sig = nacl.sign.detached(bytes, this.privateKey);
KeyPair.prototype.sign = function (s) {
var bytes = new text_encoding_shim_1.TextEncoder("utf-8").encode(s);
var sig = tweetnacl_1.default.sign.detached(bytes, this.privateKey);
return base64Encode(sig);
};
// Signs an operation, represented as a plain old object.
// A "signer" field is automatically added.
// TODO: this isn't used, should we remove it?
KeyPair.prototype.signOperation = function (type, operation) {
var op = __assign(__assign({}, operation), { signer: this.getPublicKey() });
var json = stringify(op);
var signed = {
operation: op,
type: type,
signature: this.sign(type + json)
};
return signed;
};
// Signs the individual operations in an operation message
// The "signer" field is added to each op
// Any other fields besides operations are dropped
KeyPair.prototype.signOperationMessage = function (opm) {
if (opm.type != "Operation") {
throw new Error("expected operation message in signOperationMessage");
}
var operations = [];
for (var _i = 0, _a = opm.operations; _i < _a.length; _i++) {
var sop = _a[_i];
var op = __assign({ signer: this.getPublicKey() }, sop.operation);
var signature = this.sign(sop.type + stringify(op));
operations.push({
operation: op,
type: sop.type,
signature: signature
});
}
return new Message_1.default("Operation", { operations: operations });
};
// publicKey and signature are both base64-encoded strings

@@ -225,3 +172,3 @@ // Returns whether the signature is legitimate.

try {
return nacl.sign.detached.verify(msg, sig, key);
return tweetnacl_1.default.sign.detached.verify(msg, sig, key);
}

@@ -228,0 +175,0 @@ catch (e) {

"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -13,7 +6,7 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
var forge = __importStar(require("node-forge"));
var node_forge_1 = require("node-forge");
var KeyPair_1 = __importDefault(require("./KeyPair"));
// Testing that our JavaScript libraries work like our Go libraries
test("KeyPair crypto basics", function () {
var hash = forge.md.sha512.sha256.create();
var hash = node_forge_1.md.sha512.sha256.create();
var sum = hash.digest().getBytes();

@@ -23,4 +16,4 @@ if (sum.charCodeAt(0) != 198) {

}
hash = forge.md.sha512.sha256.create();
hash.update("qq", "utf-8");
hash = node_forge_1.md.sha512.sha256.create();
hash.update("qq", "utf8");
sum = hash.digest().getBytes();

@@ -32,3 +25,3 @@ expect(sum.charCodeAt(0)).toBe(59);

String.fromCharCode(4);
hash = forge.md.sha512.sha256.create();
hash = node_forge_1.md.sha512.sha256.create();
hash.update(bytes);

@@ -35,0 +28,0 @@ sum = hash.digest().getBytes();

export default class Message {
type: string;
_serialized: string;
constructor(type: string, properties?: {});
[key: string]: any;
constructor(type: string, properties?: any);
serialize(): string;
static fromSerialized(serialized: any): any;
static fromSerialized(serialized: string): Message;
}

@@ -6,3 +6,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var KeyPair_1 = __importDefault(require("./KeyPair"));
var Node_1 = __importDefault(require("./Node"));

@@ -33,3 +32,3 @@ var Peer_1 = __importDefault(require("./Peer"));

for (var i = 0; i < bootstrap.length; i++) {
var node = new Node_1.default(KeyPair_1.default.fromRandom(), bootstrap, false);
var node = new Node_1.default({ bootstrap: bootstrap });
answer.push(new MockPeerServer(node));

@@ -36,0 +35,0 @@ }

export default class NetworkConfig {
name: string;
chain: string[];
trackers: string[];
proxies: string[];
bootstrap: string[];
retries: number;
constructor(name: any);
getChain(): any;
getProxy(): any;
constructor(name: string);
}

@@ -7,3 +7,4 @@ "use strict";

// local: the local network on your machine for testing
// alpha: the alpha test network running under alphatest.network
// prod: the production network
// "alpha" is an old name for prod.
var NetworkConfig = /** @class */ (function () {

@@ -13,32 +14,5 @@ function NetworkConfig(name) {

if (name == "local") {
this.chain = [
"http://localhost:8000",
"http://localhost:8001",
"http://localhost:8002",
"http://localhost:8003"
];
this.trackers = ["ws://localhost:4000"];
this.proxies = ["localhost:3000"];
this.bootstrap = ["ws://localhost:3500"];
this.retries = 3;
}
else if (name == "alpha") {
this.chain = [
"http://0.alphatest.network:8000",
"http://1.alphatest.network:8000",
"http://2.alphatest.network:8000",
"http://3.alphatest.network:8000"
];
this.trackers = [
"ws://0.alphatest.network:4000",
"ws://1.alphatest.network:4000",
"ws://2.alphatest.network:4000",
"ws://3.alphatest.network:4000"
];
this.proxies = [
"0.alphatest.network:3000",
"1.alphatest.network:3000",
"2.alphatest.network:3000",
"3.alphatest.network:3000"
];
else if (name == "alpha" || name == "prod") {
this.bootstrap = [

@@ -50,3 +24,2 @@ "wss://0.axiombootstrap.com",

];
this.retries = -1;
}

@@ -57,15 +30,5 @@ else {

}
NetworkConfig.prototype.getChain = function () {
return randomChoice(this.chain);
};
NetworkConfig.prototype.getProxy = function () {
return randomChoice(this.proxies);
};
return NetworkConfig;
}());
exports.default = NetworkConfig;
function randomChoice(list) {
var i = Math.floor(list.length * Math.random());
return list[i];
}
//# sourceMappingURL=NetworkConfig.js.map

@@ -20,4 +20,4 @@ import Channel from "./Channel";

};
nextMessageCallbacks: ((SignedMessage: any) => void)[];
everyMessageCallbacks: ((SignedMessage: any) => void)[];
nextMessageCallbacks: ((sm: SignedMessage) => void)[];
everyMessageCallbacks: ((sm: SignedMessage) => void)[];
destroyed: boolean;

@@ -38,3 +38,8 @@ channelMembers: {

timer: IntervalTimer;
constructor(keyPair: KeyPair, urls: string[], verbose: boolean);
constructor(options?: {
network?: string;
keyPair?: KeyPair;
bootstrap?: string[];
verbose?: boolean;
});
log(...args: any[]): void;

@@ -48,4 +53,4 @@ statusLine(): string;

bootstrap(): void;
onNextMessage(callback: (SignedMessage: any) => void): void;
onEveryMessage(callback: (SignedMessage: any) => void): void;
onNextMessage(callback: (sm: SignedMessage) => void): void;
onEveryMessage(callback: (sm: SignedMessage) => void): void;
waitForMessage(): Promise<SignedMessage>;

@@ -52,0 +57,0 @@ waitUntil(f: () => boolean): Promise<void>;

@@ -54,2 +54,3 @@ "use strict";

var Message_1 = __importDefault(require("./Message"));
var NetworkConfig_1 = __importDefault(require("./NetworkConfig"));
var Peer_1 = __importDefault(require("./Peer"));

@@ -59,13 +60,20 @@ var SignedMessage_1 = __importDefault(require("./SignedMessage"));

// A Node represents a member of the Axiom peer-to-peer network.
// Externally, this object is the entry point to the public-facing API, and
// is typically just named "Axiom".
// See the README in this directory for a description of message formats.
var Node = /** @class */ (function () {
function Node(keyPair, urls, verbose) {
// If bootstrap is provided, it overrides network.
function Node(options) {
var _this = this;
this.keyPair = keyPair;
if (!this.keyPair) {
this.keyPair = KeyPair_1.default.fromRandom();
options = options || {};
this.keyPair = options.keyPair || KeyPair_1.default.fromRandom();
var bootstrap = options.bootstrap;
if (!bootstrap) {
var network = options.network || "prod";
var config = new NetworkConfig_1.default(network);
bootstrap = config.bootstrap;
}
this.pendingByURL = {};
for (var _i = 0, urls_1 = urls; _i < urls_1.length; _i++) {
var url = urls_1[_i];
for (var _i = 0, bootstrap_1 = bootstrap; _i < bootstrap_1.length; _i++) {
var url = bootstrap_1[_i];
this.pendingByURL[url] = null;

@@ -76,3 +84,3 @@ }

this.destroyed = false;
this.verbose = verbose;
this.verbose = !!options.verbose;
this.peers = {};

@@ -79,0 +87,0 @@ this.nextMessageCallbacks = [];

@@ -21,3 +21,3 @@ import BasicPeer from "./BasicPeer";

static intercept: {
[url: string]: (Peer: any) => void;
[url: string]: (p: Peer) => void;
};

@@ -40,3 +40,3 @@ static connectToServer(keyPair: KeyPair, url: string, verbose: boolean): Peer;

onData(callback: (data: any) => void): void;
onError(callback: (Error: any) => void): void;
onError(callback: (e: Error) => void): void;
onClose(callback: () => void): void;

@@ -43,0 +43,0 @@ sendData(data: any): void;

@@ -102,3 +102,5 @@ "use strict";

try {
var signal = JSON.parse(event.data);
// According to TypeScript, at least, there are a bunch of stringlike data
// types we could receive here. In practice I have only seen strings.
var signal = JSON.parse(event.data.toString());
incomingSignals.push(signal);

@@ -105,0 +107,0 @@ }

export default class Sequence<T> {
items: T[];
callbacks: ((T: any) => void)[];
callbacks: ((t: T) => void)[];
constructor();
push(item: T): void;
forEach(callback: (T: any) => void): void;
forEach(callback: (t: T) => void): void;
finish(): void;
}

@@ -0,1 +1,3 @@

import KeyPair from "./KeyPair";
import Message from "./Message";
export default class SignedMessage {

@@ -7,10 +9,10 @@ message: any;

verified: boolean;
constructor({ message, messageString, signer, signature, verified }: {
message: any;
messageString: any;
signer: any;
signature: any;
verified: any;
constructor(args: {
message: Message;
messageString: string;
signer: string;
signature: string;
verified: boolean;
});
static fromSigning(message: any, keyPair: any, signature?: string): SignedMessage;
static fromSigning(message: Message, keyPair: KeyPair, signature?: string): SignedMessage;
serialize(): string;

@@ -17,0 +19,0 @@ verify(): void;

@@ -13,9 +13,8 @@ "use strict";

// signer and signature are base64-encoded.
function SignedMessage(_a) {
var message = _a.message, messageString = _a.messageString, signer = _a.signer, signature = _a.signature, verified = _a.verified;
this.message = message;
this.messageString = messageString;
this.signer = signer;
this.signature = signature;
this.verified = verified;
function SignedMessage(args) {
this.message = args.message;
this.messageString = args.messageString;
this.signer = args.signer;
this.signature = args.signature;
this.verified = args.verified;
}

@@ -22,0 +21,0 @@ // Construct a SignedMessage by signing a Message.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tracking = process.hrtime && process.hrtime.bigint ? true : false;
function sign(a) {
if (a > 0) {
return 1;
}
if (a < 0) {
return -1;
}
return 0;
}
var TimeTracker = /** @class */ (function () {

@@ -43,3 +52,3 @@ function TimeTracker() {

var n2 = _b[0], t2 = _b[1], c2 = _b[2];
return t2 - t1;
return sign(t2 - t1);
});

@@ -46,0 +55,0 @@ for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {

@@ -1,3 +0,2 @@

export declare function sleep(ms: any): Promise<unknown>;
export declare function sleep(ms: number): Promise<unknown>;
export declare function isEmpty(obj: object): boolean;
export declare function makeBucketName(input: any): string;

@@ -15,28 +15,2 @@ "use strict";

exports.isEmpty = isEmpty;
// Makes a validated bucket name from a user-provided one.
// Throws an error if the input is invalid.
function makeBucketName(input) {
var parts = input.split(":");
if (parts.length > 2) {
throw new Error("bucket name has too many parts: " + input);
}
if (parts.length == 0) {
throw new Error('bucket name ("' + input + '") is empty');
}
if (parts.length == 1) {
parts.unshift("www");
}
// Validate the parts. Make sure this regex matches the one in bucket.go
var regex = RegExp("^[-a-zA-Z0-9]+$");
for (var i = 0; i < 2; i++) {
if (i == 0 && parts[0] == "www") {
continue;
}
if (!regex.test(parts[i])) {
throw new Error("bucket name has an invalid part: " + parts[i]);
}
}
return parts.join(":");
}
exports.makeBucketName = makeBucketName;
//# sourceMappingURL=Util.js.map
{
"name": "axiom-api",
"version": "0.0.48",
"version": "0.1.0",
"description": "API for interacting with the Axiom.org platform",

@@ -34,3 +34,10 @@ "repository": {

"devDependencies": {
"@types/base64-js": "^1.2.5",
"@types/jest": "^24.0.18",
"@types/json-stable-stringify": "^1.0.32",
"@types/node-forge": "^0.8.6",
"@types/pouchdb": "^6.4.0",
"@types/pouchdb-adapter-memory": "^6.1.3",
"@types/simple-peer": "^6.1.6",
"@types/ws": "^6.0.3",
"jest": "^24.9.0",

@@ -37,0 +44,0 @@ "pouchdb-adapter-memory": "^7.1.1",

@@ -19,3 +19,2 @@ // AxiomAPI is the public-facing API that developers will use.

KeyPair,
Node,
Peer,

@@ -26,17 +25,2 @@ Sequence,

export default class AxiomAPI {
network: string;
verbose: boolean;
constructor(options?: { network?: string; verbose?: boolean }) {
options = options || {};
this.network = options.network || "alpha";
this.verbose = !!options.verbose;
}
createNode(): Node {
let config = new NetworkConfig(this.network);
return new Node(null, config.bootstrap, this.verbose);
}
}
export default Node;

@@ -8,4 +8,4 @@ // BasicPeer is a small wrapper around the SimplePeer provided by the

// TODO: solve this at compile-time rather than at runtime
let OPTIONAL = {
wrtc: null
let OPTIONAL: { wrtc: any } = {
wrtc: undefined
};

@@ -24,5 +24,5 @@ declare var global: any;

onConnect(callback: () => void): void;
onData(callback: (any) => void): void;
onError(callback: (Error) => void): void;
onSignal(callback: (any) => void): void;
onData(callback: (data: any) => void): void;
onError(callback: (error: Error) => void): void;
onSignal(callback: (sig: any) => void): void;
signal(sig: any): void;

@@ -35,3 +35,3 @@ send(data: any): void;

class WebRTCBasicPeer implements BasicPeer {
_peer: SimplePeer;
_peer: any;

@@ -53,11 +53,11 @@ constructor(initiator: boolean) {

onData(callback: (any) => void) {
onData(callback: (data: any) => void) {
this._peer.on("data", callback);
}
onError(callback: (Error) => void) {
onError(callback: (error: Error) => void) {
this._peer.on("error", callback);
}
onSignal(callback: (any) => void) {
onSignal(callback: (sig: any) => void) {
this._peer.on("signal", callback);

@@ -96,3 +96,3 @@ }

class MockBasicPeer implements BasicPeer {
partner: MockBasicPeer;
partner?: MockBasicPeer;
id: number;

@@ -103,5 +103,5 @@ static allPeers: MockBasicPeer[] = [];

initiator: boolean;
closeCallback: () => void;
connectCallback: () => void;
dataCallback: (any) => void;
closeCallback?: () => void;
connectCallback?: () => void;
dataCallback?: (data: any) => void;

@@ -137,3 +137,3 @@ static clear() {

onData(callback: (any) => void) {
onData(callback: (data: any) => void) {
if (this.dataCallback) {

@@ -145,5 +145,5 @@ throw new Error("multiple dataCallback");

onError(callback: (Error) => void) {}
onError(callback: (error: Error) => void) {}
onSignal(callback: (any) => void) {
onSignal(callback: (sig: any) => void) {
callback(this.id);

@@ -150,0 +150,0 @@ }

// A wrapper for AES encryption and decryption
import * as forge from "node-forge";
import forge from "node-forge";
export default class Cipher {
static keyFromPassword(password, salt) {
static keyFromPassword(password: string, salt: string) {
let keySize = 32;

@@ -12,3 +12,3 @@ return forge.pkcs5.pbkdf2(password, salt, 1000, keySize);

// Returns a new hex-encoded initialization vector
static makeIV() {
static makeIV(): string {
return forge.util.bytesToHex(forge.random.getBytes(16));

@@ -18,3 +18,3 @@ }

// Returns a new hex-encoded salt
static makeSalt() {
static makeSalt(): string {
return forge.util.bytesToHex(forge.random.getBytes(8));

@@ -25,3 +25,8 @@ }

// Returns a hex-encoded string so that we don't need to muck around with bytes.
static encrypt(password, iv, salt, plaintext) {
static encrypt(
password: string,
iv: string,
salt: string,
plaintext: string
): string {
iv = forge.util.hexToBytes(iv);

@@ -43,3 +48,8 @@ salt = forge.util.hexToBytes(salt);

// It might just return garbage if the password is wrong, though.
static decrypt(password, iv, salt, ciphertext) {
static decrypt(
password: string,
iv: string,
salt: string,
ciphertext: string
) {
iv = forge.util.hexToBytes(iv);

@@ -57,3 +67,4 @@ salt = forge.util.hexToBytes(salt);

try {
let answer = decipher.output.toString("utf8");
// Decipher output string conversion always assumes utf-8
let answer = decipher.output.toString();
if (answer == "") {

@@ -60,0 +71,0 @@ return null;

@@ -40,3 +40,3 @@ import PouchDB from "pouchdb";

db: any;
filterer: (AxiomObject) => boolean;
filterer: (obj: AxiomObject) => boolean;

@@ -67,3 +67,3 @@ callbacks: DatabaseCallback[];

// A filter returns true for objects that are to be kept.
setFilter(filterer: (AxiomObject) => boolean): void {
setFilter(filterer: (obj: AxiomObject) => boolean): void {
this.filterer = filterer;

@@ -74,3 +74,3 @@ }

// Returns when we are done filtering.
async applyFilter(filterer: (AxiomObject) => boolean): Promise<void> {
async applyFilter(filterer: (obj: AxiomObject) => boolean): Promise<void> {
let objects = await this.find({ selector: {} });

@@ -82,3 +82,3 @@ let forgettable = objects.filter(x => !filterer(x));

// Applies a filter to both objects already in the database, and new objects.
async useFilter(filterer: (AxiomObject) => boolean): Promise<void> {
async useFilter(filterer: (obj: AxiomObject) => boolean): Promise<void> {
this.setFilter(filterer);

@@ -170,3 +170,7 @@ await this.applyFilter(filterer);

// Convert a SignedMessage to a form storable in PouchDB
// Convert a SignedMessage to a form storable in PouchDB.
// Of the top-level fields, most of them are the user-generated data.
// There is also _id, which is the object id, aka
// "owner:objectName".
// There is also metadata, which we reserve the right to add junk to in the future.
// TODO: Throw an error if the message is invalid

@@ -188,4 +192,2 @@ signedMessageToDocument(sm: SignedMessage): any {

type: sm.message.type,
channel: sm.message.channel,
database: sm.message.database,
signature: sm.signature

@@ -236,4 +238,4 @@ }

let messageContent: any = {
channel: doc.metadata.channel,
database: doc.metadata.database,
channel: this.channel.name,
database: this.name,
timestamp: doc.metadata.timestamp,

@@ -280,3 +282,3 @@ name

}
let data = {};
let data: any = {};
for (let key in doc) {

@@ -283,0 +285,0 @@ if (!key.startsWith("_") && key !== "metadata") {

@@ -1,2 +0,2 @@

import * as forge from "node-forge";
import { md } from "node-forge";

@@ -7,3 +7,3 @@ import KeyPair from "./KeyPair";

test("KeyPair crypto basics", () => {
let hash = forge.md.sha512.sha256.create();
let hash = md.sha512.sha256.create();
let sum = hash.digest().getBytes();

@@ -14,4 +14,4 @@ if (sum.charCodeAt(0) != 198) {

hash = forge.md.sha512.sha256.create();
hash.update("qq", "utf-8");
hash = md.sha512.sha256.create();
hash.update("qq", "utf8");
sum = hash.digest().getBytes();

@@ -25,3 +25,3 @@ expect(sum.charCodeAt(0)).toBe(59);

String.fromCharCode(4);
hash = forge.md.sha512.sha256.create();
hash = md.sha512.sha256.create();
hash.update(bytes);

@@ -28,0 +28,0 @@ sum = hash.digest().getBytes();

@@ -7,4 +7,4 @@ // An ed25519 keypair. Designed to be parallel to the Go implementation.

import * as nacl from "tweetnacl";
import * as forge from "node-forge";
import nacl from "tweetnacl";
import { md } from "node-forge";
import { TextEncoder } from "text-encoding-shim";

@@ -15,5 +15,14 @@ import stringify = require("json-stable-stringify");

// node-forge is missing a typescript definition for sha512/256
declare module "node-forge" {
namespace md {
namespace sha512 {
namespace sha256 { function create(): md.MessageDigest; }
}
}
}
// Decodes a Uint8Array from a base64 string.
// Adds = padding at the end, which our library requires but some do not.
function base64Decode(s) {
function base64Decode(s: string) {
while (s.length % 4 != 0) {

@@ -27,3 +36,3 @@ s += "=";

// Removes any = padding at the end.
function base64Encode(bytes) {
function base64Encode(bytes: Uint8Array): string {
let padded = fromByteArray(bytes);

@@ -34,3 +43,3 @@ return padded.replace(/=*$/, "");

// Decodes a Uint8Array from a hex string.
function hexDecode(s) {
function hexDecode(s: string): Uint8Array {
if (s.length % 2 != 0) {

@@ -55,3 +64,3 @@ throw new Error("hex-encoded byte arrays should be even length");

// Shorten a string where the inside doesn't matter, typically some key for display
function shorten(s) {
function shorten(s: string): string {
return s.slice(0, 6) + "..." + s.slice(-4);

@@ -61,3 +70,3 @@ }

// Encodes a Uint8Array into a hex string.
function hexEncode(bytes: Uint8Array) {
function hexEncode(bytes: Uint8Array): string {
return Array.from(bytes)

@@ -68,4 +77,4 @@ .map(byte => byte.toString(16).padStart(2, "0"))

// Creates a forge sha512/256 hash object from bytes
function forgeHash(bytes) {
// Creates a forge sha512/256 message digest from bytes
function forgeHash(bytes: Uint8Array) {
// Convert bytes to the format for bytes that forge wants

@@ -76,3 +85,3 @@ let s = "";

}
let hash = forge.md.sha512.sha256.create();
let hash = md.sha512.sha256.create();
hash.update(s);

@@ -83,3 +92,3 @@ return hash;

// Returns a hex checksum from a Uint8array public key.
function hexChecksum(bytes) {
function hexChecksum(bytes: Uint8Array) {
let hash = forgeHash(bytes);

@@ -91,3 +100,3 @@ let digest = hash.digest();

// Returns a Uint8Array sha512_256 hash from a Uint8Array input.
function sha512_256(inputBytes) {
function sha512_256(inputBytes: Uint8Array) {
let hash = forgeHash(inputBytes);

@@ -106,3 +115,3 @@ let byteString = hash.digest().bytes();

constructor(publicKey, privateKey) {
constructor(publicKey: Uint8Array, privateKey: Uint8Array) {
this.publicKey = publicKey;

@@ -134,3 +143,3 @@ this.privateKey = privateKey;

// Throws an error if priv is not a valid private key.
static fromPrivateKey(priv) {
static fromPrivateKey(priv: string) {
let bytes = base64Decode(priv);

@@ -141,4 +150,4 @@ let keys = nacl.sign.keyPair.fromSecretKey(bytes);

// The "plain" format is a plain object with 'public' and 'private' keys
static fromPlain(j) {
// The "plain" format should be a plain object with 'public' and 'private' keys
static fromPlain(j: any) {
let publicString = j.public || j.Public;

@@ -158,3 +167,3 @@ let privateString = j.private || j.Private;

// The input format is a serialized JSON string with 'public' and 'private' keys
static fromSerialized(s) {
static fromSerialized(s: string) {
let j = JSON.parse(s);

@@ -165,3 +174,3 @@ return KeyPair.fromPlain(j);

// Generates a keypair randomly
static fromRandom() {
static fromRandom(): KeyPair {
let keys = nacl.sign.keyPair();

@@ -172,3 +181,3 @@ return new KeyPair(keys.publicKey, keys.secretKey);

// Generates a keypair from a secret phrase
static fromSecretPhrase(phrase) {
static fromSecretPhrase(phrase: string): KeyPair {
// Hash the phrase for the ed25519 entropy seed bytes

@@ -190,3 +199,3 @@ let bytes = new TextEncoder("utf-8").encode(phrase);

// serialize() returns a serialized JSON string
serialize(): String {
serialize(): string {
let j = this.plain();

@@ -200,4 +209,4 @@

// Signatures are returned in base64 encoding.
sign(string): String {
let bytes = new TextEncoder("utf-8").encode(string);
sign(s: string): string {
let bytes = new TextEncoder("utf-8").encode(s);
let sig = nacl.sign.detached(bytes, this.privateKey);

@@ -207,47 +216,9 @@ return base64Encode(sig);

// Signs an operation, represented as a plain old object.
// A "signer" field is automatically added.
// TODO: this isn't used, should we remove it?
signOperation(type, operation) {
let op = {
...operation,
signer: this.getPublicKey()
};
let json = stringify(op);
let signed = {
operation: op,
type: type,
signature: this.sign(type + json)
};
return signed;
}
// Signs the individual operations in an operation message
// The "signer" field is added to each op
// Any other fields besides operations are dropped
signOperationMessage(opm) {
if (opm.type != "Operation") {
throw new Error("expected operation message in signOperationMessage");
}
let operations = [];
for (let sop of opm.operations) {
let op = {
signer: this.getPublicKey(),
...sop.operation
};
let signature = this.sign(sop.type + stringify(op));
operations.push({
operation: op,
type: sop.type,
signature
});
}
return new Message("Operation", { operations });
}
// publicKey and signature are both base64-encoded strings
// Returns whether the signature is legitimate.
static verifySignature(publicKey, message, signature) {
static verifySignature(
publicKey: string,
message: string,
signature: string
): boolean {
let key = KeyPair.decodePublicKey(publicKey);

@@ -282,3 +253,3 @@ let msg = new TextEncoder("utf-8").encode(message);

// Throws an error if the input format is not valid.
static decodePublicKey(input) {
static decodePublicKey(input: string) {
if (input.length != 70) {

@@ -307,3 +278,3 @@ throw new Error("public key " + input + " should be 70 characters long");

// The checksum is added at the end
static encodePublicKey(key) {
static encodePublicKey(key: Uint8Array): string {
if (key.length != 32) {

@@ -316,3 +287,3 @@ throw new Error("public keys should be 32 bytes long");

// Returns the public key in hex format
getPublicKey() {
getPublicKey(): string {
return KeyPair.encodePublicKey(this.publicKey);

@@ -322,5 +293,5 @@ }

// Returns the private key in base64 format
getPrivateKey() {
getPrivateKey(): string {
return base64Encode(this.privateKey);
}
}

@@ -7,4 +7,5 @@ import stringify = require("json-stable-stringify");

_serialized: string;
[key: string]: any;
constructor(type: string, properties = {}) {
constructor(type: string, properties: any = {}) {
this.type = type;

@@ -24,3 +25,3 @@ this._serialized = stringify({

static fromSerialized(serialized): any {
static fromSerialized(serialized: string): Message {
let { type, message } = JSON.parse(serialized);

@@ -27,0 +28,0 @@ return new Message(type, message);

@@ -25,3 +25,3 @@ import KeyPair from "./KeyPair";

for (let i = 0; i < bootstrap.length; i++) {
let node = new Node(KeyPair.fromRandom(), bootstrap, false);
let node = new Node({ bootstrap });
answer.push(new MockPeerServer(node));

@@ -28,0 +28,0 @@ }

@@ -5,45 +5,13 @@ // A NetworkConfig object specifies how to connect to a particular network.

// local: the local network on your machine for testing
// alpha: the alpha test network running under alphatest.network
// prod: the production network
// "alpha" is an old name for prod.
export default class NetworkConfig {
name: string;
chain: string[];
trackers: string[];
proxies: string[];
bootstrap: string[];
// A negative number means no limit
retries: number;
constructor(name) {
constructor(name: string) {
this.name = name;
if (name == "local") {
this.chain = [
"http://localhost:8000",
"http://localhost:8001",
"http://localhost:8002",
"http://localhost:8003"
];
this.trackers = ["ws://localhost:4000"];
this.proxies = ["localhost:3000"];
this.bootstrap = ["ws://localhost:3500"];
this.retries = 3;
} else if (name == "alpha") {
this.chain = [
"http://0.alphatest.network:8000",
"http://1.alphatest.network:8000",
"http://2.alphatest.network:8000",
"http://3.alphatest.network:8000"
];
this.trackers = [
"ws://0.alphatest.network:4000",
"ws://1.alphatest.network:4000",
"ws://2.alphatest.network:4000",
"ws://3.alphatest.network:4000"
];
this.proxies = [
"0.alphatest.network:3000",
"1.alphatest.network:3000",
"2.alphatest.network:3000",
"3.alphatest.network:3000"
];
} else if (name == "alpha" || name == "prod") {
this.bootstrap = [

@@ -55,3 +23,2 @@ "wss://0.axiombootstrap.com",

];
this.retries = -1;
} else {

@@ -61,15 +28,2 @@ throw new Error("unrecognized network config name: " + name);

}
getChain() {
return randomChoice(this.chain);
}
getProxy() {
return randomChoice(this.proxies);
}
}
function randomChoice(list) {
let i = Math.floor(list.length * Math.random());
return list[i];
}

@@ -6,2 +6,3 @@ import Channel from "./Channel";

import Message from "./Message";
import NetworkConfig from "./NetworkConfig";
import Peer from "./Peer";

@@ -13,2 +14,4 @@ import SignedMessage from "./SignedMessage";

// A Node represents a member of the Axiom peer-to-peer network.
// Externally, this object is the entry point to the public-facing API, and
// is typically just named "Axiom".
// See the README in this directory for a description of message formats.

@@ -36,6 +39,6 @@ export default class Node {

// Callbacks that will run on the next message received
nextMessageCallbacks: ((SignedMessage) => void)[];
nextMessageCallbacks: ((sm: SignedMessage) => void)[];
// Callbacks that will run on every message received
everyMessageCallbacks: ((SignedMessage) => void)[];
everyMessageCallbacks: ((sm: SignedMessage) => void)[];

@@ -64,10 +67,22 @@ // Whether this Node has been destroyed

constructor(keyPair: KeyPair, urls: string[], verbose: boolean) {
this.keyPair = keyPair;
if (!this.keyPair) {
this.keyPair = KeyPair.fromRandom();
// If bootstrap is provided, it overrides network.
constructor(options?: {
network?: string;
keyPair?: KeyPair;
bootstrap?: string[];
verbose?: boolean;
}) {
options = options || {};
this.keyPair = options.keyPair || KeyPair.fromRandom();
let bootstrap = options.bootstrap;
if (!bootstrap) {
let network = options.network || "prod";
let config = new NetworkConfig(network);
bootstrap = config.bootstrap;
}
this.pendingByURL = {};
for (let url of urls) {
for (let url of bootstrap) {
this.pendingByURL[url] = null;

@@ -81,3 +96,3 @@ }

this.destroyed = false;
this.verbose = verbose;
this.verbose = !!options.verbose;
this.peers = {};

@@ -100,3 +115,3 @@ this.nextMessageCallbacks = [];

log(...args) {
log(...args: any[]) {
if (this.verbose) {

@@ -193,7 +208,7 @@ console.log(`${this.keyPair.getPublicKey().slice(0, 6)}:`, ...args);

onNextMessage(callback: (SignedMessage) => void) {
onNextMessage(callback: (sm: SignedMessage) => void) {
this.nextMessageCallbacks.push(callback);
}
onEveryMessage(callback: (SignedMessage) => void) {
onEveryMessage(callback: (sm: SignedMessage) => void) {
this.everyMessageCallbacks.push(callback);

@@ -200,0 +215,0 @@ }

@@ -54,3 +54,3 @@ import WebSocket = require("isomorphic-ws");

// Server URLs to intercept with a handler function
static intercept: { [url: string]: (Peer) => void } = {};
static intercept: { [url: string]: (p: Peer) => void } = {};

@@ -87,3 +87,5 @@ // Creates a Peer by connecting to a PeerServer.

try {
let signal = JSON.parse(event.data);
// According to TypeScript, at least, there are a bunch of stringlike data
// types we could receive here. In practice I have only seen strings.
let signal = JSON.parse(event.data.toString());
incomingSignals.push(signal);

@@ -182,3 +184,3 @@ } catch (e) {

log(...args) {
log(...args: any[]) {
if (this.verbose) {

@@ -197,3 +199,3 @@ console.log(...args);

onError(callback: (Error) => void) {
onError(callback: (e: Error) => void) {
this._peer.onError(callback);

@@ -200,0 +202,0 @@ }

@@ -6,3 +6,3 @@ // A Sequence is like a list that can be asynchronously populated.

items: T[];
callbacks: ((T) => void)[];
callbacks: ((t: T) => void)[];

@@ -24,3 +24,3 @@ constructor() {

forEach(callback: (T) => void) {
forEach(callback: (t: T) => void) {
for (let item of this.items) {

@@ -27,0 +27,0 @@ callback(item);

@@ -15,12 +15,22 @@ import KeyPair from "./KeyPair";

// signer and signature are base64-encoded.
constructor({ message, messageString, signer, signature, verified }) {
this.message = message;
this.messageString = messageString;
this.signer = signer;
this.signature = signature;
this.verified = verified;
constructor(args: {
message: Message;
messageString: string;
signer: string;
signature: string;
verified: boolean;
}) {
this.message = args.message;
this.messageString = args.messageString;
this.signer = args.signer;
this.signature = args.signature;
this.verified = args.verified;
}
// Construct a SignedMessage by signing a Message.
static fromSigning(message, keyPair, signature?: string) {
static fromSigning(
message: Message,
keyPair: KeyPair,
signature?: string
): SignedMessage {
if (!message) {

@@ -48,7 +58,7 @@ throw new Error("cannot sign a falsy message");

serialize() {
serialize(): string {
return "e:" + this.signer + ":" + this.signature + ":" + this.messageString;
}
verify() {
verify(): void {
if (this.verified) {

@@ -77,3 +87,3 @@ return;

// Returns null if the serialization is just an "ok"
static fromSerialized(serialized, skipVerify: boolean) {
static fromSerialized(serialized: any, skipVerify: boolean): SignedMessage {
let s = typeof serialized === "string" ? serialized : serialized.toString();

@@ -80,0 +90,0 @@

@@ -6,2 +6,12 @@ declare var process: any;

function sign(a: bigint): number {
if (a > 0) {
return 1;
}
if (a < 0) {
return -1;
}
return 0;
}
export default class TimeTracker {

@@ -40,3 +50,3 @@ static nanoseconds: { [name: string]: bigint } = {};

static show() {
let items = [];
let items: [string, bigint, number][] = [];
for (let name in TimeTracker.nanoseconds) {

@@ -49,3 +59,3 @@ items.push([

}
items.sort(([n1, t1, c1], [n2, t2, c2]) => t2 - t1);
items.sort(([n1, t1, c1], [n2, t2, c2]) => sign(t2 - t1));
for (let [name, total, calls] of items) {

@@ -52,0 +62,0 @@ console.log(

// Utility functions
export function sleep(ms) {
export function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));

@@ -13,29 +13,1 @@ }

}
// Makes a validated bucket name from a user-provided one.
// Throws an error if the input is invalid.
export function makeBucketName(input): string {
let parts = input.split(":");
if (parts.length > 2) {
throw new Error("bucket name has too many parts: " + input);
}
if (parts.length == 0) {
throw new Error('bucket name ("' + input + '") is empty');
}
if (parts.length == 1) {
parts.unshift("www");
}
// Validate the parts. Make sure this regex matches the one in bucket.go
let regex = RegExp("^[-a-zA-Z0-9]+$");
for (let i = 0; i < 2; i++) {
if (i == 0 && parts[0] == "www") {
continue;
}
if (!regex.test(parts[i])) {
throw new Error("bucket name has an invalid part: " + parts[i]);
}
}
return parts.join(":");
}

@@ -8,2 +8,3 @@ {

"lib": [ "es2017", "dom" ],
"noImplicitAny": true,
"types": [

@@ -10,0 +11,0 @@ "jest",

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

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

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