From b9bb4722932d07597a25d2305ba78d67b0b38fa6 Mon Sep 17 00:00:00 2001
From: erhant
Date: Fri, 23 Feb 2024 13:47:38 +0300
Subject: [PATCH] Tests (#19)
* setup for tests
* fetch small fix, more test setups
* todo tests within docker
* added `fetch` and `pull` test flows
* bump version
---
README.md | 6 +-
jest.config.ts | 22 ++++++
package.json | 37 +++++++--
src/cli.ts | 153 ++++++++++++++++++++++++++++++++++++
src/commands/fetch.ts | 16 +++-
src/common/download.ts | 24 +++---
src/common/index.ts | 1 -
src/configurations/index.ts | 5 +-
src/constants/index.ts | 57 +++++++++-----
src/index.ts | 144 +--------------------------------
tests/common/index.ts | 34 ++++++++
tests/config.test.ts | 28 +++++++
tests/fetch.test.ts | 56 +++++++++++++
tests/index.test.ts | 3 -
tests/pull.test.ts | 53 +++++++++++++
tsconfig.build.json | 9 +++
tsconfig.json | 6 +-
yarn.lock | 139 +++++++++++++++++++++++++++++++-
18 files changed, 602 insertions(+), 191 deletions(-)
create mode 100644 jest.config.ts
create mode 100644 src/cli.ts
create mode 100644 tests/common/index.ts
create mode 100644 tests/config.test.ts
create mode 100644 tests/fetch.test.ts
delete mode 100644 tests/index.test.ts
create mode 100644 tests/pull.test.ts
create mode 100644 tsconfig.build.json
diff --git a/README.md b/README.md
index df7e785..2956090 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
Dria CLI
- Dria CLI is a command-line tool that can be used to interact with Dria.
+ Dria CLI is a command-line tool that can be used to interact with Dria locally.
@@ -155,3 +155,7 @@ You can lint & check formatting with:
yarn lint
yarn format
```
+
+## License
+
+See [LICENSE](./LICENSE).
diff --git a/jest.config.ts b/jest.config.ts
new file mode 100644
index 0000000..ec6f453
--- /dev/null
+++ b/jest.config.ts
@@ -0,0 +1,22 @@
+import type { JestConfigWithTsJest } from "ts-jest";
+
+const config: JestConfigWithTsJest = {
+ // ts-jest defaults
+ preset: "ts-jest",
+ testEnvironment: "node",
+ transform: {
+ "^.+\\.(ts|js)$": "ts-jest",
+ },
+ // timeout should be rather large due to Docker stuff & sleeps
+ testTimeout: 600_000,
+ // docker containers may take some time to close
+ openHandlesTimeout: 10_000,
+ // print everything like Mocha
+ verbose: true,
+ // dont run in parallel
+ maxConcurrency: 1,
+ // ignore output directory
+ testPathIgnorePatterns: ["bin", "node_modules", "src"],
+};
+
+export default config;
diff --git a/package.json b/package.json
index 0233d76..b879322 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,11 @@
{
"name": "dria-cli",
- "version": "0.0.7",
+ "version": "0.0.8",
"description": "A command-line tool for Dria",
"author": "FirstBatch Team ",
"contributors": [
"Erhan Tezcan (https://github.com/erhant)"
],
- "homepage": "https://github.com/firstbatchxyz/dria-cli#readme",
"license": "Apache-2.0",
"files": [
"/bin",
@@ -17,12 +16,12 @@
"dria": "./bin/index.js"
},
"scripts": {
- "lint": "npx eslint './src/**/*.ts' && echo 'All good!'",
- "format": "npx prettier --check ./src/**/*.ts",
- "build": "npx tsc",
+ "build": "npx tsc -p tsconfig.build.json",
"start": "node ./bin/index.js",
"dria": "yarn build && yarn start",
- "test": "npx jest"
+ "test": "npx jest",
+ "lint": "npx eslint './src/**/*.ts' && echo 'All good!'",
+ "format": "npx prettier --check ./src/**/*.ts"
},
"engines": {
"node": ">=18.0.0"
@@ -49,6 +48,7 @@
"jest": "^29.7.0",
"prettier": "^3.2.5",
"ts-jest": "^29.1.2",
+ "ts-node": "^10.9.2",
"typescript": "^5.3.3"
},
"prettier": {
@@ -65,6 +65,27 @@
],
"rules": {
"@typescript-eslint/no-unused-vars": "warn"
- }
- }
+ },
+ "ignorePatterns": [
+ "bin",
+ "node_modules"
+ ]
+ },
+ "homepage": "https://github.com/firstbatchxyz/dria-cli#readme",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/firstbatchxyz/dria-cli.git"
+ },
+ "bugs": {
+ "url": "https://github.com/firstbatchxyz/dria-cli/issues/"
+ },
+ "keywords": [
+ "dria",
+ "hollowdb",
+ "arweave",
+ "yargs",
+ "cli",
+ "rag",
+ "ai"
+ ]
}
diff --git a/src/cli.ts b/src/cli.ts
new file mode 100644
index 0000000..c1e34cd
--- /dev/null
+++ b/src/cli.ts
@@ -0,0 +1,153 @@
+import yargs from "yargs";
+import commands from "./commands/";
+import { checkDocker, checkNetwork, logger } from "./common";
+import { getConfig, setConfig } from "./configurations";
+
+const config = getConfig();
+
+const contractIdArg = {
+ id: "contract" as const,
+ opts: {
+ alias: "c",
+ describe: "Contract ID",
+ type: "string",
+ default: config.contract,
+ } as const,
+} as const;
+
+const verboseArg = {
+ id: "verbose" as const,
+ opts: {
+ alias: "v",
+ describe: "Show extra information",
+ boolean: true,
+ default: false,
+ coerce: (verbose: boolean) => {
+ logger.setLevel(verbose ? "DEBUG" : "INFO");
+ return verbose;
+ },
+ } as const,
+} as const;
+
+const txIdArg = {
+ id: "txid" as const,
+ opts: {
+ describe: "Transaction ID",
+ type: "string",
+ demandOption: true,
+ } as const,
+} as const;
+
+async function checkArgs(args: { contract?: string }, checks: { contract?: boolean; docker?: boolean }) {
+ if (checks.contract) {
+ if (args.contract === undefined) throw new Error("Contract not provided.");
+ }
+
+ if (checks.docker) {
+ await checkDocker();
+ await checkNetwork();
+ }
+
+ return true;
+}
+
+/**
+ * Use Dria CLI with arguments.
+ * @param args command-line arguments
+ * @example
+ * import { hideBin } from "yargs/helpers";
+ *
+ * driaCLI(hideBin(process.argv));
+ */
+export function driaCLI(args: string[]) {
+ yargs(args)
+ .scriptName("dria")
+ .option(verboseArg.id, verboseArg.opts)
+
+ .command(
+ "pull [contract]",
+ "Pull a knowledge to your local machine.",
+ (yargs) =>
+ yargs.positional(contractIdArg.id, contractIdArg.opts).check(async (args) => {
+ return await checkArgs(args, { contract: true, docker: true });
+ }),
+ async (args) => {
+ await commands.pull(args.contract!);
+ },
+ )
+
+ .command(
+ "serve [contract]",
+ "Serve a local knowledge.",
+ (yargs) =>
+ yargs.positional(contractIdArg.id, contractIdArg.opts).check(async (args) => {
+ return await checkArgs(args, { contract: true, docker: true });
+ }),
+ async (args) => {
+ await commands.serve(args.contract!);
+ },
+ )
+
+ .command(
+ "clear [contract]",
+ "Clear local knowledge.",
+ (yargs) =>
+ yargs.positional(contractIdArg.id, contractIdArg.opts).check(async (args) => {
+ return await checkArgs(args, { contract: true });
+ }),
+ async (args) => {
+ await commands.clear(args.contract!);
+ },
+ )
+
+ .command(
+ "fetch ",
+ "Fetch an existing index at the given URL directly.",
+ (yargs) => yargs.positional(txIdArg.id, txIdArg.opts),
+ async (args) => {
+ await commands.fetch(args.txid!);
+ },
+ )
+
+ .command(
+ "set-contract ",
+ "Set default contract.",
+ (yargs) => yargs.option(contractIdArg.id, { ...contractIdArg.opts, demandOption: true }),
+ (args) => {
+ setConfig({
+ contract: args.contract,
+ });
+ },
+ )
+
+ .command(
+ "config",
+ "Show default configurations.",
+ (yargs) => yargs,
+ () => {
+ const cfg = getConfig();
+ logger.info("Contract: ", cfg.contract ?? "not set.");
+ },
+ )
+
+ .command(
+ "list",
+ "List all local knowledge.",
+ (yargs) => yargs,
+ () => {
+ commands.list();
+ },
+ )
+
+ .command(
+ "stop",
+ "Stop serving knowledge.",
+ (yargs) => yargs,
+ async () => {
+ await commands.stop();
+ },
+ )
+
+ .demandCommand(1)
+ .parse();
+}
diff --git a/src/commands/fetch.ts b/src/commands/fetch.ts
index 6ba80c2..267483b 100644
--- a/src/commands/fetch.ts
+++ b/src/commands/fetch.ts
@@ -5,8 +5,18 @@ import constants from "../constants";
* Fetch an existing unbundled data on Arweave, i.e. a zipped Rocksdb folder
* that is bundled & uploaded to Arweave.
*
- * @param contractId contract ID to download
+ * Note that this command takes in the txID, not a contract ID! When the downloaded
+ * knowledge is unzipped, it might have a different name; you can see it with the command:
+ *
+ * ```sh
+ * dria list
+ * ```
+ *
+ * Or, you can see the knowledge ID in the console, while the unzip operations
+ * prints its logs.
+ *
+ * @param txId Arweave txID to download
*/
-export default async function cmdFetch(contractId: string) {
- await downloadAndUnzip(contractId, constants.DRIA.DATA);
+export default async function cmdFetch(txId: string) {
+ await downloadAndUnzip(txId, constants.DRIA.DATA);
}
diff --git a/src/common/download.ts b/src/common/download.ts
index 1001b49..d959385 100644
--- a/src/common/download.ts
+++ b/src/common/download.ts
@@ -54,13 +54,19 @@ export async function downloadAndUnzip(txId: string, outDir: string) {
});
});
- // unzip to out directory
- createReadStream(tmpPath)
- .pipe(unzipper.Extract({ path: outDir, verbose: true }))
- .on("close", () => {
- logger.info("Knowledge extracted at", outDir);
- logger.info("Cleaning up zip artifacts.");
- rmSync(tmpPath);
- logger.info("Done.");
- });
+ await new Promise((resolve, reject) => {
+ createReadStream(tmpPath)
+ // unzips to out directory
+ .pipe(unzipper.Extract({ path: outDir, verbose: process.env.NODE_ENV !== "test" }))
+ .on("error", (err) => {
+ reject(err);
+ })
+ .on("close", () => {
+ logger.info("Knowledge extracted at", outDir);
+ logger.info("Cleaning up zip artifacts.");
+ rmSync(tmpPath);
+ logger.info("Done.");
+ resolve(true);
+ });
+ });
}
diff --git a/src/common/index.ts b/src/common/index.ts
index 9de48f7..613075c 100644
--- a/src/common/index.ts
+++ b/src/common/index.ts
@@ -1,7 +1,6 @@
import Docker from "dockerode";
import loglevel from "loglevel";
import constants from "../constants";
-import { existsSync, mkdirSync } from "fs";
export * from "./download";
export * from "./image";
diff --git a/src/configurations/index.ts b/src/configurations/index.ts
index eaca10c..f575b57 100644
--- a/src/configurations/index.ts
+++ b/src/configurations/index.ts
@@ -15,7 +15,10 @@ const CONFIG_PATH = constants.DRIA.CONFIG;
/**
* Returns the active Dria configurations.
- * @returns config
+ *
+ * If no existing config is found, writes the default configuration to the config destination and returns it.
+ *
+ * @returns Dria configuration
*/
export function getConfig(): DriaCLIConfig {
if (existsSync(CONFIG_PATH)) {
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 491e470..a217eea 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -4,11 +4,11 @@ import { resolve } from "path";
type ENTITIES = "REDIS" | "HOLLOWDB" | "HNSW";
-// "~/.dria/",
-const DRIA_ROOT = homedir() + "/.dria";
+const DRIA_ROOT = homedir() + "/.dria"; // "~/.dria/",
export default {
ARWEAVE: {
+ /** Base URL for `fetch` command. */
DOWNLOAD_URL: "https://arweave.net",
},
DRIA: {
@@ -22,7 +22,9 @@ export default {
TMP: resolve(`${DRIA_ROOT}/tmp`),
} as const,
HOLLOWDB: {
- DOWNLOAD_TIMEOUT: 15000, // timeout until download starts, otherwise rejects
+ /** Timeout until download starts during `pull`,
+ * if download doesn't start by then, it gives an error. */
+ DOWNLOAD_TIMEOUT: 15000,
},
LOGGER: {
NAME: "dria-logger",
@@ -38,19 +40,38 @@ export default {
HOLLOWDB: "firstbatch/dria-hollowdb:latest",
HNSW: "firstbatch/dria-hnsw:latest",
} as const satisfies Record,
- CONTAINERS: {
- REDIS: "dria-redis",
- HOLLOWDB: "dria-hollowdb",
- HNSW: "dria-hnsw",
- } as const satisfies Record,
- NETWORK: {
- NAME: "dria-network",
- SUBNET: "172.30.0.0/24",
- GATEWAY: "172.30.0.1",
- IPS: {
- REDIS: "172.30.0.11",
- HOLLOWDB: "172.30.0.12",
- HNSW: "172.30.0.13",
- } as const satisfies Record,
- },
+ CONTAINERS:
+ process.env.NODE_ENV === "test"
+ ? ({
+ REDIS: "dria-redis-testing",
+ HOLLOWDB: "dria-hollowdb-testing",
+ HNSW: "dria-hnsw-testing",
+ } as const satisfies Record)
+ : ({
+ REDIS: "dria-redis",
+ HOLLOWDB: "dria-hollowdb",
+ HNSW: "dria-hnsw",
+ } as const satisfies Record),
+ NETWORK:
+ process.env.NODE_ENV === "test"
+ ? {
+ NAME: "dria-network",
+ SUBNET: "172.30.0.0/24",
+ GATEWAY: "172.30.0.1",
+ IPS: {
+ REDIS: "172.30.0.11",
+ HOLLOWDB: "172.30.0.12",
+ HNSW: "172.30.0.13",
+ } as const satisfies Record,
+ }
+ : {
+ NAME: "dria-network-testing",
+ SUBNET: "173.30.0.0/24",
+ GATEWAY: "173.30.0.1",
+ IPS: {
+ REDIS: "173.30.0.11",
+ HOLLOWDB: "173.30.0.12",
+ HNSW: "173.30.0.13",
+ } as const satisfies Record,
+ },
} as const;
diff --git a/src/index.ts b/src/index.ts
index edf4810..a97f7f3 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,146 +1,6 @@
#!/usr/bin/env node
-import yargs from "yargs";
import { hideBin } from "yargs/helpers";
-import commands from "./commands/";
-import { checkDocker, checkNetwork, logger } from "./common";
-import { getConfig, setConfig } from "./configurations";
+import { driaCLI } from "./cli";
-const config = getConfig();
-
-const contractIdArg = {
- id: "contract" as const,
- opts: {
- alias: "c",
- describe: "Contract ID",
- type: "string",
- default: config.contract,
- } as const,
-} as const;
-
-const verboseArg = {
- id: "verbose" as const,
- opts: {
- alias: "v",
- describe: "Show extra information",
- boolean: true,
- default: false,
- coerce: (verbose: boolean) => {
- logger.setLevel(verbose ? "DEBUG" : "INFO");
- return verbose;
- },
- } as const,
-} as const;
-
-const txIdArg = {
- id: "txid" as const,
- opts: {
- describe: "Transaction ID",
- type: "string",
- demandOption: true,
- } as const,
-} as const;
-
-async function checkArgs(args: { contract?: string }, checks: { contract?: boolean; docker?: boolean }) {
- if (checks.contract) {
- if (args.contract === undefined) throw new Error("Contract not provided.");
- }
-
- if (checks.docker) {
- await checkDocker();
- await checkNetwork();
- }
-
- return true;
-}
-
-yargs(hideBin(process.argv))
- .scriptName("dria")
- .option(verboseArg.id, verboseArg.opts)
-
- .command(
- "pull [contract]",
- "Pull a knowledge to your local machine.",
- (yargs) =>
- yargs.positional(contractIdArg.id, contractIdArg.opts).check(async (args) => {
- return await checkArgs(args, { contract: true, docker: true });
- }),
- async (args) => {
- await commands.pull(args.contract!);
- },
- )
-
- .command(
- "serve [contract]",
- "Serve a local knowledge.",
- (yargs) =>
- yargs.positional(contractIdArg.id, contractIdArg.opts).check(async (args) => {
- return await checkArgs(args, { contract: true, docker: true });
- }),
- async (args) => {
- await commands.serve(args.contract!);
- },
- )
-
- .command(
- "clear [contract]",
- "Clear local knowledge.",
- (yargs) =>
- yargs.positional(contractIdArg.id, contractIdArg.opts).check(async (args) => {
- return await checkArgs(args, { contract: true });
- }),
- async (args) => {
- await commands.clear(args.contract!);
- },
- )
-
- .command(
- "fetch ",
- "Fetch an existing index at the given URL directly.",
- (yargs) => yargs.positional(txIdArg.id, txIdArg.opts),
- async (args) => {
- await commands.fetch(args.txid!);
- },
- )
-
- .command(
- "set-contract ",
- "Set default contract.",
- (yargs) => yargs.option(contractIdArg.id, { ...contractIdArg.opts, demandOption: true }),
- (args) => {
- setConfig({
- contract: args.contract,
- });
- },
- )
-
- .command(
- "config",
- "Show default configurations.",
- (yargs) => yargs,
- () => {
- const cfg = getConfig();
- logger.info("Contract: ", cfg.contract ?? "not set.");
- },
- )
-
- .command(
- "list",
- "List all local knowledge.",
- (yargs) => yargs,
- () => {
- commands.list();
- },
- )
-
- .command(
- "stop",
- "Stop serving knowledge.",
- (yargs) => yargs,
- async () => {
- await commands.stop();
- },
- )
-
- .demandCommand(1)
- .parse();
+driaCLI(hideBin(process.argv));
diff --git a/tests/common/index.ts b/tests/common/index.ts
new file mode 100644
index 0000000..d4f6325
--- /dev/null
+++ b/tests/common/index.ts
@@ -0,0 +1,34 @@
+class DriaClient {
+ constructor(readonly url: string) {}
+
+ async health(): Promise {
+ try {
+ const res = await fetch(this.url + "/health");
+ return res.ok;
+ } catch {
+ return false;
+ }
+ }
+
+ async fetchIds(ids: number[]): Promise {
+ const res = await fetch(this.url + "/fetch", {
+ method: "POST",
+ body: JSON.stringify({ id: ids }),
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ if (!res.ok) {
+ console.log(res);
+ throw `Failed with ${res.status}`;
+ }
+
+ const body: { data: T[] } = await res.json();
+ return body.data;
+ }
+}
+
+/**
+ * A Dria client to be used with locally hosted HNSW.
+ */
+export const driaClient = new DriaClient("http://localhost:8080");
diff --git a/tests/config.test.ts b/tests/config.test.ts
new file mode 100644
index 0000000..5112468
--- /dev/null
+++ b/tests/config.test.ts
@@ -0,0 +1,28 @@
+import { readFileSync, writeFileSync } from "fs";
+import { getConfig, type DriaCLIConfig, setConfig } from "../src/configurations";
+import constants from "../src/constants";
+
+describe("configurations", () => {
+ let existingConfig: DriaCLIConfig;
+
+ beforeAll(() => {
+ existingConfig = JSON.parse(readFileSync(constants.DRIA.CONFIG, "utf-8"));
+ });
+
+ afterAll(() => {
+ writeFileSync(constants.DRIA.CONFIG, JSON.stringify(existingConfig));
+ });
+
+ it("should get config", () => {
+ const cfg = getConfig();
+ expect(cfg.contract).toBe(existingConfig.contract);
+ });
+
+ it("should update config", () => {
+ const newContract = "test-contract";
+ setConfig({ contract: newContract });
+
+ const cfg = getConfig();
+ expect(cfg.contract).toBe(newContract);
+ });
+});
diff --git a/tests/fetch.test.ts b/tests/fetch.test.ts
new file mode 100644
index 0000000..b1d2104
--- /dev/null
+++ b/tests/fetch.test.ts
@@ -0,0 +1,56 @@
+import cmdFetch from "../src/commands/fetch";
+import cmdClear from "../src/commands/clear";
+import constants from "../src/constants";
+import { existsSync } from "node:fs";
+import cmdServe from "../src/commands/serve";
+import { driaClient } from "./common";
+import cmdStop from "../src/commands/stop";
+import { checkDocker, checkNetwork, sleep } from "../src/common";
+
+describe("fetch", () => {
+ // a small knowledge zip on Arweave
+ const txid = "3yUzQ8vnLeFUz_T2mhMoAQFZhJtQYG5o6FfeRRbLm-E";
+ // the corresponding contract ID from the zip at that txID
+ const contractId = "WbcY2a-KfDpk7fsgumUtLC2bu4NQcVzNlXWi13fPMlU";
+ // metadata type of this knowledge
+ type MetadataType = { id: string; page: string; text: string };
+
+ beforeAll(async () => {
+ await checkDocker();
+ await checkNetwork();
+
+ await cmdClear(contractId);
+ });
+
+ afterAll(async () => {
+ await cmdClear(contractId);
+
+ await cmdStop();
+ });
+
+ it("should fetch", async () => {
+ expect(existsSync(`${constants.DRIA.DATA}/${contractId}`)).toBe(false);
+ await cmdFetch(txid);
+ await sleep(2000);
+ expect(existsSync(`${constants.DRIA.DATA}/${contractId}`)).toBe(true);
+ });
+
+ it("should serve", async () => {
+ expect(await driaClient.health()).toBe(false);
+ await cmdServe(contractId);
+ await sleep(2000);
+ expect(await driaClient.health()).toBe(true);
+
+ const fetched = await driaClient.fetchIds([0]);
+ expect(fetched.length).toBe(1);
+ expect(typeof fetched[0].id).toBe("string");
+ expect(typeof fetched[0].page).toBe("string");
+ expect(typeof fetched[0].text).toBe("string");
+ });
+
+ it("should stop", async () => {
+ await cmdStop();
+ await sleep(2000);
+ expect(await driaClient.health()).toBe(false);
+ });
+});
diff --git a/tests/index.test.ts b/tests/index.test.ts
deleted file mode 100644
index 00567eb..0000000
--- a/tests/index.test.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-describe("cli tests", () => {
- // TODO: https://kgajera.com/blog/how-to-test-yargs-cli-with-jest/
-});
diff --git a/tests/pull.test.ts b/tests/pull.test.ts
new file mode 100644
index 0000000..569d4d1
--- /dev/null
+++ b/tests/pull.test.ts
@@ -0,0 +1,53 @@
+import cmdFetch from "../src/commands/fetch";
+import cmdClear from "../src/commands/clear";
+import constants from "../src/constants";
+import { existsSync } from "node:fs";
+import cmdServe from "../src/commands/serve";
+import { driaClient } from "./common";
+import cmdStop from "../src/commands/stop";
+import { checkDocker, checkNetwork, sleep } from "../src/common";
+import cmdPull from "../src/commands/pull";
+
+describe("pull", () => {
+ // a small knowledge about TypeScript (272 entries)
+ const contractId = "-B64DjhUtCwBdXSpsRytlRQCu-bie-vSTvTIT8Ap3g0";
+ // metadata type of this knowledge
+ type MetadataType = { id: string; page: string; text: string };
+
+ beforeAll(async () => {
+ await checkDocker();
+ await checkNetwork();
+
+ await cmdClear(contractId);
+ });
+
+ afterAll(async () => {
+ await cmdClear(contractId);
+ });
+
+ it("should pull", async () => {
+ expect(existsSync(`${constants.DRIA.DATA}/${contractId}`)).toBe(false);
+ await cmdPull(contractId);
+ await sleep(2000);
+ expect(existsSync(`${constants.DRIA.DATA}/${contractId}`)).toBe(true);
+ });
+
+ it("should serve", async () => {
+ expect(await driaClient.health()).toBe(false);
+ await cmdServe(contractId);
+ await sleep(2000);
+ expect(await driaClient.health()).toBe(true);
+
+ const fetched = await driaClient.fetchIds([0]);
+ expect(fetched.length).toBe(1);
+ expect(typeof fetched[0].id).toBe("string");
+ expect(typeof fetched[0].page).toBe("string");
+ expect(typeof fetched[0].text).toBe("string");
+ });
+
+ it("should stop", async () => {
+ await cmdStop();
+ await sleep(2000);
+ expect(await driaClient.health()).toBe(false);
+ });
+});
diff --git a/tsconfig.build.json b/tsconfig.build.json
new file mode 100644
index 0000000..aee142c
--- /dev/null
+++ b/tsconfig.build.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "rootDir": "./src",
+ "outDir": "bin",
+ "noEmit": false
+ },
+ "include": ["src/**/*.ts"]
+}
diff --git a/tsconfig.json b/tsconfig.json
index 2ca234e..984d8b0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,5 @@
{
- "exclude": ["tests"],
+ "exclude": ["node_modules", "bin"],
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
@@ -27,7 +27,7 @@
/* Modules */
"module": "CommonJS" /* Specify what module code is generated. */,
- "rootDir": "./src" /* Specify the root folder within your source files. */,
+ // "rootDir": "./" /* Specify the root folder within your source files. */,
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
@@ -56,7 +56,7 @@
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./bin" /* Specify an output folder for all emitted files. */,
+ // "outDir": "./bin" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
diff --git a/yarn.lock b/yarn.lock
index dc4a70b..b5985a9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -422,6 +422,15 @@ __metadata:
languageName: node
linkType: hard
+"@cspotcode/source-map-support@npm:^0.8.0":
+ version: 0.8.1
+ resolution: "@cspotcode/source-map-support@npm:0.8.1"
+ dependencies:
+ "@jridgewell/trace-mapping": "npm:0.3.9"
+ checksum: 10c0/05c5368c13b662ee4c122c7bfbe5dc0b613416672a829f3e78bc49a357a197e0218d6e74e7c66cfcd04e15a179acab080bd3c69658c9fbefd0e1ccd950a07fc6
+ languageName: node
+ linkType: hard
+
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0":
version: 4.4.0
resolution: "@eslint-community/eslint-utils@npm:4.4.0"
@@ -764,6 +773,13 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/resolve-uri@npm:^3.0.3":
+ version: 3.1.2
+ resolution: "@jridgewell/resolve-uri@npm:3.1.2"
+ checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e
+ languageName: node
+ linkType: hard
+
"@jridgewell/resolve-uri@npm:^3.1.0":
version: 3.1.1
resolution: "@jridgewell/resolve-uri@npm:3.1.1"
@@ -785,6 +801,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/trace-mapping@npm:0.3.9":
+ version: 0.3.9
+ resolution: "@jridgewell/trace-mapping@npm:0.3.9"
+ dependencies:
+ "@jridgewell/resolve-uri": "npm:^3.0.3"
+ "@jridgewell/sourcemap-codec": "npm:^1.4.10"
+ checksum: 10c0/fa425b606d7c7ee5bfa6a31a7b050dd5814b4082f318e0e4190f991902181b4330f43f4805db1dd4f2433fd0ed9cc7a7b9c2683f1deeab1df1b0a98b1e24055b
+ languageName: node
+ linkType: hard
+
"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.22
resolution: "@jridgewell/trace-mapping@npm:0.3.22"
@@ -883,6 +909,34 @@ __metadata:
languageName: node
linkType: hard
+"@tsconfig/node10@npm:^1.0.7":
+ version: 1.0.9
+ resolution: "@tsconfig/node10@npm:1.0.9"
+ checksum: 10c0/c176a2c1e1b16be120c328300ea910df15fb9a5277010116d26818272341a11483c5a80059389d04edacf6fd2d03d4687ad3660870fdd1cc0b7109e160adb220
+ languageName: node
+ linkType: hard
+
+"@tsconfig/node12@npm:^1.0.7":
+ version: 1.0.11
+ resolution: "@tsconfig/node12@npm:1.0.11"
+ checksum: 10c0/dddca2b553e2bee1308a056705103fc8304e42bb2d2cbd797b84403a223b25c78f2c683ec3e24a095e82cd435387c877239bffcb15a590ba817cd3f6b9a99fd9
+ languageName: node
+ linkType: hard
+
+"@tsconfig/node14@npm:^1.0.0":
+ version: 1.0.3
+ resolution: "@tsconfig/node14@npm:1.0.3"
+ checksum: 10c0/67c1316d065fdaa32525bc9449ff82c197c4c19092b9663b23213c8cbbf8d88b6ed6a17898e0cbc2711950fbfaf40388938c1c748a2ee89f7234fc9e7fe2bf44
+ languageName: node
+ linkType: hard
+
+"@tsconfig/node16@npm:^1.0.2":
+ version: 1.0.4
+ resolution: "@tsconfig/node16@npm:1.0.4"
+ checksum: 10c0/05f8f2734e266fb1839eb1d57290df1664fe2aa3b0fdd685a9035806daa635f7519bf6d5d9b33f6e69dd545b8c46bd6e2b5c79acb2b1f146e885f7f11a42a5bb
+ languageName: node
+ linkType: hard
+
"@types/babel__core@npm:^7.1.14":
version: 7.20.5
resolution: "@types/babel__core@npm:7.20.5"
@@ -1207,7 +1261,14 @@ __metadata:
languageName: node
linkType: hard
-"acorn@npm:^8.9.0":
+"acorn-walk@npm:^8.1.1":
+ version: 8.3.2
+ resolution: "acorn-walk@npm:8.3.2"
+ checksum: 10c0/7e2a8dad5480df7f872569b9dccff2f3da7e65f5353686b1d6032ab9f4ddf6e3a2cb83a9b52cf50b1497fd522154dda92f0abf7153290cc79cd14721ff121e52
+ languageName: node
+ linkType: hard
+
+"acorn@npm:^8.4.1, acorn@npm:^8.9.0":
version: 8.11.3
resolution: "acorn@npm:8.11.3"
bin:
@@ -1312,6 +1373,13 @@ __metadata:
languageName: node
linkType: hard
+"arg@npm:^4.1.0":
+ version: 4.1.3
+ resolution: "arg@npm:4.1.3"
+ checksum: 10c0/070ff801a9d236a6caa647507bdcc7034530604844d64408149a26b9e87c2f97650055c0f049abd1efc024b334635c01f29e0b632b371ac3f26130f4cf65997a
+ languageName: node
+ linkType: hard
+
"argparse@npm:^1.0.7":
version: 1.0.10
resolution: "argparse@npm:1.0.10"
@@ -1829,6 +1897,13 @@ __metadata:
languageName: node
linkType: hard
+"create-require@npm:^1.1.0":
+ version: 1.1.1
+ resolution: "create-require@npm:1.1.1"
+ checksum: 10c0/157cbc59b2430ae9a90034a5f3a1b398b6738bf510f713edc4d4e45e169bc514d3d99dd34d8d01ca7ae7830b5b8b537e46ae8f3c8f932371b0875c0151d7ec91
+ languageName: node
+ linkType: hard
+
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
@@ -1899,6 +1974,13 @@ __metadata:
languageName: node
linkType: hard
+"diff@npm:^4.0.1":
+ version: 4.0.2
+ resolution: "diff@npm:4.0.2"
+ checksum: 10c0/81b91f9d39c4eaca068eb0c1eb0e4afbdc5bb2941d197f513dd596b820b956fef43485876226d65d497bebc15666aa2aa82c679e84f65d5f2bfbf14ee46e32c1
+ languageName: node
+ linkType: hard
+
"dir-glob@npm:^3.0.1":
version: 3.0.1
resolution: "dir-glob@npm:3.0.1"
@@ -1960,6 +2042,7 @@ __metadata:
loglevel: "npm:^1.9.1"
prettier: "npm:^3.2.5"
ts-jest: "npm:^29.1.2"
+ ts-node: "npm:^10.9.2"
typescript: "npm:^5.3.3"
unzipper: "npm:^0.10.14"
yargs: "npm:^17.7.2"
@@ -3564,7 +3647,7 @@ __metadata:
languageName: node
linkType: hard
-"make-error@npm:1.x":
+"make-error@npm:1.x, make-error@npm:^1.1.1":
version: 1.3.6
resolution: "make-error@npm:1.3.6"
checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f
@@ -4750,6 +4833,44 @@ __metadata:
languageName: node
linkType: hard
+"ts-node@npm:^10.9.2":
+ version: 10.9.2
+ resolution: "ts-node@npm:10.9.2"
+ dependencies:
+ "@cspotcode/source-map-support": "npm:^0.8.0"
+ "@tsconfig/node10": "npm:^1.0.7"
+ "@tsconfig/node12": "npm:^1.0.7"
+ "@tsconfig/node14": "npm:^1.0.0"
+ "@tsconfig/node16": "npm:^1.0.2"
+ acorn: "npm:^8.4.1"
+ acorn-walk: "npm:^8.1.1"
+ arg: "npm:^4.1.0"
+ create-require: "npm:^1.1.0"
+ diff: "npm:^4.0.1"
+ make-error: "npm:^1.1.1"
+ v8-compile-cache-lib: "npm:^3.0.1"
+ yn: "npm:3.1.1"
+ peerDependencies:
+ "@swc/core": ">=1.2.50"
+ "@swc/wasm": ">=1.2.50"
+ "@types/node": "*"
+ typescript: ">=2.7"
+ peerDependenciesMeta:
+ "@swc/core":
+ optional: true
+ "@swc/wasm":
+ optional: true
+ bin:
+ ts-node: dist/bin.js
+ ts-node-cwd: dist/bin-cwd.js
+ ts-node-esm: dist/bin-esm.js
+ ts-node-script: dist/bin-script.js
+ ts-node-transpile-only: dist/bin-transpile.js
+ ts-script: dist/bin-script-deprecated.js
+ checksum: 10c0/5f29938489f96982a25ba650b64218e83a3357d76f7bede80195c65ab44ad279c8357264639b7abdd5d7e75fc269a83daa0e9c62fd8637a3def67254ecc9ddc2
+ languageName: node
+ linkType: hard
+
"tslib@npm:^2.6.2":
version: 2.6.2
resolution: "tslib@npm:2.6.2"
@@ -4887,6 +5008,13 @@ __metadata:
languageName: node
linkType: hard
+"v8-compile-cache-lib@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "v8-compile-cache-lib@npm:3.0.1"
+ checksum: 10c0/bdc36fb8095d3b41df197f5fb6f11e3a26adf4059df3213e3baa93810d8f0cc76f9a74aaefc18b73e91fe7e19154ed6f134eda6fded2e0f1c8d2272ed2d2d391
+ languageName: node
+ linkType: hard
+
"v8-to-istanbul@npm:^9.0.1":
version: 9.2.0
resolution: "v8-to-istanbul@npm:9.2.0"
@@ -5011,6 +5139,13 @@ __metadata:
languageName: node
linkType: hard
+"yn@npm:3.1.1":
+ version: 3.1.1
+ resolution: "yn@npm:3.1.1"
+ checksum: 10c0/0732468dd7622ed8a274f640f191f3eaf1f39d5349a1b72836df484998d7d9807fbea094e2f5486d6b0cd2414aad5775972df0e68f8604db89a239f0f4bf7443
+ languageName: node
+ linkType: hard
+
"yocto-queue@npm:^0.1.0":
version: 0.1.0
resolution: "yocto-queue@npm:0.1.0"