diff --git a/.gitignore b/.gitignore index 90c68ed..22ede88 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ yarn-error.log* lerna-debug.log* .pnpm-debug.log* package-lock.json +substreams-atomicmarket-api # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/index.ts b/index.ts index 68d2057..0829e2c 100644 --- a/index.ts +++ b/index.ts @@ -1,6 +1,6 @@ -import { config } from "./src/config"; -import { logger } from "./src/logger"; -import GET from "./src/fetch/GET"; +import { config } from "./src/config.js"; +import { logger } from "./src/logger.js"; +import GET from "./src/fetch/GET.js"; import * as prometheus from "./src/prometheus.js"; if (config.verbose) logger.enable(); diff --git a/package.json b/package.json index c682daa..4db5262 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "description": "Atomicmarket sales API powered by Substreams", "version": "v0.2.0", "homepage": "https://github.com/pinax-network/substreams-atomicmarket-api", + "type": "module", "author": { "name": "Paul Meignan", "email": "paulm@pinax.network", diff --git a/src/clickhouse/makeQuery.ts b/src/clickhouse/makeQuery.ts index 058541f..fe0ee69 100644 --- a/src/clickhouse/makeQuery.ts +++ b/src/clickhouse/makeQuery.ts @@ -1,6 +1,6 @@ -import { logger } from "../logger"; -import * as prometheus from "../prometheus"; -import client from "./createClient"; +import { logger } from "../logger.js"; +import * as prometheus from "../prometheus.js"; +import client from "./createClient.js"; export interface Meta { name: string, diff --git a/src/clickhouse/ping.ts b/src/clickhouse/ping.ts index 18ae36a..5646c6e 100644 --- a/src/clickhouse/ping.ts +++ b/src/clickhouse/ping.ts @@ -1,5 +1,5 @@ import { PingResult } from "@clickhouse/client-web"; -import client from "./createClient"; +import client from "./createClient.js"; // Does not work with Bun's implementation of Node streams. export async function ping(): Promise { diff --git a/src/config.ts b/src/config.ts index 15d1e37..91effc7 100644 --- a/src/config.ts +++ b/src/config.ts @@ -4,19 +4,17 @@ import { Option, program } from "commander"; import pkg from "../package.json"; -export const DEFAULT_PORT = "3001"; +export const DEFAULT_PORT = "8080"; export const DEFAULT_HOSTNAME = "localhost"; export const DEFAULT_HOST = "http://localhost:8123"; export const DEFAULT_DATABASE = "default"; -export const DEFAULT_TABLE = "demo"; export const DEFAULT_USERNAME = "default"; export const DEFAULT_PASSWORD = ""; -export const DEFAULT_MAX_LIMIT = 500; +export const DEFAULT_MAX_LIMIT = 10000; export const DEFAULT_VERBOSE = false; export const APP_NAME = pkg.name; export const DEFAULT_SORT_BY = "DESC"; - // parse command line options const opts = program .name(pkg.name) @@ -30,7 +28,6 @@ const opts = program .addOption(new Option("--username ", "Database user").env("USERNAME").default(DEFAULT_USERNAME)) .addOption(new Option("--password ", "Password associated with the specified username").env("PASSWORD").default(DEFAULT_PASSWORD)) .addOption(new Option("--database ", "The database to use inside ClickHouse").env("DATABASE").default(DEFAULT_DATABASE)) - .addOption(new Option("--table ", "Clickhouse table name").env("TABLE").default(DEFAULT_TABLE)) .addOption(new Option("--max-limit ", "Maximum LIMIT queries").env("MAX_LIMIT").default(DEFAULT_MAX_LIMIT)) .parse() .opts(); @@ -39,7 +36,6 @@ export const config = z.object({ port: z.string(), hostname: z.string(), host: z.string(), - table: z.string(), database: z.string(), username: z.string(), password: z.string(), diff --git a/src/fetch/openapi.ts b/src/fetch/openapi.ts index 6f17228..f8f01c9 100644 --- a/src/fetch/openapi.ts +++ b/src/fetch/openapi.ts @@ -1,9 +1,9 @@ import pkg from "../../package.json" assert { type: "json" }; import { OpenApiBuilder, SchemaObject, ExampleObject, ParameterObject } from "openapi3-ts/oas31"; -import { config } from "../config"; -import { registry } from "../prometheus"; -import { makeQuery } from "../clickhouse/makeQuery"; +import { config } from "../config.js"; +import { registry } from "../prometheus.js"; +import { makeQuery } from "../clickhouse/makeQuery.js"; const TAGS = { MONITORING: "Monitoring", diff --git a/src/fetch/salescount.ts b/src/fetch/salescount.ts index 98551ce..3aad0ff 100644 --- a/src/fetch/salescount.ts +++ b/src/fetch/salescount.ts @@ -1,14 +1,13 @@ import { makeQuery } from "../clickhouse/makeQuery.js"; import { logger } from "../logger.js"; -import { DEFAULT_SORT_BY, config } from '../config'; import * as prometheus from "../prometheus.js"; +import { getSalesCount } from "../queries.js"; export default async function (req: Request) { try { const { searchParams } = new URL(req.url); logger.info({searchParams: Object.fromEntries(Array.from(searchParams))}); - const collection_name = searchParams.get("collection_name"); - const query = `SELECT count(sale_id)FROM ${config.table} WHERE collection_name = '${collection_name}'`; + const query = getSalesCount(searchParams); const response = await makeQuery(query) return new Response(JSON.stringify(response.data), { headers: { "Content-Type": "application/json" } }); } catch (e: any) { diff --git a/src/fetch/totalvolume.ts b/src/fetch/totalvolume.ts index ac6db30..e196a7f 100644 --- a/src/fetch/totalvolume.ts +++ b/src/fetch/totalvolume.ts @@ -1,6 +1,6 @@ import { makeQuery } from "../clickhouse/makeQuery.js"; import { logger } from "../logger.js"; -import { DEFAULT_SORT_BY, config } from '../config'; +import { DEFAULT_SORT_BY, config } from '../config.js'; import * as prometheus from "../prometheus.js"; export default async function (req: Request) { @@ -8,7 +8,7 @@ export default async function (req: Request) { const { searchParams } = new URL(req.url); logger.info({searchParams: Object.fromEntries(Array.from(searchParams))}); const collection_name = searchParams.get("collection_name"); - const query = `SELECT sum(listing_price) FROM ${config.table} WHERE collection_name = '${collection_name}'`; + const query = `SELECT sum(listing_price) FROM Sales WHERE collection_name = '${collection_name}'`; const response = await makeQuery(query) return new Response(JSON.stringify(response.data), { headers: { "Content-Type": "application/json" } }); } catch (e: any) { diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..a43d03e --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,14 @@ +declare module "*.png" { + const content: string; + export default content; +} + +declare module "*.html" { + const content: string; + export default content; +} + +declare module "*.sql" { + const content: string; + export default content; +} diff --git a/tsconfig.json b/tsconfig.json index 5ace8f8..34b3b62 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,39 +1,14 @@ { "compilerOptions": { - // add Bun type definitions - "types": ["bun-types"], - - // enable latest features - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - - // if TS 5.x+ - "moduleResolution": "bundler", - "noEmit": true, - "allowImportingTsExtensions": true, - "moduleDetection": "force", - // if TS 4.x or earlier - // "moduleResolution": "nodenext", - - "jsx": "react-jsx", // support JSX - "allowJs": true, // allow importing `.js` from `.ts` - - // best practices + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "resolveJsonModule": true, "strict": true, - "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "strictNullChecks": true, + "alwaysStrict": true, "skipLibCheck": true, - "composite": true, - "downlevelIteration": true, - "allowSyntheticDefaultImports": true - }, - "include": [ - "index.ts", - "src/**/*.ts", - "package.json" - ], - "exclude": [ - "node_modules", - "src/tests/*.spec.ts" - ] + "types": ["bun-types"] + } }