added tooling (eslint, typescript and prettier)

This commit is contained in:
Carl-Gerhard Lindesvärd
2023-11-02 12:14:37 +01:00
parent 575b3c23bf
commit 493e1b7650
82 changed files with 1890 additions and 1363 deletions

View File

@@ -4,16 +4,15 @@
*
* We also create a few inference helpers for input and output types.
*/
import { type TRPCClientErrorBase, httpLink, loggerLink } from "@trpc/client";
import { createTRPCNext } from "@trpc/next";
import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
import superjson from "superjson";
import { type AppRouter } from "@/server/api/root";
import { toast } from "@/components/ui/use-toast";
import { toast } from '@/components/ui/use-toast';
import { type AppRouter } from '@/server/api/root';
import { httpLink, loggerLink, type TRPCClientErrorBase } from '@trpc/client';
import { createTRPCNext } from '@trpc/next';
import { type inferRouterInputs, type inferRouterOutputs } from '@trpc/server';
import superjson from 'superjson';
const getBaseUrl = () => {
if (typeof window !== "undefined") return ""; // browser should use relative url
if (typeof window !== 'undefined') return ''; // browser should use relative url
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
};
@@ -28,9 +27,9 @@ export const api = createTRPCNext<AppRouter>({
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
enabled: typeof window !== "undefined",
enabled: typeof window !== 'undefined',
},
}
},
},
/**
* Transformer used for data de-serialization from the server.
@@ -47,8 +46,8 @@ export const api = createTRPCNext<AppRouter>({
links: [
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === "development" ||
(opts.direction === "down" && opts.result instanceof Error),
process.env.NODE_ENV === 'development' ||
(opts.direction === 'down' && opts.result instanceof Error),
}),
httpLink({
url: `${getBaseUrl()}/api/trpc`,
@@ -78,10 +77,9 @@ export type RouterInputs = inferRouterInputs<AppRouter>;
*/
export type RouterOutputs = inferRouterOutputs<AppRouter>;
export function handleError(error: TRPCClientErrorBase<any>) {
toast({
title: 'Error',
description: error.message,
})
}
});
}

View File

@@ -1,9 +1,9 @@
import { toast } from "@/components/ui/use-toast"
import { toast } from '@/components/ui/use-toast';
export function clipboard(value: string | number) {
navigator.clipboard.writeText(value.toString())
navigator.clipboard.writeText(value.toString());
toast({
title: "Copied to clipboard",
title: 'Copied to clipboard',
description: value.toString(),
})
}
});
}

View File

@@ -1,6 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
return twMerge(clsx(inputs));
}

View File

@@ -1,47 +1,47 @@
export const operators = {
is: "Is",
isNot: "Is not",
contains: "Contains",
doesNotContain: "Not contains",
is: 'Is',
isNot: 'Is not',
contains: 'Contains',
doesNotContain: 'Not contains',
};
export const chartTypes = {
linear: "Linear",
bar: "Bar",
pie: "Pie",
metric: "Metric",
area: "Area",
linear: 'Linear',
bar: 'Bar',
pie: 'Pie',
metric: 'Metric',
area: 'Area',
};
export const intervals = {
minute: "Minute",
day: "Day",
hour: "Hour",
month: "Month",
minute: 'Minute',
day: 'Day',
hour: 'Hour',
month: 'Month',
};
export const alphabetIds = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
] as const;
export const timeRanges = [
{ range: 0.3, title: "30m" },
{ range: 0.6, title: "1h" },
{ range: 0, title: "Today" },
{ range: 1, title: "24h" },
{ range: 7, title: "7d" },
{ range: 14, title: "14d" },
{ range: 30, title: "30d" },
{ range: 90, title: "3mo" },
{ range: 180, title: "6mo" },
{ range: 365, title: "1y" },
{ range: 0.3, title: '30m' },
{ range: 0.6, title: '1h' },
{ range: 0, title: 'Today' },
{ range: 1, title: '24h' },
{ range: 7, title: '7d' },
{ range: 14, title: '14d' },
{ range: 30, title: '30d' },
{ range: 90, title: '3mo' },
{ range: 180, title: '6mo' },
{ range: 365, title: '1y' },
] as const;

