@pierre/diffs.Browse through 12 beautiful syntax themes. Use any Shiki theme or our custom Pierre themes designed for optimal diff readability.
1import { useState } from 'react';1import { useState, useCallback } from 'react';2
3function Counter() {4 const [count, setCount] = useState(0);3interface CounterProps {4 initial?: number;5 step?: number;6}7
8function Counter({ initial = 0, step = 1 }: CounterProps) {9 const [count, setCount] = useState(initial);10
11 const increment = useCallback(() => {12 setCount(c => c + step);13 }, [step]);14
15 const decrement = useCallback(() => {16 setCount(c => c - step);17 }, [step]);18
19 return (7 <div>20 <div className="counter">21 <p>Count: {count}</p>9 <button onClick={() => setCount(c => c + 1)}>10 Increment11 </button>22 <div className="buttons">23 <button onClick={decrement}>-</button>24 <button onClick={increment}>+</button>25 </div>26 </div>27 );28}Use disableFileHeader: true to completely replace the built-in chrome with your own header, footer, and toolbar.
1// String utilities2export function capitalize(str: string): string {3 if (!str) return str;4 return str.charAt(0).toUpperCase() + str.slice(1);5}6
6export function truncate(str: string, maxLength: number): string {7 if (str.length <= maxLength) return str;8 return str.slice(0, maxLength) + '...';7export function truncate(str: string, max: number, ellipsis = '…'): string {8 if (str.length <= max) return str;9 return str.slice(0, max) + ellipsis;10}11
12// Array utilities13export function unique<T>(array: T[]): T[] {14 return [...new Set(array)];15}16
16export function shuffle<T>(array: T[]): T[] {17 const result = [...array];18 for (let i = result.length - 1; i > 0; i--) {19 const j = Math.floor(Math.random() * (i + 1));20 [result[i], result[j]] = [result[j], result[i]];21 }22 return result;23}24
17// Object utilities18export function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {19 const result = {} as Pick<T, K>;20 for (const key of keys) {2 unmodified lines23 return result;24}25
26export function deepClone<T>(obj: T): T {35 return JSON.parse(JSON.stringify(obj));27 return structuredClone(obj);28}Use onLineEnter and onLineLeave callbacks to track hover state, then render contextual actions with renderHoverUtility. Perfect for code review workflows with comment, bookmark, and bug report actions.
1import { z } from 'zod';2
3const UserSchema = z.object({4 name: z.string().min(1),5 email: z.string().email(),6 role: z.enum(['admin', 'user', 'guest']),7});8
9export async function getUser(id: string) {10 const response = await fetch(`/api/users/${id}`);11 if (!response.ok) {12 throw new Error(`Failed to fetch user: ${response.status}`);13 }14 return response.json();15}16
6export async function updateUser(id: string, data: any) {17export async function updateUser(id: string, data: z.infer<typeof UserSchema>) {18 const validated = UserSchema.parse(data);19 const response = await fetch(`/api/users/${id}`, {20 method: 'PUT',9 body: JSON.stringify(data),21 headers: { 'Content-Type': 'application/json' },22 body: JSON.stringify(validated),23 });24 if (!response.ok) {25 throw new Error(`Failed to update user: ${response.status}`);26 }27 return response.json();28}Use annotations to display inline AI suggestions, warnings, and code improvements. Each annotation can have custom actions like accept, dismiss, or apply fix.
1import { hash, compare } from 'bcrypt';2import { sign, verify } from 'jsonwebtoken';3
4const SECRET = 'my-secret-key';5const SALT_ROUNDS = 10;4const SECRET = process.env.JWT_SECRET!; 5const SALT_ROUNDS = 12;6
7export async function hashPassword(password: string) {7export async function hashPassword(password: string): Promise<string> {8 return hash(password, SALT_ROUNDS);9}10
11export async function verifyPassword(password: string, hashed: string) {11export async function verifyPassword(12 password: string,13 hashed: string14): Promise<boolean> {15 return compare(password, hashed);16}17
15export function createToken(userId: string) {16 return sign({ userId }, SECRET, { expiresIn: '24h' });18export function createToken(userId: string, role: string = 'user'): string { 19 return sign({ userId, role }, SECRET, { expiresIn: '1h' });20}21
19export function verifyToken(token: string) {22export function verifyToken(token: string): TokenPayload | null {23 try {21 return verify(token, SECRET);24 return verify(token, SECRET) as TokenPayload;25 } catch {26 return null;27 }28}29
30interface TokenPayload {31 userId: string;32 role: string;33}Using non-null assertion on environment variable. Consider adding runtime validation.
const SECRET = process.env.JWT_SECRET;
if (!SECRET) throw new Error('JWT_SECRET not configured');Consider using a shorter token expiry for better security.
Build a complete PR review experience with file navigation, approval tracking, and inline comments. Collapse files, approve changes, and track review progress.
#42 opened by @developer
1import { useState, useEffect } from 'react';1import { useState, useEffect, useCallback } from 'react';2import type { User } from '@/types';3
4export function useAuth() {4 const [user, setUser] = useState(null);5 const [user, setUser] = useState<User | null>(null);6 const [loading, setLoading] = useState(true);7 const [error, setError] = useState<Error | null>(null);8
7 useEffect(() => {8 fetch('/api/me')9 .then(res => res.json())10 .then(setUser)11 .finally(() => setLoading(false));9 const refetch = useCallback(async () => {10 setLoading(true);11 setError(null);12 try {13 const res = await fetch('/api/me');14 if (!res.ok) throw new Error('Failed to fetch user');15 setUser(await res.json());16 } catch (e) {17 setError(e instanceof Error ? e : new Error('Unknown error'));18 } finally {19 setLoading(false);20 }21 }, []);22
14 return { user, loading };23 useEffect(() => {24 refetch();25 }, [refetch]);26
27 return { user, loading, error, refetch };28}1export interface User {2 id: string;3 email: string;4 name: string;5 avatar?: string;6 role: 'admin' | 'user';7 createdAt: Date;8}Use onLineEnter and onLineLeave to track hover state, then render blame info with renderHoverUtility. Displays author, commit message, and timestamp - just like GitLens in VS Code.
1{2 "name": "my-app",3 "version": "1.0.0",4 "description": "A simple application",5 "main": "index.js",3 "version": "2.0.0",4 "description": "A modern web application",5 "type": "module",6 "main": "src/index.ts",7 "scripts": {7 "start": "node index.js",8 "test": "jest"8 "start": "tsx src/index.ts",9 "dev": "tsx watch src/index.ts",10 "build": "tsc",11 "test": "vitest"12 },13 "dependencies": {11 "express": "^4.18.0"14 "express": "^4.21.0",15 "zod": "^3.23.0"16 },17 "devDependencies": {18 "typescript": "^5.6.0",19 "tsx": "^4.19.0",20 "vitest": "^2.1.0"21 }22}The onLineEnter callback updates React state with the hovered line number. This triggers a re-render, and renderHoverUtility uses that state to look up blame data and render an inline tooltip. In a real app, you'd fetch this from your git provider's API.