mirror of
https://github.com/logos-storage/logos-storage-js.git
synced 2026-01-08 08:23:08 +00:00
Merge branch 'master' into chore/generate-types-from-open-api
This commit is contained in:
commit
0a0fed1955
14
README.md
14
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.
|
||||
|
||||
1
examples/basic-auth/.gitignore
vendored
Normal file
1
examples/basic-auth/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
index.bundle.js
|
||||
23
examples/basic-auth/README.md
Normal file
23
examples/basic-auth/README.md
Normal file
@ -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.
|
||||
22
examples/basic-auth/esbuild.js
Normal file
22
examples/basic-auth/esbuild.js
Normal file
@ -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));
|
||||
4
examples/basic-auth/index.html
Normal file
4
examples/basic-auth/index.html
Normal file
@ -0,0 +1,4 @@
|
||||
<html>
|
||||
<script src="./index.bundle.js">
|
||||
</script>
|
||||
</html>
|
||||
19
examples/basic-auth/index.js
Normal file
19
examples/basic-auth/index.js
Normal file
@ -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();
|
||||
@ -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": {
|
||||
18
examples/basic-auth/package.json
Normal file
18
examples/basic-auth/package.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
|
||||
@ -14,6 +14,9 @@ const options = {
|
||||
outfile: "./index.bundle.js",
|
||||
bundle: true,
|
||||
define,
|
||||
logOverride: {
|
||||
"ignored-bare-import": "silent",
|
||||
},
|
||||
};
|
||||
|
||||
build(options).catch(() => process.exit(1));
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@codex-storage/sdk-js": ".."
|
||||
"@codex-storage/sdk-js": "../.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.1",
|
||||
|
||||
@ -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.
|
||||
|
||||
5
examples/upload-node/package-lock.json
generated
5
examples/upload-node/package-lock.json
generated
@ -39,6 +39,9 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"undici": "^7.6.0"
|
||||
}
|
||||
},
|
||||
"../dist": {
|
||||
@ -74,4 +77,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,4 +13,4 @@
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
6
package-lock.json
generated
6
package-lock.json
generated
@ -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 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<SafeValue<string>> {
|
||||
upload(
|
||||
url: string,
|
||||
{ auth }: UploadStategyOptions
|
||||
): Promise<SafeValue<string>> {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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<SafeValue<CodexDataItems>> {
|
||||
const url = this.url + Api.config.prefix + "/data";
|
||||
|
||||
return Fetch.safeJson<CodexDataResponse>(url, { method: "GET" });
|
||||
return Fetch.safeJson<CodexDataResponse>(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<SafeValue<CodexNodeSpace>> {
|
||||
const url = this.url + Api.config.prefix + "/space";
|
||||
|
||||
return Fetch.safeJson<CodexSpaceResponse>(url, { method: "GET" });
|
||||
return Fetch.safeJson<CodexSpaceResponse>(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<SafeValue<Response>> {
|
||||
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<SafeValue<CodexNetworkDownload>> {
|
||||
const url = this.url + Api.config.prefix + `/data/${cid}/network`;
|
||||
|
||||
return Fetch.safeJson<CodexDataNetworkResponse>(url, { method: "POST" });
|
||||
return Fetch.safeJson<CodexDataNetworkResponse>(url, {
|
||||
method: "POST",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +114,10 @@ export class CodexData {
|
||||
async networkDownloadStream(cid: string): Promise<SafeValue<Response>> {
|
||||
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<SafeValue<CodexManifest>> {
|
||||
const url = this.url + Api.config.prefix + `/data/${cid}/network/manifest`;
|
||||
|
||||
return Fetch.safeJson<CodexManifest>(url, { method: "GET" });
|
||||
return Fetch.safeJson<CodexManifest>(url, {
|
||||
method: "GET",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<SafeValue<string>> {
|
||||
const headers: Record<string, string> = {};
|
||||
async upload(
|
||||
url: string,
|
||||
{ auth }: UploadStategyOptions
|
||||
): Promise<SafeValue<string>> {
|
||||
const headers: Record<string, string> = FetchAuthBuilder.build(auth);
|
||||
|
||||
if (this.metadata?.filename) {
|
||||
headers["Content-Disposition"] =
|
||||
|
||||
@ -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<SafeValue<string>>;
|
||||
upload(
|
||||
url: string,
|
||||
options?: UploadStategyOptions
|
||||
): Promise<SafeValue<string>>;
|
||||
abort(): void;
|
||||
}
|
||||
|
||||
@ -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<CodexInfoResponse>(url, {
|
||||
method: "GET",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(() => {
|
||||
|
||||
@ -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<SafeValue<Response>> {
|
||||
const res = await Promises.safe(() => fetch(url, init));
|
||||
|
||||
20
src/index.ts
20
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;
|
||||
}
|
||||
|
||||
@ -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<CodexSlotResponse[]>(url, {
|
||||
method: "GET",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
}
|
||||
|
||||
@ -53,6 +67,7 @@ export class CodexMarketplace {
|
||||
|
||||
return Fetch.safeJson<CodexSlotAgentResponse>(url, {
|
||||
method: "GET",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
}
|
||||
|
||||
@ -84,6 +99,7 @@ export class CodexMarketplace {
|
||||
|
||||
const res = await Fetch.safeJson<CodexAvailabilityResponse>(url, {
|
||||
method: "GET",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
|
||||
if (res.error) {
|
||||
@ -133,6 +149,7 @@ export class CodexMarketplace {
|
||||
|
||||
return Fetch.safeJson<CodexAvailabilityCreateResponse>(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<CodexReservationsResponse>(url, {
|
||||
method: "GET",
|
||||
headers: FetchAuthBuilder.build(this.auth),
|
||||
});
|
||||
}
|
||||
|
||||
@ -216,6 +235,7 @@ export class CodexMarketplace {
|
||||
|
||||
return Fetch.safeJson<CodexPurchaseIdsResponse>(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<CodexPurchaseResponse>(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(),
|
||||
|
||||
@ -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),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -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 () => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { CodexError } from "../async";
|
||||
import { CodexError } from "../errors/errors";
|
||||
import type { SafeValue } from "../values/values";
|
||||
|
||||
export const Promises = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user