Reformat project with Prettier

This commit is contained in:
Xevion
2023-02-23 22:48:00 -06:00
parent 6e89c7738f
commit 9506f61e7e
8 changed files with 115 additions and 82 deletions

7
.prettierignore Normal file
View File

@@ -0,0 +1,7 @@
.next/
.vercel
.env
.gitignore
vercel.json
*.log
*.lock

View File

@@ -1,4 +1,5 @@
# bus-reminder # bus-reminder
![Location Check](https://cronitor.io/badges/8frC2k/production/XcmWhvdYm0OyCRuinS1IP6MEUiE.svg) ![Location Check](https://cronitor.io/badges/8frC2k/production/XcmWhvdYm0OyCRuinS1IP6MEUiE.svg)
A cron-job based personal notification system for myself. A cron-job based personal notification system for myself.
@@ -31,7 +32,7 @@ Next.js was complete overkill for this, and in retrospect, using something like
[cronitor]: https://cronitor.io [cronitor]: https://cronitor.io
[cron-jobs]: https://cron-jobs.org [cron-jobs]: https://cron-jobs.org
## TODO ## TODO
- Integrate Discord notifications - Integrate Discord notifications
- Create system for dynamically disabling the check for the rest of the day ([Upstash](upstash.com) for Redis) - Create system for dynamically disabling the check for the rest of the day ([Upstash](upstash.com) for Redis)

View File

@@ -1,6 +1,6 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
reactStrictMode: true, reactStrictMode: true,
} };
module.exports = nextConfig module.exports = nextConfig;

4
src/env/util.mjs vendored
View File

