@leetnotion/leetcode-api
Version:
Get user profiles, submissions, and problems on LeetCode.
1,471 lines (1,453 loc) • 41.9 kB
text/typescript
import EventEmitter from 'eventemitter3';
import { Fetcher } from '@fetch-impl/fetcher';
interface CacheItem {
/**
* The key of the item.
*/
key: string;
/**
* The value of the item.
*/
value: unknown;
/**
* The expiration time of the item in milliseconds since the Unix epoch.
*/
expires: number;
}
/**
* A simple in-memory cache table.
*/
interface CacheTable {
[key: string]: CacheItem;
}
interface ICredential {
/**
* The authentication session.
*/
session?: string;
/**
* The csrf token.
*/
csrf?: string;
}
interface LeetCodeGraphQLQuery {
operationName?: string;
variables?: {
[key: string]: unknown;
};
query: string;
headers?: {
[key: string]: string;
};
/**
* Cache TTL in milliseconds. Set to 0 or omit to skip caching.
*/
cacheTime?: number;
}
interface LeetCodeGraphQLResponse {
data: any;
}
interface QuestionOfList {
difficulty: string;
id: number;
paidOnly: boolean;
questionFrontendId: string;
status: string;
title: string;
titleSlug: string;
topicTags: Array<{
title: string;
slug: string;
}>;
isInMyFavorites: boolean;
frequency: number | null;
acRate: number | null;
__typename: string;
}
declare abstract class BaseCredential implements ICredential {
/**
* The authentication session.
*/
session?: string;
/**
* The csrf token.
*/
csrf?: string;
constructor(data?: ICredential);
/**
* Fetch the CSRF token from the respective LeetCode endpoint.
*/
protected abstract fetchCsrf(): Promise<string | undefined>;
/**
* Init the credential with or without leetcode session cookie.
* @param session
* @returns
*/
init(session?: string): Promise<this>;
}
/**
* Cache class
*/
declare class Cache {
private _table;
/**
* Get an item from the cache.
* @param key The key of the item.
* @returns {any} The item, or null if it doesn't exist.
*/
get(key: string): unknown;
/**
* Set an item in the cache.
* @param key The key of the item.
* @param value The value of the item.
* @param expires The time in milliseconds until the item expires.
*/
set(key: string, value: unknown, expires?: number): void;
/**
* Remove an item from the cache.
* @param key The key of the item.
*/
remove(key: string): void;
/**
* Clear the cache.
*/
clear(): void;
/**
* Load the cache from a JSON string.
* @param json A {@link CacheTable}-like JSON string.
*/
load(json: string): void;
}
declare const cache: Cache;
declare const caches: {
[key: string]: Cache;
};
type Release = (value: void | PromiseLike<void>) => void;
declare class Mutex extends EventEmitter {
protected space: number;
protected used: number;
protected releases: Release[];
constructor(space?: number);
lock(): Promise<number>;
unlock(): number;
resize(space: number): number;
full(): boolean;
waiting(): number;
emit(event: 'lock' | 'unlock' | 'all-clear'): boolean;
emit(event: 'wait', { lock, release }: {
lock: Promise<void>;
release: Release;
}): boolean;
emit(event: string): boolean;
on(event: 'lock' | 'unlock' | 'all-clear', listener: () => void): this;
on(event: 'wait', listener: ({ lock, release }: {
lock: Promise<void>;
release: Release;
}) => void): this;
on(event: string, listener: (...args: unknown[]) => void): this;
once(event: 'lock' | 'unlock' | 'all-clear', listener: () => void): this;
once(event: 'wait', listener: ({ lock, release }: {
lock: Promise<void>;
release: Release;
}) => void): this;
once(event: string, listener: (...args: unknown[]) => void): this;
}
declare class RateLimiter extends Mutex {
private time_mutex;
private count;
private last;
private timer?;
interval: number;
constructor({ limit, interval, concurrent }?: {
limit?: number | undefined;
interval?: number | undefined;
concurrent?: number | undefined;
});
lock(): Promise<number>;
reset(): void;
cleaner(): void;
set limit(limit: number);
emit(event: 'lock' | 'unlock' | 'all-clear'): boolean;
emit(event: 'wait', { lock, release }: {
lock: Promise<void>;
release: Release;
}): boolean;
emit(event: 'time-lock' | 'time-unlock' | 'timer-reset'): boolean;
emit(event: string): boolean;
on(event: 'lock' | 'unlock' | 'all-clear', listener: () => void): this;
on(event: 'wait', listener: ({ lock, release }: {
lock: Promise<void>;
release: Release;
}) => void): this;
on(event: 'time-lock' | 'time-unlock' | 'timer-reset', listener: () => void): this;
on(event: string, listener: (...args: unknown[]) => void): this;
once(event: 'lock' | 'unlock' | 'all-clear', listener: () => void): this;
once(event: 'wait', listener: ({ lock, release }: {
lock: Promise<void>;
release: Release;
}) => void): this;
once(event: 'time-lock' | 'time-unlock' | 'timer-reset', listener: () => void): this;
once(event: string, listener: (...args: unknown[]) => void): this;
}
declare abstract class BaseLeetCode extends EventEmitter {
/**
* The credential this instance is using.
*/
credential: BaseCredential;
/**
* The internal cache.
*/
cache: Cache;
/**
* Used to ensure the instance is initialized.
*/
protected initialized: Promise<boolean>;
/**
* Rate limiter
*/
limiter: RateLimiter;
/**
* The base URL for API requests.
*/
protected abstract readonly baseUrl: string;
constructor(credential: BaseCredential | null, createCredential: () => BaseCredential, cache: Cache);
/**
* Use GraphQL to query LeetCode API.
* @param query
* @param endpoint The GraphQL endpoint path. Default is `/graphql`.
* @returns
*/
graphql(query: LeetCodeGraphQLQuery, endpoint?: string): Promise<LeetCodeGraphQLResponse>;
emit(event: 'receive-graphql', res: Response): boolean;
emit(event: 'update-csrf', credential: BaseCredential): boolean;
emit(event: string, ...args: unknown[]): boolean;
on(event: 'receive-graphql', listener: (res: Response) => void): this;
on(event: 'update-csrf', listener: (credential: BaseCredential) => void): this;
on(event: string, listener: (...args: unknown[]) => void): this;
once(event: 'receive-graphql', listener: (res: Response) => void): this;
once(event: 'update-csrf', listener: (credential: BaseCredential) => void): this;
once(event: string, listener: (...args: unknown[]) => void): this;
}
declare class Credential extends BaseCredential {
protected fetchCsrf(): Promise<string | undefined>;
}
interface QueryParams {
category?: string;
offset?: number;
limit?: number;
filters?: {
difficulty?: 'EASY' | 'MEDIUM' | 'HARD';
tags?: string[];
};
}
interface LeetcodeProblem {
title: string;
difficulty: ProblemDifficulty;
topicTags: TopicTag[];
companyTagStats: OfficialCompanyTagStats | null;
frequency: number;
similarQuestions: SimilarQuestion[] | string;
questionFrontendId: string;
isPaidOnly: boolean;
solution: LeetcodeSolution;
questionId: string;
likes: number;
dislikes: number;
stats: Stats | string;
titleSlug: string;
}
interface LeetcodeSolution {
url: string;
paidOnly: boolean;
hasVideoSolution: boolean;
}
interface DetailedProblem {
allowDiscuss?: boolean;
article?: Article;
categoryTitle?: string;
codeDefinition?: CodeDefinition[];
codeSnippets?: CodeSnippet[];
companyTagStats?: OfficialCompanyTagStats | null;
content?: string;
difficulty?: ProblemDifficulty;
dislikes?: number;
enableRunCode?: boolean;
enableSubmit?: boolean;
enableTestMode?: boolean;
frequency?: number;
hints?: string[];
infoVerified?: boolean;
interpretUrl?: string;
isLiked?: true | null;
isPaidOnly?: boolean;
judgeType?: string;
judgerAvailable?: boolean;
langToValidPlayground?: Record<string, boolean>;
libraryUrl?: string | null;
likes?: number;
metaData?: string;
mysqlSchemas?: string[];
nextChallengePairs?: NextChallengePair[] | null;
note?: string | null;
questionDetailUrl?: string;
questionFrontendId?: string;
questionId?: string;
questionTitle?: string;
questionTitleSlug?: string;
questionType?: string;
sampleTestCase?: string;
sessionId?: string;
similarQuestions?: SimilarQuestion[];
solution?: OfficialSolution;
stats?: Stats;
status?: string | null;
submitUrl?: string;
title?: string;
titleSlug?: string;
topicTags?: TopicTag[];
translatedContent?: string | null;
translatedTitle?: string | null;
}
interface LanguageListItem {
id: number;
name: string;
}
interface SubmittableLanguageListItem {
id: number;
name: string;
verboseName: string;
}
interface StatusListItem {
id: number;
name: string;
}
interface QuestionDiscussionTopic {
id: number;
commentCount: number;
topLevelCommentCount: number;
}
interface UgcArticleOfficialSolutionArticle {
uuid: string;
chargeType: string;
canSee: boolean;
hasVideoArticle: boolean;
}
interface PositionLevelTag {
name: string;
nameTranslated: string | null;
slug: string;
}
interface SimilarQuestionListItem {
difficulty: ProblemDifficulty;
titleSlug: string;
title: string;
translatedTitle: string | null;
isPaidOnly: boolean;
}
interface NextChallenge {
difficulty: ProblemDifficulty;
title: string;
titleSlug: string;
questionFrontendId: string;
}
interface FeaturedContest {
titleSlug: string;
title: string;
}
interface QuestionDetailQuestion {
title: string;
titleSlug: string;
questionId: string;
questionFrontendId: string;
questionTitle: string;
translatedTitle: string | null;
content: string;
translatedContent: string | null;
categoryTitle: string;
difficulty: ProblemDifficulty;
stats: string;
companyTagStatsV2: unknown;
topicTags: TopicTag[];
positionLevelTags: PositionLevelTag[];
similarQuestionList: SimilarQuestionListItem[];
mysqlSchemas: string[];
dataSchemas: string[];
frontendPreviews: string;
likes: number;
dislikes: number;
isPaidOnly: boolean;
status: string | null;
canSeeQuestion: boolean;
enableTestMode: boolean;
metaData: string;
enableRunCode: boolean;
enableSubmit: boolean;
enableDebugger: boolean;
envInfo: string;
isLiked: boolean | null;
nextChallenges: NextChallenge[];
libraryUrl: string | null;
adminUrl: string | null;
hints: string[];
codeSnippets: CodeSnippet[];
exampleTestcaseList: string[];
hasFrontendPreview: boolean;
featuredContests: FeaturedContest[];
}
interface QuestionDetail {
languageList: LanguageListItem[];
submittableLanguageList: SubmittableLanguageListItem[];
statusList: StatusListItem[];
questionDiscussionTopic: QuestionDiscussionTopic;
ugcArticleOfficialSolutionArticle: UgcArticleOfficialSolutionArticle | null;
question: QuestionDetailQuestion;
}
interface NextChallengePair {
question_title: string;
question_title_slug: string;
difficulty: 'E' | 'M' | 'H';
}
interface CodeDefinition {
value: string;
text: string;
defaultCode: string;
}
interface Article {
id: number;
url: string;
topicId: number;
}
interface SimilarQuestion {
title: string;
titleSlug: string;
difficulty: ProblemDifficulty;
translatedTitle: string | null;
}
interface CompanyTagStat {
company: string;
frequency: number;
}
interface OfficialCompanyTagStats {
[type: string]: {
taggedByAdmin: boolean;
name: string;
slug: string;
timesEncountered: number;
}[];
}
interface Stats {
totalAccepted: string;
totalSubmission: string;
totalAcceptedRaw: number;
totalSubmissionRaw: number;
acRate: string;
}
interface ProblemFieldDetails {
title: string;
property: keyof DetailedProblem;
graphql: string;
enable: boolean;
private: boolean;
isPremium: boolean;
needParsing: boolean;
needRequestChunking: boolean;
problemsPerRequest: number;
}
interface AllCompanyTags {
companyTags: CompanyTagDetail[];
}
interface MinimalCompanyTagDetail {
name: string;
questions: {
questionFrontendId: string;
}[];
}
interface TopicTagDetails {
questionFrontendId: string;
topicTags: {
name: string;
}[];
}
interface CompanyTagDetail {
id: string;
imgUrl: string;
name: string;
slug: string;
questionCount: number;
questionIds: number[];
frequencies: string;
}
interface EasterEggStatus {
isEasterEggCollected: boolean;
}
interface AllQuestionsCount {
difficulty: string;
count: number;
}
interface Contributions {
points: number;
questionCount: number;
testcaseCount: number;
}
interface Profile {
realName: string;
websites: string[];
countryName: string | null;
skillTags: string[];
company: string | null;
school: string | null;
starRating: number;
aboutMe: string;
userAvatar: string;
reputation: number;
ranking: number;
}
interface AcSubmissionNum {
difficulty: string;
count: number;
submissions: number;
}
interface TotalSubmissionNum {
difficulty: string;
count: number;
submissions: number;
}
interface SubmitStats {
acSubmissionNum: AcSubmissionNum[];
totalSubmissionNum: TotalSubmissionNum[];
}
interface Badge {
id: string;
displayName: string;
icon: string;
creationDate?: string;
}
interface MatchedUser {
username: string;
socialAccounts: unknown;
githubUrl: null;
contributions: Contributions;
profile: Profile;
submissionCalendar: string;
submitStats: SubmitStats;
badges: Badge[];
upcomingBadges: Badge[];
activeBadge: Badge | null;
}
interface UserProfile {
allQuestionsCount: AllQuestionsCount[];
matchedUser: MatchedUser | null;
recentSubmissionList: UserSubmission[] | null;
}
interface Contest {
title: string;
startTime: number;
}
interface ContestInfo {
attended: boolean;
trendDirection: string;
problemsSolved: number;
totalProblems: number;
finishTimeInSeconds: number;
rating: number;
ranking: number;
contest: Contest;
}
interface ContestRanking {
attendedContestsCount: number;
rating: number;
globalRanking: number;
totalParticipants: number;
topPercentage: number;
badge: null | {
name: string;
};
}
interface UserContestInfo {
userContestRanking: ContestRanking;
userContestRankingHistory: ContestInfo[];
}
interface TopicTag {
name: string;
slug: string;
translatedName: string | null;
}
interface CodeSnippet {
lang: string;
langSlug: string;
code: string;
}
interface CodeSnippet {
lang: string;
langSlug: string;
code: string;
}
interface OfficialSolution {
canSeeDetail: boolean;
content: string | null;
contentTypeId: string;
id: string;
rating: {
average: string;
count: number;
id: string;
userRating: {
id: string;
score: number;
} | null;
};
title: string;
url: string;
paidOnly: boolean;
hasVideoSolution: boolean;
paidOnlyVideo: boolean;
}
interface OfficialSolution {
id: string;
canSeeDetail: boolean;
paidOnly: boolean;
hasVideoSolution: boolean;
paidOnlyVideo: boolean;
}
interface ChallengeQuestion {
id: string;
date: string;
incompleteChallengeCount: number;
streakCount: number;
type: string;
}
interface ChallengeQuestion {
id: string;
date: string;
incompleteChallengeCount: number;
streakCount: number;
type: string;
}
type ProblemDifficulty = 'Easy' | 'Medium' | 'Hard';
interface Problem {
questionId: string;
questionFrontendId: string;
boundTopicId: unknown;
title: string;
titleSlug: string;
content: string;
translatedTitle: string | null;
translatedContent: string | null;
isPaidOnly: boolean;
difficulty: ProblemDifficulty;
likes: number;
dislikes: number;
isLiked: boolean | null;
similarQuestions: string;
exampleTestcases: string;
contributors: unknown[];
topicTags: TopicTag[];
companyTagStats: unknown;
codeSnippets: CodeSnippet[];
stats: string;
hints: string[];
solution: OfficialSolution;
status: unknown;
sampleTestCase: string;
metaData: string;
judgerAvailable: boolean;
judgeType: string;
mysqlSchemas: unknown[];
enableRunCode: boolean;
enableTestMode: boolean;
enableDebugger: boolean;
envInfo: string;
libraryUrl: string | null;
adminUrl: string | null;
challengeQuestion: ChallengeQuestion;
/** null if not logged in */
note: string | null;
}
type SubmissionStatus = 'Accepted' | 'Wrong Answer' | 'Time Limit Exceeded' | 'Memory Limit Exceeded' | 'Output Limit Exceeded' | 'Compile Error' | 'Runtime Error';
interface UserSubmission {
id: string;
isPending: string;
memory: string;
runtime: string;
time: string;
timestamp: string;
title: string;
titleSlug: string;
statusDisplay: SubmissionStatus;
lang: string;
url: string;
}
interface Submission {
id: number;
question_id: number;
lang: string;
lang_name: string;
time: string;
timestamp: number;
status: number;
status_display: SubmissionStatus;
runtime: string;
url: string;
is_pending: boolean;
title: string;
memory: number;
code: string;
compare_result: string;
title_slug: string;
has_notes: boolean;
flat_type: number;
}
interface SubmissionsDump {
submissions_dump: Submission[];
has_next: boolean;
last_key: string;
}
interface Whoami {
userId: number | null;
username: string;
avatar: string | null;
isSignedIn: boolean;
isMockUser: boolean;
isPremium: boolean | null;
isAdmin: boolean;
isSuperuser: boolean;
isTranslator: boolean;
activeSessionId: string;
checkedInToday: string;
permissions: string[];
}
interface SubmissionDetail {
id: number;
problem_id: number;
runtime: number;
runtime_distribution: [number, number][];
runtime_percentile: number;
memory: number;
memory_distribution: [number, number][];
memory_percentile: number;
code: string;
details: {
status_code: number;
runtime: string;
memory: string;
total_correct: string;
total_testcases: string;
compare_result: string;
input_formatted: string;
input: string;
expected_output: string;
code_output: string;
last_testcase: string;
};
}
interface ProblemList {
total: number;
questions: {
acRate: number;
difficulty: 'Easy' | 'Medium' | 'Hard';
freqBar: null;
questionFrontendId: string;
isFavor: boolean;
isPaidOnly: boolean;
status: string | null;
title: string;
titleSlug: string;
topicTags: {
name: string;
id: string;
slug: string;
}[];
hasSolution: boolean;
hasVideoSolution: boolean;
}[];
}
interface DailyChallenge {
date: string;
link: string;
question: Problem;
userStatus?: string;
}
interface List {
name: string;
slug: string;
}
interface ContestQuestion {
credit: number;
title: string;
title_slug: string;
category_slug: string;
difficulty: number;
}
interface ContestQuestions {
questions: ContestQuestion[];
}
interface PastContest {
titleSlug: string;
title: string;
titleCn: string;
startTime: number;
duration: number;
cardImg: string;
cardImgApp: string;
companyWatermark: string | null;
solved: number;
totalQuestions: number;
}
interface PastContests {
totalNum: number;
contests: PastContest[];
}
declare class LeetCode extends BaseLeetCode {
protected readonly baseUrl = "https://leetcode.com";
/**
* The credential this LeetCode instance is using.
*/
credential: Credential;
/**
* If a credential is provided, the LeetCode API will be authenticated. Otherwise, it will be anonymous.
* @param credential
* @param cache
*/
constructor(credential?: Credential | null, cache?: Cache);
/**
* Get public profile of a user.
* @param username
* @returns
*
* ```javascript
* const leetcode = new LeetCode();
* const profile = await leetcode.user("codewithsathya");
* ```
*/
user(username: string): Promise<UserProfile>;
/**
* Get public contest info of a user.
* @param username
* @returns
*
*/
user_contest_info(username: string): Promise<UserContestInfo>;
/**
* Get recent submissions of a user. (max: 20 submissions)
* @param username
* @param limit
* @returns
*
* ```javascript
* const leetcode = new LeetCode();
* const submissions = await leetcode.recent_user_submissions("codewitsathya");
* ```
*/
recent_user_submissions(username: string, limit?: number): Promise<UserSubmission[]>;
/**
* Get submissions of the credential user. Need to be authenticated.
*
* @returns
*
* ```javascript
* const credential = new Credential();
* await credential.init("SESSION");
* const leetcode = new LeetCode(credential);
* const submissions = await leetcode.submissions({ limit: 100, offset: 0 });
* ```
*/
submissions({ limit, offset, }?: {
limit?: number;
offset?: number;
slug?: string;
}): Promise<Submission[]>;
private submissionsApi;
/**
* Get detail of a submission, including the code and percentiles.
* Need to be authenticated.
* @param id Submission ID
* @returns
* @deprecated
*
*/
submission(id: number): Promise<SubmissionDetail>;
/**
* Get a list of problems by tags and difficulty.
* @param option
* @param option.category
* @param option.offset
* @param option.limit
* @param option.filters
* @returns
*/
problems({ category, offset, limit, filters, }?: QueryParams): Promise<ProblemList>;
/**
* Get information of a problem by its slug.
* @param slug
* @returns
*/
problem(slug: string): Promise<Problem>;
/**
* Get daily challenge.
* @returns
*
* @example
* ```javascript
* const leetcode = new LeetCode();
* const daily = await leetcode.daily();
* ```
*/
daily(): Promise<DailyChallenge>;
/**
* Check the information of the credential owner.
* @returns
*/
whoami(): Promise<Whoami>;
}
declare class CredentialCN extends BaseCredential {
protected fetchCsrf(): Promise<string | undefined>;
}
declare class LeetCodeCN extends BaseLeetCode {
protected readonly baseUrl = "https://leetcode.cn";
/**
* The credential this LeetCodeCN instance is using.
*/
credential: CredentialCN;
/**
* If a credential is provided, the LeetCodeCN API will be authenticated. Otherwise, it will be anonymous.
* @param credential
* @param cache
*/
constructor(credential?: CredentialCN | null, cache?: Cache);
/**
* Get public profile of a user.
* @param username
* @returns
*
* ```javascript
* const leetcode = new LeetCodeCN();
* const profile = await leetcode.user("codewithsathya");
* ```
*/
user(username: string): Promise<CNUserResult>;
/**
* Use GraphQL to query LeetCodeCN API.
* @param query
* @param endpoint Maybe you want to use `/graphql/noj-go/` instead of `/graphql/`.
* @returns
*/
graphql(...args: Parameters<BaseLeetCode['graphql']>): ReturnType<BaseLeetCode['graphql']>;
}
interface CNNumAcceptedQuestion {
difficulty: string;
count: number;
}
interface CNNumFailedQuestion {
difficulty: string;
count: number;
}
interface CNNumUntouchedQuestion {
difficulty: string;
count: number;
}
interface CNUserProfileUserQuestionProgress {
numAcceptedQuestions: CNNumAcceptedQuestion[];
numFailedQuestions: CNNumFailedQuestion[];
numUntouchedQuestions: CNNumUntouchedQuestion[];
}
interface CNMedal {
name: string;
year: number;
month: number;
category: string;
}
interface CNRanking {
currentLocalRanking: number;
currentGlobalRanking: number;
currentRating: string;
totalLocalUsers: number;
totalGlobalUsers: number;
}
interface CNSocialAccount {
provider: string;
profileUrl: string;
}
interface CNProfile {
userSlug: string;
realName: string;
aboutMe: string;
userAvatar: string;
location: string;
gender: string;
websites: unknown[];
skillTags: string[];
contestCount: number;
asciiCode: string;
medals: CNMedal[];
ranking: CNRanking;
socialAccounts: CNSocialAccount[];
}
interface CNUserProfilePublicProfile {
username: string;
haveFollowed?: unknown;
siteRanking: number;
profile: CNProfile;
}
interface CNUserResult {
userProfileUserQuestionProgress: CNUserProfileUserQuestionProgress;
userProfilePublicProfile: CNUserProfilePublicProfile;
}
declare const BASE_URL = "https://leetcode.com";
declare const BASE_URL_CN = "https://leetcode.cn";
declare const USER_AGENT = "Mozilla/5.0 LeetCode API";
declare const PROBLEM_CATEGORIES: string[];
declare const fetcher: Fetcher;
declare const _fetch: (input: string | URL | Request, init?: RequestInit | undefined) => ReturnType<typeof fetch>;
declare class LeetCodeAdvanced extends LeetCode {
problemProperties: ProblemFieldDetails[];
uniquePropertyOfProblem: string;
constructor(credential?: Credential | null, cache?: Cache);
setUniquePropertyOfProblem(property: string): void;
setCustomProblemProperties(problemProperties: ProblemFieldDetails[]): void;
/**
* Checks if easter egg is already collected.
* Need to be authenticated.
* @returns boolean
*/
isEasterEggCollected(): Promise<boolean>;
/**
* Collects easter egg if available.
* Need to be authenticated.
*/
collectEasterEgg(): Promise<boolean>;
/**
* Get all topic tags for each question with question frontend id as key
* @returns
*/
topicTags({ limit, problemsPerRequest, skip, }?: {
limit?: number;
problemsPerRequest?: number;
skip?: number;
}): Promise<Record<string, string[]>>;
/**
* Get all company tags with their details.
* For company wise question details, need to be authenticated and should be premium user.
* @returns
*/
companyTags(): Promise<CompanyTagDetail[]>;
/**
* Get question frontend id to company tags mapping.
* Need to be authenticated and should be premium user
* @returns
*/
getQuestionIdCompanyTagsMapping(): Promise<Record<string, string[]>>;
/**
* Checkin to collect a coin
* Need to be authenticated
*/
checkIn(): Promise<boolean>;
/**
* Get recent submission of current user.
* Need to be authenticated
* @returns Submission
* @returns null if there are no recent submissions
*/
recentSubmission(): Promise<Submission | null>;
/**
* Get recent submission of a user by username
* Need to be authenticated
* @param username
* @returns Submission
* @returns null if there are no recent submissions
*/
recentSubmissionOfUser(username: string): Promise<UserSubmission | null>;
/**
* Get no of total problems in leetcode right now.
* @returns number
*/
noOfProblems(): Promise<number>;
/**
* Get leetcode lists of the user
* Need to be authenticated
* @returns array of leetcode lists
*/
getLists(): Promise<Array<List>>;
/**
* Get all questions of a leetcode list
* Need to be authenticated
* @param slug slug id of the leetcode list
* @returns array of questions
*/
getQuestionsOfList(slug: string): Promise<Array<QuestionOfList>>;
/**
* Get problem types for all questions.
* @returns Record<string, string> - A mapping of question frontend IDs to their problem type.
*/
getProblemTypes(): Promise<Record<string, string>>;
/**
* Get leetcode problems with optional parameters.
* @param option
* @param option.limit - Total number of problems to fetch. Default is 10000.
* @param option.problemsPerRequest - Number of problems to fetch per request. Default is 100.
* @param option.skip - Number of problems to skip from the start. Default is 0.
* @param option.callbackFn - Optional callback function that will be called after each request with the currently fetched problems.
* @returns Array of LeetcodeProblem
*/
getLeetcodeProblems({ limit, problemsPerRequest, skip, callbackFn, }?: {
limit?: number;
problemsPerRequest?: number;
skip?: number;
callbackFn?: ((problems: LeetcodeProblem[]) => void) | null;
}): Promise<LeetcodeProblem[]>;
private parseProblems;
/**
* Get list of detailed problems by tags and difficulty.
* This will collect details according to the problemProperties configuration and this is slow.
* @param option
* @param option.category
* @param option.offset
* @param option.limit
* @param option.filters
* @returns DetailedProblem[]
*/
detailedProblems({ category, offset, limit, filters, }?: QueryParams): Promise<DetailedProblem[]>;
/**
* Get problems with a particular property and requests are sent according to the configuration.
* @param problemProperty
* @param QueryParams
* @returns DetailedProblem[]
*/
problemsOfProperty(problemProperty: ProblemFieldDetails, { category, offset, limit, filters }?: QueryParams): Promise<DetailedProblem[]>;
/**
* Get title slug question number mapping for all leetcode questions
* @returns Mapping
*/
getTitleSlugQuestionNumberMapping(): Promise<Record<string, string>>;
getQuestionDetailsByTitleSlug(titleSlug: string): Promise<QuestionDetail>;
/**
* Get questions of a contest by its slug.
* @param contestSlug - The slug of the contest (e.g., "weekly-contest-495").
* @returns ContestQuestions
*/
getContestQuestions(contestSlug: string): Promise<ContestQuestions>;
/**
* Get past contests history.
* @param option
* @param option.limit - Number of contests to fetch. Default is 30.
* @param option.skip - Number of contests to skip. Default is 0.
* @returns PastContests
*/
getPastContests({ limit, skip, }?: {
limit?: number;
skip?: number;
}): Promise<PastContests>;
private fetchCategoryQuestions;
private combineProperties;
private getProblemsQuery;
}
/** Result from /submissions/detail/$id/check/ polling */
interface JudgeResult {
ok: boolean;
lang: string;
runtime: string;
runtime_percentile: number | string;
memory: string;
memory_percentile: number | string;
state: string;
testcase: string;
passed: number;
total: number;
error: string[];
stdout: string;
answer: string | string[];
expected_answer: string | string[];
submission_id: string;
}
/** Raw response from /submissions/detail/$id/check/ */
interface JudgeCheckResponse {
state: 'PENDING' | 'STARTED' | 'SUCCESS';
run_success?: boolean;
status_msg?: string;
status_runtime?: string;
runtime_percentile?: number;
status_memory?: string;
memory_percentile?: number;
lang?: string;
input?: string;
last_testcase?: string;
code_output?: string | string[];
code_answer?: string | string[];
expected_code_answer?: string | string[];
expected_output?: string;
std_output?: string;
total_correct?: number;
total_testcases?: number;
runtime_error?: string;
compile_error?: string;
syntax_error?: string;
submission_id?: string;
}
/** Options for testing code */
interface TestCodeOptions {
slug: string;
lang: string;
questionId: number;
typedCode: string;
dataInput: string;
}
/** Options for submitting code */
interface SubmitCodeOptions {
slug: string;
lang: string;
questionId: number;
typedCode: string;
}
/** Response from interpret_solution endpoint */
interface InterpretResponse {
interpret_id: string;
interpret_expected_id?: string;
}
/** Response from submit endpoint */
interface SubmitResponse {
submission_id: number;
}
/** LeetCode session object */
interface LeetCodeSession {
id: number;
name: string;
is_active: boolean;
ac_questions: number;
submitted_questions: number;
total_acs: number;
total_submitted: number;
}
/** User favorites response */
interface FavoritesResponse {
user_name: string;
favorites: {
private_favorites: FavoriteList[];
public_favorites: FavoriteList[];
};
}
interface FavoriteList {
id_hash: string;
name: string;
is_public_favorite: boolean;
questions: number[];
}
/** Problem from the REST /api/problems/$category/ endpoint */
interface CategoryProblem {
id: number;
fid: number;
name: string;
slug: string;
link: string;
locked: boolean;
percent: number;
level: string;
state: string;
starred: boolean;
category: string;
}
/** Raw response from /api/problems/$category/ */
interface CategoryProblemsResponse {
user_name: string;
num_solved: number;
num_total: number;
ac_easy: number;
ac_medium: number;
ac_hard: number;
stat_status_pairs: {
stat: {
question_id: number;
frontend_question_id: number;
question__title: string;
question__title_slug: string;
question__hide: boolean;
total_acs: number;
total_submitted: number;
};
status: string | null;
difficulty: {
level: number;
};
paid_only: boolean;
is_favor: boolean;
}[];
category_slug: string;
}
/** Problem submission from REST /api/submissions/$slug */
interface ProblemSubmission {
id: string;
url: string;
status_display: string;
lang: string;
title: string;
timestamp: number;
runtime: string;
memory: string;
}
/** Result from getTopVotedSolutionId */
type TopVotedSolutionIdResult = {
totalNum: number;
topicId: number;
} | {
totalNum: 0;
};
/** Solution article returned by getSolutionById */
interface SolutionArticle {
uuid: string;
title: string;
slug: string;
summary: string;
author: {
realName: string;
userAvatar: string;
userSlug: string;
userName: string;
nameColor: string | null;
certificationLevel: string;
activeBadge: {
icon: string;
displayName: string;
} | null;
};
articleType: string;
thumbnail: string;
createdAt: string;
updatedAt: string;
status: string;
isLeetcode: boolean;
canSee: boolean;
canEdit: boolean;
isMyFavorite: boolean;
chargeType: string;
myReactionType: string | null;
topicId: number;
hitCount: number;
hasVideoArticle: boolean;
reactions: {
count: number;
reactionType: string;
}[];
tags: {
name: string;
slug: string;
tagType: string | null;
}[];
topic: {
id: number;
topLevelCommentCount: number;
};
content: string;
isSerialized: boolean;
isAuthorArticleReviewer: boolean | null;
scoreInfo: {
scoreCoefficient: number;
} | null;
prev: {
uuid: string;
slug: string;
topicId: string;
title: string;
} | null;
next: {
uuid: string;
slug: string;
topicId: string;
title: string;
} | null;
}
declare class LeetCodeCLI extends LeetCode {
/**
* Build standard auth headers for REST API calls.
*/
private authHeaders;
/**
* Handle CSRF update from response cookies.
*/
private handleCsrf;
/**
* Make a rate-limited REST request with automatic CSRF handling.
*/
private restRequest;
/**
* Poll /submissions/detail/$id/check/ until state is SUCCESS.
* @param id - The submission or interpret ID to check
* @param maxAttempts - Maximum number of polling attempts (default: 60)
*/
private pollJudgeResult;
/**
* Collect error messages from a judge check response.
*/
private collectErrors;
/**
* Format raw judge check response into a JudgeResult.
*/
private formatResult;
private formatTestOutput;
private formatSubmitOutput;
/**
* Test code against sample or custom test cases.
*/
testCode(options: TestCodeOptions): Promise<JudgeResult[]>;
/**
* Submit code for full judging.
*/
submitCode(options: SubmitCodeOptions): Promise<JudgeResult>;
/**
* Get user's favorite lists.
*/
getFavorites(): Promise<FavoritesResponse>;
/**
* Star (favorite) a problem.
*/
star(questionId: string, favoriteIdHash: string): Promise<void>;
/**
* Unstar (unfavorite) a problem.
*/
unstar(questionId: string, favoriteIdHash: string): Promise<void>;
/**
* Helper for session management REST calls.
*/
private sessionRequest;
/**
* List all coding sessions.
*/
getSessions(): Promise<LeetCodeSession[]>;
/**
* Create a new coding session.
*/
createSession(name: string): Promise<LeetCodeSession[]>;
/**
* Activate a coding session.
*/
activateSession(sessionId: number): Promise<LeetCodeSession[]>;
/**
* Delete a coding session.
*/
deleteSession(sessionId: number): Promise<LeetCodeSession[]>;
private static DIFFICULTY_MAP;
/**
* Get problems for a category via the REST API.
* Categories: 'algorithms', 'database', 'shell', 'concurrency'
*/
categoryProblems(category: string): Promise<CategoryProblem[]>;
/**
* Get problems from all categories.
*/
allCategoryProblems(): Promise<CategoryProblem[]>;
/**
* Get submissions for a specific problem by its slug.
* Returns the first 20 submissions.
*/
problemSubmissions(slug: string): Promise<ProblemSubmission[]>;
/**
* Get the topic ID of the top voted solution article for a problem.
*/
getTopVotedSolutionId(slug: string, lang?: string[]): Promise<TopVotedSolutionIdResult>;
/**
* Get a solution article by its topic ID.
*/
getSolutionById(topicId: number): Promise<SolutionArticle>;
/**
* Get the top voted solution for a problem.
*/
getTopVotedSolution(slug: string, lang?: string[]): Promise<SolutionArticle | null>;
}
export { type AcSubmissionNum, type AllCompanyTags, type AllQuestionsCount, type Article, BASE_URL, BASE_URL_CN, type Badge, BaseCredential, BaseLeetCode, Cache, type CacheItem, type CacheTable, type CategoryProblem, type CategoryProblemsResponse, type ChallengeQuestion, type CodeDefinition, type CodeSnippet, type CompanyTagDetail, type CompanyTagStat, type Contest, type ContestInfo, type ContestQuestion, type ContestQuestions, type ContestRanking, type Contributions, Credential, CredentialCN, type DailyChallenge, type DetailedProblem, type EasterEggStatus, type FavoriteList, type FavoritesResponse, type FeaturedContest, type ICredential, type InterpretResponse, type JudgeCheckResponse, type JudgeResult, type LanguageListItem, LeetCode, LeetCodeAdvanced, LeetCodeCLI, LeetCodeCN, type LeetCodeGraphQLQuery, type LeetCodeGraphQLResponse, type LeetCodeSession, type LeetcodeProblem, type LeetcodeSolution, type List, type MatchedUser, type MinimalCompanyTagDetail, Mutex, type NextChallenge, type NextChallengePair, type OfficialCompanyTagStats, type OfficialSolution, PROBLEM_CATEGORIES, type PastContest, type PastContests, type PositionLevelTag, type Problem, type ProblemDifficulty, type ProblemFieldDetails, type ProblemList, type ProblemSubmission, type Profile, type QueryParams, type QuestionDetail, type QuestionDetailQuestion, type QuestionDiscussionTopic, type QuestionOfList, RateLimiter, type Release, type SimilarQuestion, type SimilarQuestionListItem, type SolutionArticle, type Stats, type StatusListItem, type Submission, type SubmissionDetail, type SubmissionStatus, type SubmissionsDump, type SubmitCodeOptions, type SubmitResponse, type SubmitStats, type SubmittableLanguageListItem, type TestCodeOptions, type TopVotedSolutionIdResult, type TopicTag, type TopicTagDetails, type TotalSubmissionNum, USER_AGENT, type UgcArticleOfficialSolutionArticle, type UserContestInfo, type UserProfile, type UserSubmission, type Whoami, _fetch, cache, caches, LeetCode as default, _fetch as fetch, fetcher };