Skip to content

Commit

Permalink
style: clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
chronark committed Sep 23, 2024
1 parent b3ac029 commit 901266b
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 43 deletions.
13 changes: 3 additions & 10 deletions apps/api/src/pkg/analytics.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NoopTinybird, Tinybird } from "@chronark/zod-bird";
import { Clickhouse } from "@unkey/clickhouse-zod";
import * as ch from "@unkey/clickhouse-zod";
import { newId } from "@unkey/id";
import { auditLogSchemaV1, unkeyAuditLogEvents } from "@unkey/schema/src/auditlog";
import { ratelimitSchemaV1 } from "@unkey/schema/src/ratelimit-tinybird";
Expand All @@ -18,7 +18,7 @@ const dateToUnixMilli = z.string().transform((t) => new Date(t.split(" ").at(0)
export class Analytics {
public readonly readClient: Tinybird | NoopTinybird;
public readonly writeClient: Tinybird | NoopTinybird;
private clickhouse: Clickhouse;
private clickhouse: ch.Clickhouse;

constructor(opts: {
tinybirdToken?: string;
Expand All @@ -38,13 +38,7 @@ export class Analytics {
? new Tinybird({ token: opts.tinybirdProxy.token, baseUrl: opts.tinybirdProxy.url })
: this.readClient;

this.clickhouse = new Clickhouse(
opts.clickhouse?.url
? {
url: opts.clickhouse.url,
}
: { noop: true },
);
this.clickhouse = opts.clickhouse ? new ch.Client({ url: opts.clickhouse.url }) : new ch.Noop();
}

public get ingestSdkTelemetry() {
Expand Down Expand Up @@ -123,7 +117,6 @@ export class Analytics {
"DISABLED",
"FORBIDDEN",
"USAGE_EXCEEDED",
"DISABLED",
"INSUFFICIENT_PERMISSIONS",
]),
identity_id: z.string().optional().default(""),
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/lib/clickhouse/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Clickhouse } from "@unkey/clickhouse-zod";
import { type Clickhouse, Client, Noop } from "@unkey/clickhouse-zod";
import { z } from "zod";
import { env } from "../env";

// dummy example of how to query stuff from clickhouse
export async function getLogs(args: { workspaceId: string; limit: number }) {
const { CLICKHOUSE_URL } = env();

const ch = new Clickhouse(CLICKHOUSE_URL ? { url: CLICKHOUSE_URL } : { noop: true });
const ch: Clickhouse = CLICKHOUSE_URL ? new Client({ url: CLICKHOUSE_URL }) : new Noop();
const query = ch.query({
query: `
SELECT
Expand Down
45 changes: 14 additions & 31 deletions internal/clickhouse-zod/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import { type ClickHouseClient, createClient } from "@clickhouse/client-web";
import type { z } from "zod";
import { z } from "zod";
import type { Clickhouse } from "./interface";

export type Config =
| {
url: string;
noop?: never;
}
| {
url?: never;
noop: true;
};
export type Config = {
url: string;
};

export class Clickhouse {
export class Client implements Clickhouse {
private readonly client: ClickHouseClient;
private readonly noop: boolean;

constructor(config: Config) {
this.noop = config.noop || false;
this.client = createClient({
url: config.url,
clickhouse_settings: {
Expand All @@ -41,17 +34,13 @@ export class Clickhouse {
schema: TOut;
}): (params: z.input<TIn>) => Promise<z.output<TOut>[]> {
return async (params: z.input<TIn>): Promise<z.output<TOut>[]> => {
if (this.noop) {
return [];
}

const res = await this.client.query({
query: req.query,
query_params: params,
query_params: req.params?.safeParse(params),
format: "JSONEachRow",
});
const rows = await res.json();
return rows.map((row) => req.schema.parse(row));
return z.array(req.schema).parse(rows);
};
}

Expand All @@ -63,19 +52,13 @@ export class Clickhouse {
) => Promise<{ executed: boolean; query_id: string }> {
return async (events: z.input<TSchema> | z.input<TSchema>[]) => {
let validatedEvents: z.output<TSchema> | z.output<TSchema>[] | undefined = undefined;
if (req.schema) {
const v = Array.isArray(events)
? req.schema.array().safeParse(events)
: req.schema.safeParse(events);
if (!v.success) {
throw new Error(v.error.message);
}
validatedEvents = v.data;
}

if (this.noop) {
return { executed: true, query_id: "noop" };
const v = Array.isArray(events)
? req.schema.array().safeParse(events)
: req.schema.safeParse(events);
if (!v.success) {
throw new Error(v.error.message);
}
validatedEvents = v.data;

return await this.client.insert({
table: req.table,
Expand Down
2 changes: 2 additions & 0 deletions internal/clickhouse-zod/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from "./client";
export * from "./noop";
export * from "./interface";
23 changes: 23 additions & 0 deletions internal/clickhouse-zod/src/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { z } from "zod";

export interface Clickhouse {
query<TIn extends z.ZodSchema<any>, TOut extends z.ZodSchema<any>>(req: {
// The SQL query to run.
// Use {paramName: Type} to define parameters
// Example: `SELECT * FROM table WHERE id = {id: String}`
query: string;
// The schema of the parameters
// Example: z.object({ id: z.string() })
params?: TIn;
// The schema of the output of each row
// Example: z.object({ id: z.string() })
schema: TOut;
}): (params: z.input<TIn>) => Promise<z.output<TOut>[]>;

insert<TSchema extends z.ZodSchema<any>>(req: {
table: string;
schema: TSchema;
}): (
events: z.input<TSchema> | z.input<TSchema>[],
) => Promise<{ executed: boolean; query_id: string }>;
}
39 changes: 39 additions & 0 deletions internal/clickhouse-zod/src/noop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { z } from "zod";
import type { Clickhouse } from "./interface";
export class Noop implements Clickhouse {
public query<TIn extends z.ZodSchema<any>, TOut extends z.ZodSchema<any>>(req: {
// The SQL query to run.
// Use {paramName: Type} to define parameters
// Example: `SELECT * FROM table WHERE id = {id: String}`
query: string;
// The schema of the parameters
// Example: z.object({ id: z.string() })
params?: TIn;
// The schema of the output of each row
// Example: z.object({ id: z.string() })
schema: TOut;
}): (params: z.input<TIn>) => Promise<z.output<TOut>[]> {
return async (params: z.input<TIn>): Promise<z.output<TOut>[]> => {
req.params?.safeParse(params);
return [];
};
}

public insert<TSchema extends z.ZodSchema<any>>(req: {
table: string;
schema: TSchema;
}): (
events: z.input<TSchema> | z.input<TSchema>[],
) => Promise<{ executed: boolean; query_id: string }> {
return async (events: z.input<TSchema> | z.input<TSchema>[]) => {
const v = Array.isArray(events)
? req.schema.array().safeParse(events)
: req.schema.safeParse(events);
if (!v.success) {
throw new Error(v.error.message);
}

return { executed: true, query_id: "noop" };
};
}
}

0 comments on commit 901266b

Please sign in to comment.