@@ -1,7 +1,7 @@
export const formatErrors = ( export const formatErrors = (
/** @type {import('zod').ZodFormattedError<Map<string,string>,string>} */ /** @type {import('zod').ZodFormattedError<Map<string,string>,string>} */
errors, errors
) => ) =>
Object.entries(errors) Object.entries(errors)
.map(([name, value]) => { .map(([name, value]) => {
if (value && "_errors" in value) if (value && "_errors" in value)

View File

@@ -2,7 +2,10 @@ import { env } from "@/env/server.mjs";
// @ts-ignore // @ts-ignore
import * as life360 from "life360-node-api"; import * as life360 from "life360-node-api";
const center = {longitude: env.CENTER_LONGITUDE, latitude: env.CENTER_LATITUDE}; const center = {
longitude: env.CENTER_LONGITUDE,
latitude: env.CENTER_LATITUDE,
};
const MILES_PER_NAUTICAL_MILE = 1.15078; const MILES_PER_NAUTICAL_MILE = 1.15078;
const KILOMETERS_PER_MILE = 1.60934; const KILOMETERS_PER_MILE = 1.60934;
@@ -24,10 +27,11 @@ export function distance(
const radlat2 = (Math.PI * b.latitude) / 180; const radlat2 = (Math.PI * b.latitude) / 180;
const theta = a.longitude - b.longitude; const theta = a.longitude - b.longitude;
const radtheta = (Math.PI * theta) / 180; const radtheta = (Math.PI * theta) / 180;
let dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); let dist =
Math.sin(radlat1) * Math.sin(radlat2) +
Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) if (dist > 1) dist = 1;
dist = 1;
dist = Math.acos(dist); dist = Math.acos(dist);
dist = (dist * 180) / Math.PI; dist = (dist * 180) / Math.PI;

View File

@@ -1,34 +1,45 @@
import {env} from "@/env/server.mjs"; import { env } from "@/env/server.mjs";
import {z} from "zod"; import { z } from "zod";
const BASE_URL = `https://cronitor.link/p/${env.CRONITOR_ACCOUNT_ID}/${env.CRONITOR_JOB_ID}`; const BASE_URL = `https://cronitor.link/p/${env.CRONITOR_ACCOUNT_ID}/${env.CRONITOR_JOB_ID}`;
const parameterSchema = z.object({ const parameterSchema = z.object({
env: z.string().optional(), env: z.string().optional(),
host: z.string().optional(), host: z.string().optional(),
message: z.string().optional(), message: z.string().optional(),
metric: z.union([ metric: z
z.object({count: z.number()}), .union([
z.object({duration: z.number()}), z.object({ count: z.number() }),
z.object({error_count: z.number()}), z.object({ duration: z.number() }),
]).optional(), z.object({ error_count: z.number() }),
])
.optional(),
series: z.string().optional(), series: z.string().optional(),
state: z.enum(["run", "complete", "fail", "ok"]).optional(), state: z.enum(["run", "complete", "fail", "ok"]).optional(),
status_code: z.number().int().optional(), status_code: z.number().int().optional(),
}) });
function buildURL(parameters: z.infer<typeof parameterSchema>) { function buildURL(parameters: z.infer<typeof parameterSchema>) {
const url = new URL(BASE_URL); const url = new URL(BASE_URL);
// Definite string properties // Definite string properties
const {env, host, message, series, state} = parameters; const { env, host, message, series, state } = parameters;
for (const [key, value] of Object.entries({env, host, message, series, state}).filter(([, value]) => value != undefined)) for (const [key, value] of Object.entries({
env,
host,
message,
series,
state,
}).filter(([, value]) => value != undefined))
url.searchParams.append(key, value!); url.searchParams.append(key, value!);
// Extract potentially undefined specified properties // Extract potentially undefined specified properties
if (parameters.metric != undefined) { if (parameters.metric != undefined) {
const {count, duration, error_count} = parameters.metric as {count?: number, duration?: number, error_count?: number}; const { count, duration, error_count } = parameters.metric as {
if (count != undefined) count?: number;
url.searchParams.append("metric", `count:${count}`); duration?: number;
error_count?: number;
};
if (count != undefined) url.searchParams.append("metric", `count:${count}`);
else if (duration != undefined) else if (duration != undefined)
url.searchParams.append("metric", `duration:${duration}`); url.searchParams.append("metric", `duration:${duration}`);
else if (error_count != undefined) else if (error_count != undefined)
@@ -45,18 +56,19 @@ function getDuration(start: Date, end: Date) {
return (end.getTime() - start.getTime()) / 1000; return (end.getTime() - start.getTime()) / 1000;
} }
/** /**
* Executes the given function while providing telemetry to Cronitor * Executes the given function while providing telemetry to Cronitor
* @param execute The function to execute * @param execute The function to execute
* @throws Any error thrown by the function will be rethrown. Cronitor will be notified of the failure. * @throws Any error thrown by the function will be rethrown. Cronitor will be notified of the failure.
*/ */
export default async function monitorAsync<T = any>(execute: () => Promise<T>): Promise<T> { export default async function monitorAsync<T = any>(
execute: () => Promise<T>
): Promise<T> {
// Tell Cronitor that the job is running // Tell Cronitor that the job is running
const start = new Date(); const start = new Date();
const series = start.getTime().toString(); const series = start.getTime().toString();
await fetch(buildURL({state: "run", series}).toString()); await fetch(buildURL({ state: "run", series }).toString());
console.log("Cronitor: Job started") console.log("Cronitor: Job started");
// Execute the function, provide try/catch // Execute the function, provide try/catch
let result: T | undefined = undefined; let result: T | undefined = undefined;
@@ -64,14 +76,23 @@ export default async function monitorAsync<T = any>(execute: () => Promise<T>):
result = await execute(); result = await execute();
} catch (error) { } catch (error) {
const duration = getDuration(start, new Date()); const duration = getDuration(start, new Date());
await fetch(buildURL({state: "fail", series, message: error instanceof Error ? error.message : undefined, metric: {duration}}).toString()); await fetch(
buildURL({
state: "fail",
series,
message: error instanceof Error ? error.message : undefined,
metric: { duration },
}).toString()
);
throw error; throw error;
} }
// Tell Cronitor that the job is complete (success) // Tell Cronitor that the job is complete (success)
console.log("Cronitor: Job completed") console.log("Cronitor: Job completed");
const duration = getDuration(start, new Date()); const duration = getDuration(start, new Date());
await fetch(buildURL({state: "complete", series, metric: {duration}}).toString()); await fetch(
buildURL({ state: "complete", series, metric: { duration } }).toString()
);
return result as T; return result as T;
} }

View File

@@ -18,7 +18,7 @@ const center = {
export default async function handler( export default async function handler(
req: NextApiRequest, req: NextApiRequest,
res: NextApiResponse<ResponseData & StatusData | StatusData> res: NextApiResponse<(ResponseData & StatusData) | StatusData>
) { ) {
if (req.query.key != env.API_KEY) { if (req.query.key != env.API_KEY) {
// auth failed // auth failed