diff --git a/README.md b/README.md
index 3488d3d..6629660 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,20 @@ To use a module, you need to use the await syntax. If the module is not loaded y
const marketplace = await codex.marketplace();
```
+### Authentication
+
+You can use basic authentication when creating a new Codex object:
+
+```js
+const codex = new Codex("http://localhost:3000", {
+ auth: {
+ basic: "MY BASIC AUTH SECRET"
+ }
+});
+
+You can obtain your secret using the `btoa` method in the browser or `Buffer.from(string).toString('base64')` in Node.js. The secret is stored in memory only.
+```
+
### Error handling
The SDK provides a type called `SafeValue` for error handling instead of throwing errors. It is inspired by Go's "error as value" concept.
diff --git a/examples/basic-auth/.gitignore b/examples/basic-auth/.gitignore
new file mode 100644
index 0000000..91097d8
--- /dev/null
+++ b/examples/basic-auth/.gitignore
@@ -0,0 +1 @@
+index.bundle.js
\ No newline at end of file
diff --git a/examples/basic-auth/README.md b/examples/basic-auth/README.md
new file mode 100644
index 0000000..c999b21
--- /dev/null
+++ b/examples/basic-auth/README.md
@@ -0,0 +1,23 @@
+# Download example
+
+Small example to show how to download a file in the browser with Codex.
+
+## Install dependencies
+
+```bash
+npm install
+```
+
+## Build the javascript asset
+
+```bash
+CODEX_CID=REPLACE_BY_YOUR_CID npm run build
+```
+
+The response will be displayed as text, so it is better to test with .txt files.
+
+Note: You can define `CODEX_NODE_URL`, default value is "http://localhost:8080".
+
+## Check the results
+
+Open the index.html and open the web console.
diff --git a/examples/basic-auth/esbuild.js b/examples/basic-auth/esbuild.js
new file mode 100644
index 0000000..37b09c6
--- /dev/null
+++ b/examples/basic-auth/esbuild.js
@@ -0,0 +1,22 @@
+const { build } = require("esbuild");
+const define = {};
+
+for (const k in process.env) {
+ define[`process.env.${k}`] = JSON.stringify(process.env[k]);
+}
+
+if (!process.env["CODEX_NODE_URL"]) {
+ define[`process.env.CODEX_NODE_URL`] = '"http://localhost:8080"';
+}
+
+const options = {
+ entryPoints: ["./index.js"],
+ outfile: "./index.bundle.js",
+ bundle: true,
+ define,
+ logOverride: {
+ "ignored-bare-import": "silent",
+ },
+};
+
+build(options).catch(() => process.exit(1));
diff --git a/examples/basic-auth/index.html b/examples/basic-auth/index.html
new file mode 100644
index 0000000..0a494ed
--- /dev/null
+++ b/examples/basic-auth/index.html
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/examples/basic-auth/index.js b/examples/basic-auth/index.js
new file mode 100644
index 0000000..b3d1117
--- /dev/null
+++ b/examples/basic-auth/index.js
@@ -0,0 +1,19 @@
+import { Codex } from "@codex-storage/sdk-js";
+
+async function main() {
+ const codex = new Codex(process.env.CODEX_NODE_URL, {
+ auth: {
+ basic: btoa("admin:SuperSecret123"),
+ },
+ });
+
+ const data = codex.data;
+
+ const cid = process.env.CODEX_CID;
+
+ const result = await data.networkDownloadStream(cid);
+
+ console.info(await result.data.text());
+}
+
+main();
diff --git a/examples/download/package-lock.json b/examples/basic-auth/package-lock.json
similarity index 94%
rename from examples/download/package-lock.json
rename to examples/basic-auth/package-lock.json
index a7d1c79..7701ddd 100644
--- a/examples/download/package-lock.json
+++ b/examples/basic-auth/package-lock.json
@@ -1,24 +1,48 @@
{
- "name": "@codex-storage/sdk-js-download-example",
+ "name": "@codex-storage/sdk-js-basic-auth-example",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "@codex-storage/sdk-js-download-example",
+ "name": "@codex-storage/sdk-js-basic-auth-example",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
- "@codex-storage/sdk-js": ".."
+ "@codex-storage/sdk-js": "../.."
},
"devDependencies": {
"esbuild": "^0.25.1",
"prettier": "^3.5.3"
}
},
- "..": {},
+ "..": {
+ "extraneous": true
+ },
+ "../..": {
+ "name": "@codex-storage/sdk-js",
+ "version": "0.1.0",
+ "license": "MIT",
+ "dependencies": {
+ "undici": "^7.5.0",
+ "valibot": "^0.32.0"
+ },
+ "devDependencies": {
+ "@tsconfig/strictest": "^2.0.5",
+ "@types/node": "^22.13.13",
+ "oas-normalize": "^13.1.2",
+ "openapi-typescript": "^7.6.1",
+ "prettier": "^3.5.3",
+ "tsup": "^8.3.6",
+ "typescript": "^5.8.2",
+ "vitest": "^3.0.9"
+ },
+ "engines": {
+ "node": ">=20.18.1"
+ }
+ },
"node_modules/@codex-storage/sdk-js": {
- "resolved": "..",
+ "resolved": "../..",
"link": true
},
"node_modules/@esbuild/aix-ppc64": {
diff --git a/examples/basic-auth/package.json b/examples/basic-auth/package.json
new file mode 100644
index 0000000..c5b2110
--- /dev/null
+++ b/examples/basic-auth/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@codex-storage/sdk-js-basic-auth-example",
+ "version": "1.0.0",
+ "main": "index.js",
+ "scripts": {
+ "build": "node esbuild.js"
+ },
+ "author": "",
+ "license": "ISC",
+ "description": "",
+ "dependencies": {
+ "@codex-storage/sdk-js": "../.."
+ },
+ "devDependencies": {
+ "esbuild": "^0.25.1",
+ "prettier": "^3.5.3"
+ }
+}
diff --git a/examples/download/README.md b/examples/download/README.md
index 1c13969..c999b21 100644
--- a/examples/download/README.md
+++ b/examples/download/README.md
@@ -11,7 +11,7 @@ npm install
## Build the javascript asset
```bash
-CODEX_CID=REPLACE_BY_YOUR_CIDE npm run build
+CODEX_CID=REPLACE_BY_YOUR_CID npm run build
```
The response will be displayed as text, so it is better to test with .txt files.
diff --git a/examples/download/esbuild.js b/examples/download/esbuild.js
index 93c9831..37b09c6 100644
--- a/examples/download/esbuild.js
+++ b/examples/download/esbuild.js
@@ -14,6 +14,9 @@ const options = {
outfile: "./index.bundle.js",
bundle: true,
define,
+ logOverride: {
+ "ignored-bare-import": "silent",
+ },
};
build(options).catch(() => process.exit(1));
diff --git a/examples/download/package.json b/examples/download/package.json
index 6dcbd6b..1d32f3b 100644
--- a/examples/download/package.json
+++ b/examples/download/package.json
@@ -9,7 +9,7 @@
"license": "ISC",
"description": "",
"dependencies": {
- "@codex-storage/sdk-js": ".."
+ "@codex-storage/sdk-js": "../.."
},
"devDependencies": {
"esbuild": "^0.25.1",
diff --git a/examples/upload-browser/README.md b/examples/upload-browser/README.md
index 1c13969..c999b21 100644
--- a/examples/upload-browser/README.md
+++ b/examples/upload-browser/README.md
@@ -11,7 +11,7 @@ npm install
## Build the javascript asset
```bash
-CODEX_CID=REPLACE_BY_YOUR_CIDE npm run build
+CODEX_CID=REPLACE_BY_YOUR_CID npm run build
```
The response will be displayed as text, so it is better to test with .txt files.
diff --git a/examples/upload-node/package-lock.json b/examples/upload-node/package-lock.json
index ebc2c0a..e3433cb 100644
--- a/examples/upload-node/package-lock.json
+++ b/examples/upload-node/package-lock.json
@@ -39,6 +39,9 @@
},
"engines": {
"node": ">=20.18.1"
+ },
+ "peerDependencies": {
+ "undici": "^7.6.0"
}
},
"../dist": {
@@ -74,4 +77,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/examples/upload-node/package.json b/examples/upload-node/package.json
index 3b05f70..2741a4d 100644
--- a/examples/upload-node/package.json
+++ b/examples/upload-node/package.json
@@ -13,4 +13,4 @@
"devDependencies": {
"prettier": "^3.5.3"
}
-}
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 97e116f..b89356a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,6 +24,9 @@
},
"engines": {
"node": ">=20.18.1"
+ },
+ "peerDependencies": {
+ "undici": "^7.0.0"
}
},
"node_modules/@apidevtools/json-schema-ref-parser": {
@@ -3030,6 +3033,7 @@
"resolved": "https://registry.npmjs.org/undici/-/undici-7.7.0.tgz",
"integrity": "sha512-tZ6+5NBq4KH35rr46XJ2JPFKxfcBlYNaqLF/wyWIO9RMHqqU/gx/CLB1Y2qMcgB8lWw/bKHa7qzspqCN7mUHvA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=20.18.1"
}
@@ -3473,4 +3477,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/data/browser-upload.ts b/src/data/browser-upload.ts
index 8ddf0c5..9470441 100644
--- a/src/data/browser-upload.ts
+++ b/src/data/browser-upload.ts
@@ -1,6 +1,6 @@
import { CodexError } from "../errors/errors";
import type { SafeValue } from "../values/values";
-import type { UploadStategy } from "./types";
+import type { UploadStategy, UploadStategyOptions } from "./types";
export class BrowserUploadStategy implements UploadStategy {
private readonly file: Document | XMLHttpRequestBodyInit;
@@ -22,7 +22,10 @@ export class BrowserUploadStategy implements UploadStategy {
this.metadata = metadata;
}
- download(url: string): Promise> {
+ upload(
+ url: string,
+ { auth }: UploadStategyOptions
+ ): Promise> {
const xhr = new XMLHttpRequest();
this.xhr = xhr;
@@ -42,6 +45,10 @@ export class BrowserUploadStategy implements UploadStategy {
);
}
+ if (auth?.basic) {
+ xhr.setRequestHeader("Authorization", "Basic " + auth.basic);
+ }
+
if (this.metadata?.mimetype) {
xhr.setRequestHeader("Content-Type", this.metadata.mimetype);
}
diff --git a/src/data/data.ts b/src/data/data.ts
index 13c7d7c..d709432 100644
--- a/src/data/data.ts
+++ b/src/data/data.ts
@@ -1,5 +1,9 @@
import { Api } from "../api/config";
-import { Fetch } from "../fetch-safe/fetch-safe";
+import {
+ Fetch,
+ FetchAuthBuilder,
+ type FetchAuth,
+} from "../fetch-safe/fetch-safe";
import type { SafeValue } from "../values/values";
import type {
CodexDataResponse,
@@ -13,11 +17,20 @@ import type {
CodexDataItems,
} from "./types";
+type CodexDataOptions = {
+ auth?: FetchAuth;
+};
+
export class CodexData {
readonly url: string;
+ readonly auth: FetchAuth = {};
- constructor(url: string) {
+ constructor(url: string, options?: CodexDataOptions) {
this.url = url;
+
+ if (options?.auth) {
+ this.auth = options.auth;
+ }
}
/**
@@ -27,7 +40,16 @@ export class CodexData {
cids(): Promise> {
const url = this.url + Api.config.prefix + "/data";
- return Fetch.safeJson(url, { method: "GET" });
+ return Fetch.safeJson(url, {
+ method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
+ }).then((data) => {
+ if (data.error) {
+ return data;
+ }
+
+ return { error: false, data: { content: data.data.content } };
+ });
}
/**
@@ -36,7 +58,10 @@ export class CodexData {
space(): Promise> {
const url = this.url + Api.config.prefix + "/space";
- return Fetch.safeJson(url, { method: "GET" });
+ return Fetch.safeJson(url, {
+ method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
+ });
}
/**
@@ -49,7 +74,7 @@ export class CodexData {
const url = this.url + Api.config.prefix + "/data";
return {
- result: stategy.download(url),
+ result: stategy.upload(url, { auth: this.auth }),
abort: () => {
stategy.abort();
},
@@ -63,7 +88,10 @@ export class CodexData {
async localDownload(cid: string): Promise> {
const url = this.url + Api.config.prefix + "/data/" + cid;
- return Fetch.safe(url, { method: "GET" });
+ return Fetch.safe(url, {
+ method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
+ });
}
/**
@@ -73,7 +101,10 @@ export class CodexData {
async networkDownload(cid: string): Promise> {
const url = this.url + Api.config.prefix + `/data/${cid}/network`;
- return Fetch.safeJson(url, { method: "POST" });
+ return Fetch.safeJson(url, {
+ method: "POST",
+ headers: FetchAuthBuilder.build(this.auth),
+ });
}
/**
@@ -83,7 +114,10 @@ export class CodexData {
async networkDownloadStream(cid: string): Promise> {
const url = this.url + Api.config.prefix + `/data/${cid}/network/stream`;
- return Fetch.safe(url, { method: "GET" });
+ return Fetch.safe(url, {
+ method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
+ });
}
/**
@@ -93,6 +127,9 @@ export class CodexData {
async fetchManifest(cid: string): Promise> {
const url = this.url + Api.config.prefix + `/data/${cid}/network/manifest`;
- return Fetch.safeJson(url, { method: "GET" });
+ return Fetch.safeJson(url, {
+ method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
+ });
}
}
diff --git a/src/data/node-upload.ts b/src/data/node-upload.ts
index 507b5e8..7c262e3 100644
--- a/src/data/node-upload.ts
+++ b/src/data/node-upload.ts
@@ -3,7 +3,8 @@ import { CodexError } from "../errors/errors";
import type { SafeValue } from "../values/values";
import Undici from "undici";
import { type FormData } from "undici";
-import type { UploadStategy } from "./types";
+import type { UploadStategy, UploadStategyOptions } from "./types";
+import { FetchAuthBuilder } from "../fetch-safe/fetch-safe";
export class NodeUploadStategy implements UploadStategy {
private readonly body:
@@ -26,8 +27,11 @@ export class NodeUploadStategy implements UploadStategy {
this.metadata = metadata;
}
- async download(url: string): Promise> {
- const headers: Record = {};
+ async upload(
+ url: string,
+ { auth }: UploadStategyOptions
+ ): Promise> {
+ const headers: Record = FetchAuthBuilder.build(auth);
if (this.metadata?.filename) {
headers["Content-Disposition"] =
diff --git a/src/data/types.ts b/src/data/types.ts
index 973979b..8e105a0 100644
--- a/src/data/types.ts
+++ b/src/data/types.ts
@@ -1,4 +1,5 @@
import type { components, paths } from "../openapi";
+import type { FetchAuth } from "../fetch-safe/fetch-safe";
import type { SafeValue } from "../values/values";
export type CodexDataResponse =
@@ -28,7 +29,14 @@ export type CodexFetchManifestResponse =
export type CodexManifest = CodexFetchManifestResponse;
+export type UploadStategyOptions = {
+ auth?: FetchAuth;
+};
+
export interface UploadStategy {
- download(url: string): Promise>;
+ upload(
+ url: string,
+ options?: UploadStategyOptions
+ ): Promise>;
abort(): void;
}
diff --git a/src/debug/debug.ts b/src/debug/debug.ts
index 66e0c7e..f476ba3 100644
--- a/src/debug/debug.ts
+++ b/src/debug/debug.ts
@@ -1,6 +1,10 @@
import { Api } from "../api/config";
import { CodexError, CodexValibotIssuesMap } from "../errors/errors";
-import { Fetch } from "../fetch-safe/fetch-safe";
+import {
+ Fetch,
+ FetchAuthBuilder,
+ type FetchAuth,
+} from "../fetch-safe/fetch-safe";
import type { SafeValue } from "../values/values";
import {
CodexLogLevelInput,
@@ -10,11 +14,20 @@ import {
} from "./types";
import * as v from "valibot";
+type CodexDebugOptions = {
+ auth?: FetchAuth;
+};
+
export class CodexDebug {
readonly url: string;
+ readonly auth: FetchAuth = {};
- constructor(url: string) {
+ constructor(url: string, options?: CodexDebugOptions) {
this.url = url;
+
+ if (options?.auth) {
+ this.auth = options.auth;
+ }
}
/**
@@ -40,6 +53,7 @@ export class CodexDebug {
return Fetch.safeText(url, {
method: "POST",
+ headers: FetchAuthBuilder.build(this.auth),
body: "",
});
}
@@ -52,6 +66,7 @@ export class CodexDebug {
return Fetch.safeJson(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
}
}
diff --git a/src/fetch-safe/fetch-safe.test.ts b/src/fetch-safe/fetch-safe.test.ts
index 0464cba..5a6484a 100644
--- a/src/fetch-safe/fetch-safe.test.ts
+++ b/src/fetch-safe/fetch-safe.test.ts
@@ -1,6 +1,6 @@
import { afterEach, assert, describe, it, vi } from "vitest";
import { Fetch } from "../fetch-safe/fetch-safe";
-import { CodexError } from "../async";
+import { CodexError } from "../errors/errors";
describe.only("fetch", () => {
afterEach(() => {
diff --git a/src/fetch-safe/fetch-safe.ts b/src/fetch-safe/fetch-safe.ts
index 6cec0c9..0f98871 100644
--- a/src/fetch-safe/fetch-safe.ts
+++ b/src/fetch-safe/fetch-safe.ts
@@ -2,6 +2,21 @@ import { CodexError } from "../errors/errors";
import { Promises } from "../promise-safe/promise-safe";
import { type SafeValue } from "../values/values";
+export type FetchAuth = {
+ basic?: string;
+};
+
+export const FetchAuthBuilder = {
+ build(auth: FetchAuth | undefined) {
+ if (auth?.basic) {
+ return {
+ Authorization: "Basic " + auth.basic,
+ };
+ }
+ return {};
+ },
+};
+
export const Fetch = {
async safe(url: string, init: RequestInit): Promise> {
const res = await Promises.safe(() => fetch(url, init));
diff --git a/src/index.ts b/src/index.ts
index 56cc17a..79b3a8f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -2,6 +2,7 @@ import { CodexData } from "./data/data";
import { CodexNode } from "./node/node";
import { CodexMarketplace } from "./marketplace/marketplace";
import { CodexDebug } from "./debug/debug";
+import type { FetchAuth } from "./fetch-safe/fetch-safe";
export * from "./fetch-safe/fetch-safe";
export * from "./marketplace/types";
@@ -15,19 +16,28 @@ export { CodexData } from "./data/data";
export { CodexNode } from "./node/node";
export { CodexMarketplace } from "./marketplace/marketplace";
+type CodexProps = {
+ auth?: FetchAuth;
+};
+
export class Codex {
readonly url: string;
private _marketplace: CodexMarketplace | null;
private _data: CodexData | null;
private _node: CodexNode | null;
private _debug: CodexDebug | null;
+ private readonly auth: FetchAuth = {};
- constructor(url: string) {
+ constructor(url: string, options?: CodexProps) {
this.url = url;
this._marketplace = null;
this._data = null;
this._node = null;
this._debug = null;
+
+ if (options?.auth) {
+ this.auth = options?.auth;
+ }
}
get marketplace() {
@@ -35,7 +45,7 @@ export class Codex {
return this._marketplace;
}
- this._marketplace = new CodexMarketplace(this.url);
+ this._marketplace = new CodexMarketplace(this.url, { auth: this.auth });
return this._marketplace;
}
@@ -45,7 +55,7 @@ export class Codex {
return this._data;
}
- this._data = new CodexData(this.url);
+ this._data = new CodexData(this.url, { auth: this.auth });
return this._data;
}
@@ -55,7 +65,7 @@ export class Codex {
return this._node;
}
- this._node = new CodexNode(this.url);
+ this._node = new CodexNode(this.url, { auth: this.auth });
return this._node;
}
@@ -65,7 +75,7 @@ export class Codex {
return this._debug;
}
- this._debug = new CodexDebug(this.url);
+ this._debug = new CodexDebug(this.url, { auth: this.auth });
return this._debug;
}
diff --git a/src/marketplace/marketplace.ts b/src/marketplace/marketplace.ts
index c5a4838..917d2d8 100644
--- a/src/marketplace/marketplace.ts
+++ b/src/marketplace/marketplace.ts
@@ -1,7 +1,11 @@
import * as v from "valibot";
import { Api } from "../api/config";
import { CodexError, CodexValibotIssuesMap } from "../errors/errors";
-import { Fetch } from "../fetch-safe/fetch-safe";
+import {
+ Fetch,
+ FetchAuthBuilder,
+ type FetchAuth,
+} from "../fetch-safe/fetch-safe";
import type { SafeValue } from "../values/values";
import {
type CodexAvailabilityResponse,
@@ -27,11 +31,20 @@ import {
CodexCreateStorageRequestInput,
} from "./types";
+type CodexMarketplaceOptions = {
+ auth?: FetchAuth;
+};
+
export class CodexMarketplace {
readonly url: string;
+ readonly auth: FetchAuth = {};
- constructor(url: string) {
+ constructor(url: string, options?: CodexMarketplaceOptions) {
this.url = url;
+
+ if (options?.auth) {
+ this.auth = options.auth;
+ }
}
/**
@@ -42,6 +55,7 @@ export class CodexMarketplace {
return Fetch.safeJson(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
}
@@ -53,6 +67,7 @@ export class CodexMarketplace {
return Fetch.safeJson(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
}
@@ -84,6 +99,7 @@ export class CodexMarketplace {
const res = await Fetch.safeJson(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
if (res.error) {
@@ -133,6 +149,7 @@ export class CodexMarketplace {
return Fetch.safeJson(url, {
method: "POST",
+ headers: FetchAuthBuilder.build(this.auth),
body: JSON.stringify(body),
}).then((result) => {
if (result.error) {
@@ -182,6 +199,7 @@ export class CodexMarketplace {
const res = await Fetch.safe(url, {
method: "PATCH",
+ headers: FetchAuthBuilder.build(this.auth),
body: JSON.stringify(body),
});
@@ -205,6 +223,7 @@ export class CodexMarketplace {
return Fetch.safeJson(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
}
@@ -216,6 +235,7 @@ export class CodexMarketplace {
return Fetch.safeJson(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
}
@@ -288,6 +308,7 @@ export class CodexMarketplace {
this.url + Api.config.prefix + `/storage/purchases/` + purchaseId;
return Fetch.safeJson(url, {
+ headers: FetchAuthBuilder.build(this.auth),
method: "GET",
}).then((res) => {
if (res.error) {
@@ -329,6 +350,7 @@ export class CodexMarketplace {
return Fetch.safeText(url, {
method: "POST",
+ headers: FetchAuthBuilder.build(this.auth),
body: JSON.stringify({
duration: duration,
pricePerBytePerSecond: pricePerBytePerSecond.toString(),
diff --git a/src/node/node.ts b/src/node/node.ts
index ff7f9b9..532152f 100644
--- a/src/node/node.ts
+++ b/src/node/node.ts
@@ -1,5 +1,9 @@
import { Api } from "../api/config";
-import { Fetch } from "../fetch-safe/fetch-safe";
+import {
+ Fetch,
+ FetchAuthBuilder,
+ type FetchAuth,
+} from "../fetch-safe/fetch-safe";
import type { SafeValue } from "../values/values";
import type {
CodexPeerId,
@@ -10,11 +14,20 @@ import type {
CodexSprJsonResponse,
} from "./types";
+type CodexNodeOptions = {
+ auth?: FetchAuth;
+};
+
export class CodexNode {
readonly url: string;
+ readonly auth: FetchAuth = {};
- constructor(url: string) {
+ constructor(url: string, options?: CodexNodeOptions) {
this.url = url;
+
+ if (options?.auth) {
+ this.auth = options.auth;
+ }
}
/**
@@ -32,6 +45,7 @@ export class CodexNode {
return Fetch.safeText(url, {
method: "GET",
+ headers: FetchAuthBuilder.build(this.auth),
});
}
@@ -56,6 +70,7 @@ export class CodexNode {
method: "GET",
headers: {
"Content-Type": "text/plain",
+ ...FetchAuthBuilder.build(this.auth),
},
});
}
@@ -81,6 +96,7 @@ export class CodexNode {
method: "GET",
headers: {
"Content-Type": "text/plain",
+ ...FetchAuthBuilder.build(this.auth),
},
});
}
diff --git a/src/promise-safe/promise-safe.test.ts b/src/promise-safe/promise-safe.test.ts
index bccbdc5..4ce2f14 100644
--- a/src/promise-safe/promise-safe.test.ts
+++ b/src/promise-safe/promise-safe.test.ts
@@ -1,6 +1,6 @@
import { assert, describe, it } from "vitest";
import { Promises } from "./promise-safe";
-import { CodexError } from "../async";
+import { CodexError } from "../errors/errors";
describe("promise safe", () => {
it("returns an error when the promise failed", async () => {
diff --git a/src/promise-safe/promise-safe.ts b/src/promise-safe/promise-safe.ts
index 0a9cb91..4944f18 100644
--- a/src/promise-safe/promise-safe.ts
+++ b/src/promise-safe/promise-safe.ts
@@ -1,4 +1,4 @@
-import { CodexError } from "../async";
+import { CodexError } from "../errors/errors";
import type { SafeValue } from "../values/values";
export const Promises = {