@mhalder/qdrant-mcp-server 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.codecov.yml +16 -0
  2. package/CHANGELOG.md +25 -0
  3. package/README.md +304 -9
  4. package/build/code/chunker/base.d.ts +19 -0
  5. package/build/code/chunker/base.d.ts.map +1 -0
  6. package/build/code/chunker/base.js +5 -0
  7. package/build/code/chunker/base.js.map +1 -0
  8. package/build/code/chunker/character-chunker.d.ts +22 -0
  9. package/build/code/chunker/character-chunker.d.ts.map +1 -0
  10. package/build/code/chunker/character-chunker.js +111 -0
  11. package/build/code/chunker/character-chunker.js.map +1 -0
  12. package/build/code/chunker/tree-sitter-chunker.d.ts +29 -0
  13. package/build/code/chunker/tree-sitter-chunker.d.ts.map +1 -0
  14. package/build/code/chunker/tree-sitter-chunker.js +213 -0
  15. package/build/code/chunker/tree-sitter-chunker.js.map +1 -0
  16. package/build/code/config.d.ts +11 -0
  17. package/build/code/config.d.ts.map +1 -0
  18. package/build/code/config.js +145 -0
  19. package/build/code/config.js.map +1 -0
  20. package/build/code/indexer.d.ts +42 -0
  21. package/build/code/indexer.d.ts.map +1 -0
  22. package/build/code/indexer.js +508 -0
  23. package/build/code/indexer.js.map +1 -0
  24. package/build/code/metadata.d.ts +32 -0
  25. package/build/code/metadata.d.ts.map +1 -0
  26. package/build/code/metadata.js +128 -0
  27. package/build/code/metadata.js.map +1 -0
  28. package/build/code/scanner.d.ts +35 -0
  29. package/build/code/scanner.d.ts.map +1 -0
  30. package/build/code/scanner.js +108 -0
  31. package/build/code/scanner.js.map +1 -0
  32. package/build/code/sync/merkle.d.ts +45 -0
  33. package/build/code/sync/merkle.d.ts.map +1 -0
  34. package/build/code/sync/merkle.js +116 -0
  35. package/build/code/sync/merkle.js.map +1 -0
  36. package/build/code/sync/snapshot.d.ts +41 -0
  37. package/build/code/sync/snapshot.d.ts.map +1 -0
  38. package/build/code/sync/snapshot.js +91 -0
  39. package/build/code/sync/snapshot.js.map +1 -0
  40. package/build/code/sync/synchronizer.d.ts +53 -0
  41. package/build/code/sync/synchronizer.d.ts.map +1 -0
  42. package/build/code/sync/synchronizer.js +132 -0
  43. package/build/code/sync/synchronizer.js.map +1 -0
  44. package/build/code/types.d.ts +98 -0
  45. package/build/code/types.d.ts.map +1 -0
  46. package/build/code/types.js +5 -0
  47. package/build/code/types.js.map +1 -0
  48. package/build/index.js +321 -6
  49. package/build/index.js.map +1 -1
  50. package/build/prompts/index.d.ts +7 -0
  51. package/build/prompts/index.d.ts.map +1 -0
  52. package/build/prompts/index.js +7 -0
  53. package/build/prompts/index.js.map +1 -0
  54. package/build/prompts/index.test.d.ts +2 -0
  55. package/build/prompts/index.test.d.ts.map +1 -0
  56. package/build/prompts/index.test.js +25 -0
  57. package/build/prompts/index.test.js.map +1 -0
  58. package/build/prompts/loader.d.ts +25 -0
  59. package/build/prompts/loader.d.ts.map +1 -0
  60. package/build/prompts/loader.js +81 -0
  61. package/build/prompts/loader.js.map +1 -0
  62. package/build/prompts/loader.test.d.ts +2 -0
  63. package/build/prompts/loader.test.d.ts.map +1 -0
  64. package/build/prompts/loader.test.js +417 -0
  65. package/build/prompts/loader.test.js.map +1 -0
  66. package/build/prompts/template.d.ts +20 -0
  67. package/build/prompts/template.d.ts.map +1 -0
  68. package/build/prompts/template.js +52 -0
  69. package/build/prompts/template.js.map +1 -0
  70. package/build/prompts/template.test.d.ts +2 -0
  71. package/build/prompts/template.test.d.ts.map +1 -0
  72. package/build/prompts/template.test.js +163 -0
  73. package/build/prompts/template.test.js.map +1 -0
  74. package/build/prompts/types.d.ts +34 -0
  75. package/build/prompts/types.d.ts.map +1 -0
  76. package/build/prompts/types.js +5 -0
  77. package/build/prompts/types.js.map +1 -0
  78. package/examples/code-search/README.md +271 -0
  79. package/package.json +13 -1
  80. package/prompts.example.json +96 -0
  81. package/src/code/chunker/base.ts +22 -0
  82. package/src/code/chunker/character-chunker.ts +131 -0
  83. package/src/code/chunker/tree-sitter-chunker.ts +250 -0
  84. package/src/code/config.ts +156 -0
  85. package/src/code/indexer.ts +613 -0
  86. package/src/code/metadata.ts +153 -0
  87. package/src/code/scanner.ts +124 -0
  88. package/src/code/sync/merkle.ts +136 -0
  89. package/src/code/sync/snapshot.ts +110 -0
  90. package/src/code/sync/synchronizer.ts +154 -0
  91. package/src/code/types.ts +117 -0
  92. package/src/index.ts +382 -5
  93. package/src/prompts/index.test.ts +29 -0
  94. package/src/prompts/index.ts +7 -0
  95. package/src/prompts/loader.test.ts +494 -0
  96. package/src/prompts/loader.ts +90 -0
  97. package/src/prompts/template.test.ts +212 -0
  98. package/src/prompts/template.ts +69 -0
  99. package/src/prompts/types.ts +37 -0
  100. package/tests/code/chunker/character-chunker.test.ts +141 -0
  101. package/tests/code/chunker/tree-sitter-chunker.test.ts +275 -0
  102. package/tests/code/fixtures/sample-py/calculator.py +32 -0
  103. package/tests/code/fixtures/sample-ts/async-operations.ts +120 -0
  104. package/tests/code/fixtures/sample-ts/auth.ts +31 -0
  105. package/tests/code/fixtures/sample-ts/config.ts +52 -0
  106. package/tests/code/fixtures/sample-ts/database.ts +50 -0
  107. package/tests/code/fixtures/sample-ts/index.ts +39 -0
  108. package/tests/code/fixtures/sample-ts/types-advanced.ts +132 -0
  109. package/tests/code/fixtures/sample-ts/utils.ts +105 -0
  110. package/tests/code/fixtures/sample-ts/validator.ts +169 -0
  111. package/tests/code/indexer.test.ts +828 -0
  112. package/tests/code/integration.test.ts +708 -0
  113. package/tests/code/metadata.test.ts +457 -0
  114. package/tests/code/scanner.test.ts +131 -0
  115. package/tests/code/sync/merkle.test.ts +406 -0
  116. package/tests/code/sync/snapshot.test.ts +360 -0
  117. package/tests/code/sync/synchronizer.test.ts +501 -0
  118. package/vitest.config.ts +1 -0
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Advanced TypeScript type features
3
+ */
4
+
5
+ // Generic constraints
6
+ export interface Identifiable {
7
+ id: string | number;
8
+ }
9
+
10
+ export class Repository<T extends Identifiable> {
11
+ private items: Map<string | number, T> = new Map();
12
+
13
+ add(item: T): void {
14
+ this.items.set(item.id, item);
15
+ }
16
+
17
+ get(id: string | number): T | undefined {
18
+ return this.items.get(id);
19
+ }
20
+
21
+ getAll(): T[] {
22
+ return Array.from(this.items.values());
23
+ }
24
+
25
+ remove(id: string | number): boolean {
26
+ return this.items.delete(id);
27
+ }
28
+ }
29
+
30
+ // Conditional types
31
+ export type Awaited<T> = T extends Promise<infer U> ? U : T;
32
+ export type NonNullable<T> = T extends null | undefined ? never : T;
33
+ export type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never;
34
+
35
+ // Mapped types
36
+ export type Readonly<T> = {
37
+ readonly [P in keyof T]: T[P];
38
+ };
39
+
40
+ export type Partial<T> = {
41
+ [P in keyof T]?: T[P];
42
+ };
43
+
44
+ export type Required<T> = {
45
+ [P in keyof T]-?: T[P];
46
+ };
47
+
48
+ // Type guards
49
+ export function isString(value: unknown): value is string {
50
+ return typeof value === "string";
51
+ }
52
+
53
+ export function isNumber(value: unknown): value is number {
54
+ return typeof value === "number";
55
+ }
56
+
57
+ export function isArray<T>(value: unknown): value is T[] {
58
+ return Array.isArray(value);
59
+ }
60
+
61
+ export function hasProperty<K extends string>(obj: unknown, key: K): obj is Record<K, unknown> {
62
+ return typeof obj === "object" && obj !== null && key in obj;
63
+ }
64
+
65
+ // Generic factory
66
+ export class Factory<T> {
67
+ constructor(private creator: () => T) {}
68
+
69
+ create(): T {
70
+ return this.creator();
71
+ }
72
+
73
+ createMany(count: number): T[] {
74
+ return Array.from({ length: count }, () => this.create());
75
+ }
76
+ }
77
+
78
+ // Builder pattern with fluent interface
79
+ export class QueryBuilder<T> {
80
+ private filters: Array<(item: T) => boolean> = [];
81
+ private sortFn?: (a: T, b: T) => number;
82
+ private limitValue?: number;
83
+
84
+ where(predicate: (item: T) => boolean): this {
85
+ this.filters.push(predicate);
86
+ return this;
87
+ }
88
+
89
+ orderBy(compareFn: (a: T, b: T) => number): this {
90
+ this.sortFn = compareFn;
91
+ return this;
92
+ }
93
+
94
+ limit(count: number): this {
95
+ this.limitValue = count;
96
+ return this;
97
+ }
98
+
99
+ execute(items: T[]): T[] {
100
+ let result = items;
101
+
102
+ // Apply filters
103
+ for (const filter of this.filters) {
104
+ result = result.filter(filter);
105
+ }
106
+
107
+ // Apply sorting
108
+ if (this.sortFn) {
109
+ result = result.sort(this.sortFn);
110
+ }
111
+
112
+ // Apply limit
113
+ if (this.limitValue !== undefined) {
114
+ result = result.slice(0, this.limitValue);
115
+ }
116
+
117
+ return result;
118
+ }
119
+ }
120
+
121
+ // Utility types
122
+ export type DeepPartial<T> = {
123
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
124
+ };
125
+
126
+ export type PickByType<T, ValueType> = {
127
+ [K in keyof T as T[K] extends ValueType ? K : never]: T[K];
128
+ };
129
+
130
+ export type OmitByType<T, ValueType> = {
131
+ [K in keyof T as T[K] extends ValueType ? never : K]: T[K];
132
+ };
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Utility functions for string manipulation
3
+ */
4
+
5
+ export function capitalize(str: string): string {
6
+ if (!str) return "";
7
+ return str.charAt(0).toUpperCase() + str.slice(1);
8
+ }
9
+
10
+ export function slugify(text: string): string {
11
+ return text
12
+ .toLowerCase()
13
+ .replace(/[^\w\s-]/g, "")
14
+ .replace(/[\s_-]+/g, "-")
15
+ .replace(/^-+|-+$/g, "");
16
+ }
17
+
18
+ /**
19
+ * Validates email format
20
+ */
21
+ export function isValidEmail(email: string): boolean {
22
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
23
+ return emailRegex.test(email);
24
+ }
25
+
26
+ /**
27
+ * Debounce function to limit execution rate
28
+ */
29
+ export function debounce<T extends (...args: any[]) => any>(
30
+ func: T,
31
+ wait: number
32
+ ): (...args: Parameters<T>) => void {
33
+ let timeout: NodeJS.Timeout | null = null;
34
+
35
+ return function executedFunction(...args: Parameters<T>) {
36
+ const later = () => {
37
+ timeout = null;
38
+ func(...args);
39
+ };
40
+
41
+ if (timeout) {
42
+ clearTimeout(timeout);
43
+ }
44
+ timeout = setTimeout(later, wait);
45
+ };
46
+ }
47
+
48
+ /**
49
+ * Deep clone an object
50
+ */
51
+ export function deepClone<T>(obj: T): T {
52
+ if (obj === null || typeof obj !== "object") {
53
+ return obj;
54
+ }
55
+
56
+ if (obj instanceof Date) {
57
+ return new Date(obj.getTime()) as any;
58
+ }
59
+
60
+ if (Array.isArray(obj)) {
61
+ const clonedArr: any[] = [];
62
+ for (let i = 0; i < obj.length; i++) {
63
+ clonedArr[i] = deepClone(obj[i]);
64
+ }
65
+ return clonedArr as any;
66
+ }
67
+
68
+ if (obj instanceof Object) {
69
+ const clonedObj: any = {};
70
+ for (const key in obj) {
71
+ if (Object.hasOwn(obj, key)) {
72
+ clonedObj[key] = deepClone(obj[key]);
73
+ }
74
+ }
75
+ return clonedObj;
76
+ }
77
+
78
+ return obj;
79
+ }
80
+
81
+ /**
82
+ * Retry a function with exponential backoff
83
+ */
84
+ export async function retry<T>(
85
+ fn: () => Promise<T>,
86
+ maxRetries: number = 3,
87
+ delay: number = 1000
88
+ ): Promise<T> {
89
+ let lastError: Error;
90
+
91
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
92
+ try {
93
+ return await fn();
94
+ } catch (error) {
95
+ lastError = error as Error;
96
+
97
+ if (attempt < maxRetries) {
98
+ const backoffDelay = delay * 2 ** attempt;
99
+ await new Promise((resolve) => setTimeout(resolve, backoffDelay));
100
+ }
101
+ }
102
+ }
103
+
104
+ throw lastError!;
105
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Complex validation logic with high cyclomatic complexity
3
+ */
4
+
5
+ export interface ValidationResult {
6
+ valid: boolean;
7
+ errors: string[];
8
+ }
9
+
10
+ export class Validator {
11
+ /**
12
+ * Validates user input with multiple conditions
13
+ */
14
+ validateUserInput(input: any): ValidationResult {
15
+ const errors: string[] = [];
16
+
17
+ if (!input) {
18
+ errors.push("Input is required");
19
+ return { valid: false, errors };
20
+ }
21
+
22
+ if (typeof input.email === "string") {
23
+ if (input.email.length < 5) {
24
+ errors.push("Email too short");
25
+ } else if (input.email.length > 100) {
26
+ errors.push("Email too long");
27
+ } else if (!input.email.includes("@")) {
28
+ errors.push("Invalid email format");
29
+ } else if (input.email.startsWith("@") || input.email.endsWith("@")) {
30
+ errors.push("Email cannot start or end with @");
31
+ }
32
+ } else {
33
+ errors.push("Email must be a string");
34
+ }
35
+
36
+ if (input.age !== undefined) {
37
+ if (typeof input.age !== "number") {
38
+ errors.push("Age must be a number");
39
+ } else if (input.age < 0) {
40
+ errors.push("Age cannot be negative");
41
+ } else if (input.age > 150) {
42
+ errors.push("Age seems unrealistic");
43
+ } else if (input.age < 13) {
44
+ errors.push("Must be 13 or older");
45
+ }
46
+ }
47
+
48
+ if (input.password) {
49
+ const pwd = input.password;
50
+ if (pwd.length < 8) {
51
+ errors.push("Password too short");
52
+ } else if (pwd.length > 128) {
53
+ errors.push("Password too long");
54
+ }
55
+
56
+ let hasUpper = false;
57
+ let hasLower = false;
58
+ let hasDigit = false;
59
+ let hasSpecial = false;
60
+
61
+ for (const char of pwd) {
62
+ if (char >= "A" && char <= "Z") {
63
+ hasUpper = true;
64
+ } else if (char >= "a" && char <= "z") {
65
+ hasLower = true;
66
+ } else if (char >= "0" && char <= "9") {
67
+ hasDigit = true;
68
+ } else if ("!@#$%^&*()_+-=[]{}|;:,.<>?".includes(char)) {
69
+ hasSpecial = true;
70
+ }
71
+ }
72
+
73
+ if (!hasUpper) {
74
+ errors.push("Password needs uppercase letter");
75
+ }
76
+ if (!hasLower) {
77
+ errors.push("Password needs lowercase letter");
78
+ }
79
+ if (!hasDigit) {
80
+ errors.push("Password needs digit");
81
+ }
82
+ if (!hasSpecial) {
83
+ errors.push("Password needs special character");
84
+ }
85
+ }
86
+
87
+ return {
88
+ valid: errors.length === 0,
89
+ errors,
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Process data with multiple switch cases and conditions
95
+ */
96
+ processData(data: any, type: string): any {
97
+ switch (type) {
98
+ case "string":
99
+ return String(data);
100
+ case "number":
101
+ return Number(data);
102
+ case "boolean":
103
+ return Boolean(data);
104
+ case "array":
105
+ if (Array.isArray(data)) {
106
+ return data;
107
+ } else if (data === null || data === undefined) {
108
+ return [];
109
+ } else {
110
+ return [data];
111
+ }
112
+ case "object":
113
+ if (typeof data === "object" && data !== null) {
114
+ return data;
115
+ } else {
116
+ return { value: data };
117
+ }
118
+ case "json":
119
+ try {
120
+ return JSON.parse(data);
121
+ } catch (_e) {
122
+ return null;
123
+ }
124
+ default:
125
+ return data;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Complex nested conditions
131
+ */
132
+ checkPermissions(user: any, resource: string, action: string): boolean {
133
+ if (!user) {
134
+ return false;
135
+ }
136
+
137
+ if (user.role === "admin") {
138
+ return true;
139
+ }
140
+
141
+ if (user.role === "moderator") {
142
+ if (action === "read" || action === "update") {
143
+ return true;
144
+ } else if (action === "delete" && resource !== "user") {
145
+ return true;
146
+ }
147
+ }
148
+
149
+ if (user.role === "user") {
150
+ if (action === "read") {
151
+ return true;
152
+ } else if (action === "update" && resource === "profile") {
153
+ return user.id === resource;
154
+ }
155
+ }
156
+
157
+ if (user.permissions && Array.isArray(user.permissions)) {
158
+ for (const perm of user.permissions) {
159
+ if (perm.resource === resource && (perm.action === action || perm.action === "*")) {
160
+ return true;
161
+ }
162
+ }
163
+ }
164
+
165
+ return false;
166
+ }
167
+ }
168
+
169
+ export default Validator;