-
Git
|--------------------------------------------------|-----------------------------------------------------------------------------------------------|
| `git blame -L 28,43 path/to/file` | Shows who modified each line in a specific range of a file. |
| `git blame -L :'class LocalFile' filepath` | Blames a block of code in a file matching a specific pattern. |
| `git log -L28,43:filepath` | Lists commits that last touched a specified region of a file. |
| `git blame -w` | Ignores whitespace changes in `git blame`. |
| `git blame -C` | Follows code movement across files in `git blame`. Can be used up to three times. |
| `git diff --word-diff` | Shows word-level differences in `git diff` output. |
| `git config --global rerere.enabled true` | Enables reuse of recorded resolution of conflicts. |
| `git config --global rerere.autoUpdate true` | Automatically updates the index with the result of rerere resolution. |
| `git config --global branch.sort -committerdate` | Sorts branches by last commit date in descending order. |
| `git push --force-with-lease` | Safely force-pushes, ensuring no updates were pushed to the branch since your last fetch. |
| `git maintenance start` | Starts Git maintenance tasks to optimize repository performance. |
-
Usefull bash commands
fd -HI node_modules -X rm -rf
-
Typescript tips and tricks. This is update whenever I come across something cool
type CreateAPIMethod = <
TInput extends Record<string, string>,
TOutput
>(opts: {
url: string;
method: "GET" | "POST"
}) = (input: TInput) = Promise<TOutput>;
declare const createAPIMethod: CreateAPIMethod;
const getUser = createAPIMethod<
{ id: string },
{ name: string }
>({
method: "GET", url: "/user",
})
getUser({ id: 123 });
type IconSize =
| "small"
| "medium"
| "large"
| (string & {});
type RemovePrefix<T, Prefix extends string> = {
[K in keyof T as K extends `${Prefix}_${infer _}` ? never : K]: T[K]
};
function throttle<T extends (...args: any[]) => any>(fn: T, wait: number): (...funcArgs: Parameters<T>) => void {
let isThrottling: boolean = false;
let lastArgs: Parameters<T> | null = null;
let lastThis: ThisParameterType<T> | null = null;
const call = () => {
if (lastArgs === null || lastThis === null) {
isThrottling = false;
return;
}
fn.apply(lastThis, lastArgs);
lastArgs = null;
lastThis = null;
setTimeout(call, wait);
};
return function(this: ThisParameterType<T>, ...args: Parameters<T>): void {
if (isThrottling) {
lastArgs = args;
lastThis = this;
return;
}
fn.apply(this, args);
isThrottling = true;
setTimeout(() => {
isThrottling = false;
call();
}, wait);
};
}
-
The CSS property to prevent scrollbar pushing the layout
.scrollbar {
scrollbar-gutter: stable;
}
-
A simple HTTP service to wrap fetch services with abstraction to handle errors
export type FetchStrategy = (
url: string,
options?: RequestInit
) => Promise<Response>;
export default class HttpService {
private fetchStrategy: FetchStrategy;
constructor(fetchStrategy: FetchStrategy = fetch) {
this.fetchStrategy = fetchStrategy;
}
async fetchHandler<T = unknown>(
url: string,
options?: RequestInit
): Promise<T> {
try {
const response = await this.fetchStrategy(url, options);
if (!response.ok) {
throw new HttpError(
`HTTP Error: ${response.status} - ${response.statusText}`,
response.status
);
}
const data = (await response.json()) as T;
return data;
} catch (error) {
throw new RequestError(`Request failed: ${error.message}`);
}
}
async get<T = unknown>(url: string, options?: RequestInit): Promise<T> {
return this.fetchHandler<T>(url, options);
}
async post<T = unknown>(
url: string,
body: Record<string, unknown> | BodyInit | null = null,
options?: Omit<RequestInit, "method" | "body">
): Promise<T> {
return this.fetchHandler<T>(url, {
method: "POST",
body: body ? JSON.stringify(body) : null,
...options
});
}
}
class HttpError extends Error {
constructor(message: string, public statusCode: number) {
super(message);
this.name = "HttpError";
}
}
class RequestError extends Error {
constructor(message: string) {
super(message);
this.name = "RequestError";
}
}
export const FetchService: HttpService = new HttpService(
globalThis.fetch.bind(globalThis)
);
const authFetch: FetchStrategy = async (url, options) => {
return fetch(`${baseUrl}${url}`, {
credentials: "include",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
...headers
},
...options
});
};
export const AuthService = new HttpService(authFetch);
-
A simple way for error handling in Typescript
enum ResultKind {
OK = "Ok",
ERR = "Err",
}
export type Result<T, E> = Ok<T> | Err<E>;
interface ResultBase<A, E> {
kind: ResultKind;
map<B>(fn: (_: A) => B): Result<B, E>;
bind<B>(fn: (_: A) => Result<B, E>): Result<B, E>;
match<B>(obj: { ok: (_: A) => B; err: (_: E) => B }): B;
}
export type Ok<A> = Readonly<ResultBase<A, never> & { kind: ResultKind.OK; value: A }>;
export function ok<A>(a: A): Ok<A> {
return {
kind: ResultKind.OK,
value: a,
map(fn) {
return ok(fn(this.value));
},
bind(fn) {
return fn(this.value);
},
match({ ok }) {
return ok(this.value);
},
};
}
export type Err<E> = Readonly<ResultBase<never, E> & { kind: ResultKind.ERR; error: E }>;
export function err<E>(e: E): Err<E> {
return {
kind: ResultKind.ERR,
error: e,
map() {
return this;
},
bind() {
return this;
},
match({ err }) {
return err(this.error);
},
};
}
-
ZOD
import { zodResolver } from "@hookform/resolvers/zod";
import { type UseFormProps, useForm } from "react-hook-form";
import { type z } from "zod";
export default function useZodForm<TSchema extends z.ZodType>(
props: Omit<UseFormProps<TSchema["_input"]>, "resolver"> & {
schema: TSchema;
},
) {
const form = useForm<TSchema["_input"]>({
...props,
resolver: zodResolver(props.schema, undefined, {
raw: true,
}),
});
return form;
}
export function safeLoader<
LoaderInputs extends any[],
OutputValidation extends ZodTypeAny,
>({
outputValidation,
loader,
}: {
outputValidation: OutputValidation;
loader: (...argsList: LoaderInputs) => any;
}) {
return async function (
...args: LoaderInputs
): Promise<z.infer<OutputValidation>> {
const outputs = await loader.apply(null, args);
const parsedOutput = outputValidation.parse(outputs);
return parsedOutput;
};
}