View File

@@ -10,11 +10,11 @@ export function dateDifferanceInDays(date1: Date, date2: Date) {
}
export function getLocale() {
if (typeof navigator === "undefined") {
return "en-US";
if (typeof navigator === 'undefined') {
return 'en-US';
}
return navigator.language ?? "en-US";
return navigator.language ?? 'en-US';
}
export function formatDate(date: Date) {
@@ -23,10 +23,10 @@ export function formatDate(date: Date) {
export function formatDateTime(date: Date) {
return new Intl.DateTimeFormat(getLocale(), {
day: "numeric",
month: "numeric",
year: "numeric",
hour: "numeric",
minute: "numeric",
day: 'numeric',
month: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
}).format(date);
}

View File

@@ -1,8 +1,7 @@
import { type IChartRange } from "@/types";
import { timeRanges } from "./constants";
import { type IChartRange } from '@/types';
import { timeRanges } from './constants';
export function getRangeLabel(range: IChartRange) {
return timeRanges.find(
(item) => item.range === range,
)?.title ?? null
}
return timeRanges.find((item) => item.range === range)?.title ?? null;
}

View File

@@ -1,9 +1,9 @@
export function toDots(
obj: Record<string, unknown>,
path = "",
path = ''
): Record<string, number | string | boolean> {
return Object.entries(obj).reduce((acc, [key, value]) => {
if (typeof value === "object" && value !== null) {
if (typeof value === 'object' && value !== null) {
return {
...acc,
...toDots(value as Record<string, unknown>, `${path}${key}.`),
@@ -15,4 +15,4 @@ export function toDots(
[`${path}${key}`]: value,
};
}, {});
}
}

View File

@@ -1,4 +1,4 @@
import _slugify from 'slugify'
import _slugify from 'slugify';
const slugify = (str: string) => {
return _slugify(
@@ -9,10 +9,10 @@ const slugify = (str: string) => {
.replace('Å', 'A')
.replace('Ä', 'A')
.replace('Ö', 'O'),
{ lower: true, strict: true, trim: true },
)
}
{ lower: true, strict: true, trim: true }
);
};
export function slug(str: string): string {
return slugify(str)
return slugify(str);
}

View File

@@ -1,5 +1,7 @@
import resolveConfig from "tailwindcss/resolveConfig";
import tailwinConfig from "../../tailwind.config";
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwinConfig from '../../tailwind.config';
// @ts-expect-error
const config = resolveConfig(tailwinConfig);
@@ -7,7 +9,7 @@ export const theme = config.theme as any;
export function getChartColor(index: number): string {
const chartColors: string[] = Object.keys(theme?.colors ?? {})
.filter((key) => key.startsWith("chart-"))
.filter((key) => key.startsWith('chart-'))
.map((key) => theme.colors[key] as string);
return chartColors[index % chartColors.length]!;

View File

@@ -1,5 +1,6 @@
import { z } from "zod";
import { operators, chartTypes, intervals } from "./constants";
import { z } from 'zod';
import { chartTypes, intervals, operators } from './constants';
function objectToZodEnums<K extends string>(obj: Record<K, any>): [K, ...K[]] {
const [firstKey, ...otherKeys] = Object.keys(obj) as K[];
@@ -9,14 +10,14 @@ function objectToZodEnums<K extends string>(obj: Record<K, any>): [K, ...K[]] {
export const zChartEvent = z.object({
id: z.string(),
name: z.string(),
segment: z.enum(["event", "user"]),
segment: z.enum(['event', 'user']),
filters: z.array(
z.object({
id: z.string(),
name: z.string(),
operator: z.enum(objectToZodEnums(operators)),
value: z.array(z.string().or(z.number()).or(z.boolean()).or(z.null())),
}),
})
),
});
export const zChartBreakdown = z.object({