Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d906371

Browse files
committed
feat: add user notes feature for LeetCode CN
1 parent fced29b commit d906371

File tree

6 files changed

+407
-0
lines changed

6 files changed

+407
-0
lines changed

‎src/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { LeetCodeServiceFactory } from "./leetcode/leetcode-service-factory.js";
1010
import { registerProblemResources } from "./mcp/resources/problem-resources.js";
1111
import { registerSolutionResources } from "./mcp/resources/solution-resources.js";
1212
import { registerContestTools } from "./mcp/tools/contest-tools.js";
13+
import { registerNoteTools } from "./mcp/tools/note-tools.js";
1314
import { registerProblemTools } from "./mcp/tools/problem-tools.js";
1415
import { registerSolutionTools } from "./mcp/tools/solution-tools.js";
1516
import { registerUserTools } from "./mcp/tools/user-tools.js";
@@ -92,6 +93,7 @@ async function main() {
9293
registerUserTools(server, leetcodeService);
9394
registerContestTools(server, leetcodeService);
9495
registerSolutionTools(server, leetcodeService);
96+
registerNoteTools(server, leetcodeService);
9597

9698
registerProblemResources(server, leetcodeService);
9799
registerSolutionResources(server, leetcodeService);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* GraphQL query for fetching user notes on LeetCode CN
3+
* This query allows retrieving notes with pagination, filtering, and sorting options
4+
*
5+
* @param orderBy - Optional sorting criteria for notes (e.g., "ASCENDING", "DESCENDING")
6+
*/
7+
export const NOTE_AGGREGATE_QUERY = `
8+
query noteAggregateNote(
9+
$aggregateType: AggregateNoteEnum!
10+
$keyword: String
11+
$orderBy: AggregateNoteSortingOrderEnum
12+
$limit: Int = 100
13+
$skip: Int = 0
14+
) {
15+
noteAggregateNote(
16+
aggregateType: $aggregateType
17+
keyword: $keyword
18+
orderBy: $orderBy
19+
limit: $limit
20+
skip: $skip
21+
) {
22+
count
23+
userNotes {
24+
id
25+
summary
26+
content
27+
... on NoteAggregateQuestionNoteNode {
28+
noteQuestion {
29+
linkTemplate
30+
questionId
31+
title
32+
translatedTitle
33+
}
34+
}
35+
}
36+
}
37+
}`;
38+
39+
/**
40+
* GraphQL query for fetching user notes for a specific question ID on LeetCode CN
41+
*/
42+
export const NOTE_BY_QUESTION_ID_QUERY = `
43+
query noteOneTargetCommonNote(
44+
$noteType: NoteCommonTypeEnum!
45+
$questionId: String!
46+
$limit: Int = 20
47+
$skip: Int = 0
48+
) {
49+
noteOneTargetCommonNote(
50+
noteType: $noteType
51+
targetId: $questionId
52+
limit: $limit
53+
skip: $skip
54+
) {
55+
count
56+
userNotes {
57+
id
58+
summary
59+
content
60+
}
61+
}
62+
}`;

‎src/leetcode/leetcode-base-service.ts‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,41 @@ export interface LeetCodeBaseService {
170170
* @returns Promise resolving to the solution article detail data
171171
*/
172172
fetchSolutionArticleDetail(identifier: string): Promise<any>;
173+
174+
/**
175+
* Retrieves user notes from LeetCode with filtering and pagination options.
176+
* Note: This feature is only available on LeetCode CN.
177+
*
178+
* @param options - Query parameters for filtering notes
179+
* @param options.aggregateType - Type of notes to aggregate (e.g., "QUESTION_NOTE")
180+
* @param options.keyword - Optional search term to filter notes
181+
* @param options.orderBy - Optional sorting criteria for notes
182+
* @param options.limit - Maximum number of notes to return
183+
* @param options.skip - Number of notes to skip (for pagination)
184+
* @returns Promise resolving to the filtered notes data
185+
* @throws Error if not implemented or feature not supported
186+
*/
187+
fetchUserNotes(options: {
188+
aggregateType: string;
189+
keyword?: string;
190+
orderBy?: string;
191+
limit?: number;
192+
skip?: number;
193+
}): Promise<any>;
194+
195+
/**
196+
* Retrieves user notes for a specific question ID.
197+
* Note: This feature is only available on LeetCode CN.
198+
*
199+
* @param questionId - The question ID to fetch notes for
200+
* @param limit - Maximum number of notes to return
201+
* @param skip - Number of notes to skip (for pagination)
202+
* @returns Promise resolving to the notes data for the specified question
203+
* @throws Error if not implemented or feature not supported
204+
*/
205+
fetchNotesByQuestionId(
206+
questionId: string,
207+
limit?: number,
208+
skip?: number
209+
): Promise<any>;
173210
}

‎src/leetcode/leetcode-cn-service.ts‎

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { Credential, LeetCodeCN } from "leetcode-query";
2+
import {
3+
NOTE_AGGREGATE_QUERY,
4+
NOTE_BY_QUESTION_ID_QUERY
5+
} from "./graphql/cn/note-queries.js";
26
import { SEARCH_PROBLEMS_QUERY } from "./graphql/cn/search-problems.js";
37
import { SOLUTION_ARTICLE_DETAIL_QUERY } from "./graphql/cn/solution-article-detail.js";
48
import { SOLUTION_ARTICLES_QUERY } from "./graphql/cn/solution-articles.js";
@@ -358,6 +362,107 @@ export class LeetCodeCNService implements LeetCodeBaseService {
358362
}
359363
}
360364

365+
/**
366+
* Retrieves user notes from LeetCode CN with filtering and pagination options.
367+
* Available only on LeetCode CN platform.
368+
*
369+
* @param options - Query parameters for filtering notes
370+
* @param options.aggregateType - Type of notes to aggregate (e.g., "QUESTION_NOTE")
371+
* @param options.keyword - Optional search term to filter notes
372+
* @param options.orderBy - Optional sorting criteria for notes
373+
* @param options.limit - Maximum number of notes to return
374+
* @param options.skip - Number of notes to skip (for pagination)
375+
* @returns Promise resolving to the filtered notes data
376+
*/
377+
async fetchUserNotes(options: {
378+
aggregateType: string;
379+
keyword?: string;
380+
orderBy?: string;
381+
limit?: number;
382+
skip?: number;
383+
}): Promise<any> {
384+
if (!this.isAuthenticated()) {
385+
throw new Error("Authentication required to fetch user notes");
386+
}
387+
388+
try {
389+
const variables = {
390+
aggregateType: options.aggregateType,
391+
keyword: options.keyword,
392+
orderBy: options.orderBy || "DESCENDING",
393+
limit: options.limit || 20,
394+
skip: options.skip || 0
395+
};
396+
397+
return await this.leetCodeApi
398+
.graphql({
399+
query: NOTE_AGGREGATE_QUERY,
400+
variables
401+
})
402+
.then((response) => {
403+
return (
404+
response.data?.noteAggregateNote || {
405+
count: 0,
406+
userNotes: []
407+
}
408+
);
409+
});
410+
} catch (error) {
411+
console.error(`Error fetching user notes:`, error);
412+
throw error;
413+
}
414+
}
415+
416+
/**
417+
* Retrieves user notes for a specific question ID.
418+
* Available only on LeetCode CN platform.
419+
*
420+
* @param questionId - The question ID to fetch notes for
421+
* @param limit - Maximum number of notes to return (default: 20)
422+
* @param skip - Number of notes to skip (default: 0)
423+
* @returns Promise resolving to the notes data for the specified question
424+
*/
425+
async fetchNotesByQuestionId(
426+
questionId: string,
427+
limit: number = 20,
428+
skip: number = 0
429+
): Promise<any> {
430+
if (!this.isAuthenticated()) {
431+
throw new Error(
432+
"Authentication required to fetch notes by question ID"
433+
);
434+
}
435+
436+
try {
437+
const variables = {
438+
noteType: "COMMON_QUESTION",
439+
questionId: questionId,
440+
limit,
441+
skip
442+
};
443+
444+
return await this.leetCodeApi
445+
.graphql({
446+
query: NOTE_BY_QUESTION_ID_QUERY,
447+
variables
448+
})
449+
.then((response) => {
450+
return (
451+
response.data?.noteOneTargetCommonNote || {
452+
count: 0,
453+
userNotes: []
454+
}
455+
);
456+
});
457+
} catch (error) {
458+
console.error(
459+
`Error fetching notes for question ${questionId}:`,
460+
error
461+
);
462+
throw error;
463+
}
464+
}
465+
361466
isAuthenticated(): boolean {
362467
return (
363468
!!this.credential &&

‎src/leetcode/leetcode-global-service.ts‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,40 @@ export class LeetCodeGlobalService implements LeetCodeBaseService {
350350
}
351351
}
352352

353+
/**
354+
* Note feature is not supported in LeetCode Global.
355+
* This method is implemented to satisfy the interface but will always throw an error.
356+
*
357+
* @param options - Query parameters (not used)
358+
* @throws Error indicating the feature is not supported on Global platform
359+
*/
360+
async fetchUserNotes(options: {
361+
aggregateType: string;
362+
keyword?: string;
363+
orderBy?: string;
364+
limit?: number;
365+
skip?: number;
366+
}): Promise<any> {
367+
throw new Error("Notes feature is not supported in LeetCode Global");
368+
}
369+
370+
/**
371+
* Note feature is not supported in LeetCode Global.
372+
* This method is implemented to satisfy the interface but will always throw an error.
373+
*
374+
* @param questionId - The question ID (not used)
375+
* @param limit - Maximum number of notes (not used)
376+
* @param skip - Pagination offset (not used)
377+
* @throws Error indicating the feature is not supported on Global platform
378+
*/
379+
async fetchNotesByQuestionId(
380+
questionId: string,
381+
limit?: number,
382+
skip?: number
383+
): Promise<any> {
384+
throw new Error("Notes feature is not supported in LeetCode Global");
385+
}
386+
353387
isAuthenticated(): boolean {
354388
return (
355389
!!this.credential &&

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /