rawsql-ts 0.11.33-beta → 0.11.34-beta

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 (65) hide show
  1. package/dist/esm/index.js +19 -0
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/index.min.js +43 -35
  4. package/dist/esm/index.min.js.map +4 -4
  5. package/dist/esm/src/index.d.ts +21 -0
  6. package/dist/esm/src/index.js +19 -0
  7. package/dist/esm/src/index.js.map +1 -1
  8. package/dist/esm/src/tokenReaders/CommandTokenReader.js +5 -0
  9. package/dist/esm/src/tokenReaders/CommandTokenReader.js.map +1 -1
  10. package/dist/esm/src/transformers/CTEBuilder.js +2 -2
  11. package/dist/esm/src/transformers/CTEBuilder.js.map +1 -1
  12. package/dist/esm/src/utils/CursorContextAnalyzer.d.ts +70 -0
  13. package/dist/esm/src/utils/CursorContextAnalyzer.js +322 -0
  14. package/dist/esm/src/utils/CursorContextAnalyzer.js.map +1 -0
  15. package/dist/esm/src/utils/IntelliSenseApi.d.ts +114 -0
  16. package/dist/esm/src/utils/IntelliSenseApi.js +284 -0
  17. package/dist/esm/src/utils/IntelliSenseApi.js.map +1 -0
  18. package/dist/esm/src/utils/KeywordCache.d.ts +65 -0
  19. package/dist/esm/src/utils/KeywordCache.js +202 -0
  20. package/dist/esm/src/utils/KeywordCache.js.map +1 -0
  21. package/dist/esm/src/utils/MultiQuerySplitter.d.ts +131 -0
  22. package/dist/esm/src/utils/MultiQuerySplitter.js +287 -0
  23. package/dist/esm/src/utils/MultiQuerySplitter.js.map +1 -0
  24. package/dist/esm/src/utils/PositionAwareParser.d.ts +85 -0
  25. package/dist/esm/src/utils/PositionAwareParser.js +336 -0
  26. package/dist/esm/src/utils/PositionAwareParser.js.map +1 -0
  27. package/dist/esm/src/utils/ScopeResolver.d.ts +127 -0
  28. package/dist/esm/src/utils/ScopeResolver.js +268 -0
  29. package/dist/esm/src/utils/ScopeResolver.js.map +1 -0
  30. package/dist/esm/src/utils/TextPositionUtils.d.ts +62 -0
  31. package/dist/esm/src/utils/TextPositionUtils.js +124 -0
  32. package/dist/esm/src/utils/TextPositionUtils.js.map +1 -0
  33. package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
  34. package/dist/index.min.js +43 -35
  35. package/dist/index.min.js.map +4 -4
  36. package/dist/src/index.d.ts +21 -0
  37. package/dist/src/index.js +20 -1
  38. package/dist/src/index.js.map +1 -1
  39. package/dist/src/tokenReaders/CommandTokenReader.js +5 -0
  40. package/dist/src/tokenReaders/CommandTokenReader.js.map +1 -1
  41. package/dist/src/transformers/CTEBuilder.js +2 -2
  42. package/dist/src/transformers/CTEBuilder.js.map +1 -1
  43. package/dist/src/utils/CursorContextAnalyzer.d.ts +70 -0
  44. package/dist/src/utils/CursorContextAnalyzer.js +338 -0
  45. package/dist/src/utils/CursorContextAnalyzer.js.map +1 -0
  46. package/dist/src/utils/IntelliSenseApi.d.ts +114 -0
  47. package/dist/src/utils/IntelliSenseApi.js +292 -0
  48. package/dist/src/utils/IntelliSenseApi.js.map +1 -0
  49. package/dist/src/utils/KeywordCache.d.ts +65 -0
  50. package/dist/src/utils/KeywordCache.js +206 -0
  51. package/dist/src/utils/KeywordCache.js.map +1 -0
  52. package/dist/src/utils/MultiQuerySplitter.d.ts +131 -0
  53. package/dist/src/utils/MultiQuerySplitter.js +292 -0
  54. package/dist/src/utils/MultiQuerySplitter.js.map +1 -0
  55. package/dist/src/utils/PositionAwareParser.d.ts +85 -0
  56. package/dist/src/utils/PositionAwareParser.js +363 -0
  57. package/dist/src/utils/PositionAwareParser.js.map +1 -0
  58. package/dist/src/utils/ScopeResolver.d.ts +127 -0
  59. package/dist/src/utils/ScopeResolver.js +272 -0
  60. package/dist/src/utils/ScopeResolver.js.map +1 -0
  61. package/dist/src/utils/TextPositionUtils.d.ts +62 -0
  62. package/dist/src/utils/TextPositionUtils.js +128 -0
  63. package/dist/src/utils/TextPositionUtils.js.map +1 -0
  64. package/dist/tsconfig.tsbuildinfo +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,114 @@
1
+ import { IntelliSenseContext } from './CursorContextAnalyzer';
2
+ import { ScopeInfo } from './ScopeResolver';
3
+ import { ParseToPositionOptions, PositionParseResult } from './PositionAwareParser';
4
+ import { QueryCollection } from './MultiQuerySplitter';
5
+ import { LineColumn } from './LexemeCursor';
6
+ /**
7
+ * Convenience API for SQL IntelliSense integration
8
+ *
9
+ * Provides simplified, high-level functions that combine the functionality
10
+ * of the various position-aware parsing components for easy integration
11
+ * with Monaco Editor and other code editors.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { parseToPosition, getCursorContext, resolveScope, splitQueries } from 'rawsql-ts';
16
+ *
17
+ * // Parse incomplete SQL with error recovery
18
+ * const sql = "SELECT u.name FROM users u WHERE u.";
19
+ * const parseResult = parseToPosition(sql, sql.length, { errorRecovery: true });
20
+ *
21
+ * // Get cursor context for completion suggestions
22
+ * const context = getCursorContext(sql, sql.length);
23
+ * console.log(context.isAfterDot); // true
24
+ * console.log(context.precedingIdentifier); // "u"
25
+ *
26
+ * // Get scope information for table/column completion
27
+ * const scope = resolveScope(sql, sql.length);
28
+ * console.log(scope.availableTables); // [{ name: 'users', alias: 'u' }]
29
+ *
30
+ * // Handle multi-query editor
31
+ * const multiSQL = "SELECT 1; SELECT 2;";
32
+ * const queries = splitQueries(multiSQL);
33
+ * const activeQuery = queries.getActive(12); // Get query at position
34
+ * ```
35
+ */
36
+ /**
37
+ * Parse SQL up to cursor position with error recovery
38
+ *
39
+ * Combines position-aware parsing with error recovery to handle incomplete SQL
40
+ * that users are actively typing. Ideal for providing IntelliSense in editors.
41
+ *
42
+ * @param sql - SQL text to parse
43
+ * @param cursorPosition - Cursor position (character offset or line/column)
44
+ * @param options - Parsing options including error recovery settings
45
+ * @returns Parse result with position-specific information
46
+ */
47
+ export declare function parseToPosition(sql: string, cursorPosition: number | LineColumn, options?: ParseToPositionOptions): PositionParseResult;
48
+ /**
49
+ * Analyze cursor context for IntelliSense completion suggestions
50
+ *
51
+ * Determines what type of completions should be offered at the cursor position
52
+ * based on SQL syntax context (SELECT clause, WHERE condition, etc.).
53
+ *
54
+ * @param sql - SQL text to analyze
55
+ * @param cursorPosition - Cursor position (character offset or line/column)
56
+ * @returns Cursor context information for completion logic
57
+ */
58
+ export declare function getCursorContext(sql: string, cursorPosition: number | LineColumn): IntelliSenseContext;
59
+ /**
60
+ * Resolve scope information at cursor position
61
+ *
62
+ * Provides comprehensive information about available tables, CTEs, and columns
63
+ * at the specified cursor position for intelligent completion suggestions.
64
+ *
65
+ * @param sql - SQL text to analyze
66
+ * @param cursorPosition - Cursor position (character offset or line/column)
67
+ * @returns Complete scope information including available tables and columns
68
+ */
69
+ export declare function resolveScope(sql: string, cursorPosition: number | LineColumn): ScopeInfo;
70
+ /**
71
+ * Split multi-query SQL text into individual queries
72
+ *
73
+ * Handles SQL editors that contain multiple statements separated by semicolons.
74
+ * Properly handles string literals and comments containing semicolons.
75
+ *
76
+ * @param sql - Multi-query SQL text
77
+ * @returns Collection of individual queries with position information
78
+ */
79
+ export declare function splitQueries(sql: string): QueryCollection;
80
+ /**
81
+ * Get IntelliSense information for a cursor position in multi-query context
82
+ *
83
+ * Combines query splitting, context analysis, and scope resolution to provide
84
+ * complete IntelliSense information for a cursor position in multi-query SQL.
85
+ *
86
+ * @param sql - Multi-query SQL text
87
+ * @param cursorPosition - Cursor position
88
+ * @param options - Parsing options
89
+ * @returns Complete IntelliSense information or undefined if position is invalid
90
+ */
91
+ export declare function getIntelliSenseInfo(sql: string, cursorPosition: number | LineColumn, options?: ParseToPositionOptions): {
92
+ context: IntelliSenseContext;
93
+ scope: ScopeInfo;
94
+ parseResult: PositionParseResult;
95
+ currentQuery: string;
96
+ relativePosition: number;
97
+ } | undefined;
98
+ /**
99
+ * Get completion suggestions based on cursor context and scope
100
+ *
101
+ * Uses the new IntelliSense interface to provide targeted completion suggestions.
102
+ * This function leverages the suggestion-based design to efficiently determine
103
+ * what completions should be offered.
104
+ *
105
+ * @param sql - SQL text
106
+ * @param cursorPosition - Cursor position
107
+ * @returns Array of completion suggestions with context information
108
+ */
109
+ export declare function getCompletionSuggestions(sql: string, cursorPosition: number | LineColumn): Array<{
110
+ type: 'keyword' | 'table' | 'column' | 'cte' | 'function';
111
+ value: string;
112
+ detail?: string;
113
+ documentation?: string;
114
+ }>;
@@ -0,0 +1,284 @@
1
+ import { CursorContextAnalyzer } from './CursorContextAnalyzer';
2
+ import { ScopeResolver } from './ScopeResolver';
3
+ import { PositionAwareParser } from './PositionAwareParser';
4
+ import { MultiQuerySplitter } from './MultiQuerySplitter';
5
+ import { TextPositionUtils } from './TextPositionUtils';
6
+ /**
7
+ * Convenience API for SQL IntelliSense integration
8
+ *
9
+ * Provides simplified, high-level functions that combine the functionality
10
+ * of the various position-aware parsing components for easy integration
11
+ * with Monaco Editor and other code editors.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { parseToPosition, getCursorContext, resolveScope, splitQueries } from 'rawsql-ts';
16
+ *
17
+ * // Parse incomplete SQL with error recovery
18
+ * const sql = "SELECT u.name FROM users u WHERE u.";
19
+ * const parseResult = parseToPosition(sql, sql.length, { errorRecovery: true });
20
+ *
21
+ * // Get cursor context for completion suggestions
22
+ * const context = getCursorContext(sql, sql.length);
23
+ * console.log(context.isAfterDot); // true
24
+ * console.log(context.precedingIdentifier); // "u"
25
+ *
26
+ * // Get scope information for table/column completion
27
+ * const scope = resolveScope(sql, sql.length);
28
+ * console.log(scope.availableTables); // [{ name: 'users', alias: 'u' }]
29
+ *
30
+ * // Handle multi-query editor
31
+ * const multiSQL = "SELECT 1; SELECT 2;";
32
+ * const queries = splitQueries(multiSQL);
33
+ * const activeQuery = queries.getActive(12); // Get query at position
34
+ * ```
35
+ */
36
+ /**
37
+ * Parse SQL up to cursor position with error recovery
38
+ *
39
+ * Combines position-aware parsing with error recovery to handle incomplete SQL
40
+ * that users are actively typing. Ideal for providing IntelliSense in editors.
41
+ *
42
+ * @param sql - SQL text to parse
43
+ * @param cursorPosition - Cursor position (character offset or line/column)
44
+ * @param options - Parsing options including error recovery settings
45
+ * @returns Parse result with position-specific information
46
+ */
47
+ export function parseToPosition(sql, cursorPosition, options = {}) {
48
+ return PositionAwareParser.parseToPosition(sql, cursorPosition, options);
49
+ }
50
+ /**
51
+ * Analyze cursor context for IntelliSense completion suggestions
52
+ *
53
+ * Determines what type of completions should be offered at the cursor position
54
+ * based on SQL syntax context (SELECT clause, WHERE condition, etc.).
55
+ *
56
+ * @param sql - SQL text to analyze
57
+ * @param cursorPosition - Cursor position (character offset or line/column)
58
+ * @returns Cursor context information for completion logic
59
+ */
60
+ export function getCursorContext(sql, cursorPosition) {
61
+ if (typeof cursorPosition === 'number') {
62
+ return CursorContextAnalyzer.analyzeIntelliSense(sql, cursorPosition);
63
+ }
64
+ else {
65
+ return CursorContextAnalyzer.analyzeIntelliSenseAt(sql, cursorPosition);
66
+ }
67
+ }
68
+ /**
69
+ * Resolve scope information at cursor position
70
+ *
71
+ * Provides comprehensive information about available tables, CTEs, and columns
72
+ * at the specified cursor position for intelligent completion suggestions.
73
+ *
74
+ * @param sql - SQL text to analyze
75
+ * @param cursorPosition - Cursor position (character offset or line/column)
76
+ * @returns Complete scope information including available tables and columns
77
+ */
78
+ export function resolveScope(sql, cursorPosition) {
79
+ if (typeof cursorPosition === 'number') {
80
+ return ScopeResolver.resolve(sql, cursorPosition);
81
+ }
82
+ else {
83
+ return ScopeResolver.resolveAt(sql, cursorPosition);
84
+ }
85
+ }
86
+ /**
87
+ * Split multi-query SQL text into individual queries
88
+ *
89
+ * Handles SQL editors that contain multiple statements separated by semicolons.
90
+ * Properly handles string literals and comments containing semicolons.
91
+ *
92
+ * @param sql - Multi-query SQL text
93
+ * @returns Collection of individual queries with position information
94
+ */
95
+ export function splitQueries(sql) {
96
+ return MultiQuerySplitter.split(sql);
97
+ }
98
+ /**
99
+ * Get IntelliSense information for a cursor position in multi-query context
100
+ *
101
+ * Combines query splitting, context analysis, and scope resolution to provide
102
+ * complete IntelliSense information for a cursor position in multi-query SQL.
103
+ *
104
+ * @param sql - Multi-query SQL text
105
+ * @param cursorPosition - Cursor position
106
+ * @param options - Parsing options
107
+ * @returns Complete IntelliSense information or undefined if position is invalid
108
+ */
109
+ export function getIntelliSenseInfo(sql, cursorPosition, options = {}) {
110
+ const charPos = typeof cursorPosition === 'number'
111
+ ? cursorPosition
112
+ : TextPositionUtils.lineColumnToCharOffset(sql, cursorPosition);
113
+ if (charPos === -1) {
114
+ return undefined;
115
+ }
116
+ // Split queries and find the active one
117
+ const queries = splitQueries(sql);
118
+ const activeQuery = queries.getActive(charPos);
119
+ if (!activeQuery) {
120
+ return undefined;
121
+ }
122
+ // Calculate relative position within the active query
123
+ const relativePosition = charPos - activeQuery.start;
124
+ const querySQL = activeQuery.sql;
125
+ // Get IntelliSense information for the active query
126
+ const context = getCursorContext(querySQL, relativePosition);
127
+ const scope = resolveScope(querySQL, relativePosition);
128
+ const parseResult = parseToPosition(querySQL, relativePosition, options);
129
+ return {
130
+ context,
131
+ scope,
132
+ parseResult,
133
+ currentQuery: querySQL,
134
+ relativePosition
135
+ };
136
+ }
137
+ /**
138
+ * Get completion suggestions based on cursor context and scope
139
+ *
140
+ * Uses the new IntelliSense interface to provide targeted completion suggestions.
141
+ * This function leverages the suggestion-based design to efficiently determine
142
+ * what completions should be offered.
143
+ *
144
+ * @param sql - SQL text
145
+ * @param cursorPosition - Cursor position
146
+ * @returns Array of completion suggestions with context information
147
+ */
148
+ export function getCompletionSuggestions(sql, cursorPosition) {
149
+ const charPos = typeof cursorPosition === 'number'
150
+ ? cursorPosition
151
+ : TextPositionUtils.lineColumnToCharOffset(sql, cursorPosition);
152
+ if (charPos === -1) {
153
+ return [];
154
+ }
155
+ const intelliSenseContext = CursorContextAnalyzer.analyzeIntelliSense(sql, charPos);
156
+ const scope = resolveScope(sql, cursorPosition);
157
+ const suggestions = [];
158
+ // Add keyword suggestions
159
+ if (intelliSenseContext.suggestKeywords) {
160
+ // Add required keywords if specified
161
+ if (intelliSenseContext.requiredKeywords) {
162
+ intelliSenseContext.requiredKeywords.forEach(keyword => {
163
+ suggestions.push({
164
+ type: 'keyword',
165
+ value: keyword,
166
+ detail: `Required keyword: ${keyword}`
167
+ });
168
+ });
169
+ }
170
+ else {
171
+ // Add general contextual keywords based on token context
172
+ const generalKeywords = getGeneralKeywords(intelliSenseContext);
173
+ generalKeywords.forEach(keyword => {
174
+ suggestions.push({
175
+ type: 'keyword',
176
+ value: keyword.value,
177
+ detail: keyword.detail
178
+ });
179
+ });
180
+ }
181
+ }
182
+ // Add table suggestions
183
+ if (intelliSenseContext.suggestTables) {
184
+ scope.availableTables.forEach(table => {
185
+ suggestions.push({
186
+ type: 'table',
187
+ value: table.alias || table.name,
188
+ detail: `Table: ${table.fullName}`,
189
+ documentation: `Available table${table.alias ? ` (alias: ${table.alias})` : ''}`
190
+ });
191
+ });
192
+ // Add CTE suggestions
193
+ scope.availableCTEs.forEach(cte => {
194
+ suggestions.push({
195
+ type: 'cte',
196
+ value: cte.name,
197
+ detail: `CTE: ${cte.name}`,
198
+ documentation: `Common Table Expression${cte.columns ? ` with columns: ${cte.columns.join(', ')}` : ''}`
199
+ });
200
+ });
201
+ }
202
+ // Add column suggestions
203
+ if (intelliSenseContext.suggestColumns) {
204
+ if (intelliSenseContext.tableScope) {
205
+ // Specific table/alias column completion
206
+ const columns = scope.visibleColumns.filter(col => col.tableName === intelliSenseContext.tableScope ||
207
+ col.tableAlias === intelliSenseContext.tableScope);
208
+ columns.forEach(col => {
209
+ suggestions.push({
210
+ type: 'column',
211
+ value: col.name,
212
+ detail: `Column: ${col.fullReference}`,
213
+ documentation: `Column from ${col.tableName}${col.type ? ` (${col.type})` : ''}`
214
+ });
215
+ });
216
+ }
217
+ else {
218
+ // General column completion
219
+ scope.visibleColumns.forEach(col => {
220
+ suggestions.push({
221
+ type: 'column',
222
+ value: col.name === '*' ? '*' : `${col.tableAlias || col.tableName}.${col.name}`,
223
+ detail: `Column: ${col.fullReference}`,
224
+ documentation: `Column from ${col.tableName}`
225
+ });
226
+ });
227
+ }
228
+ }
229
+ return suggestions;
230
+ }
231
+ /**
232
+ * Get general keyword suggestions based on IntelliSense context
233
+ */
234
+ function getGeneralKeywords(context) {
235
+ var _a, _b, _c, _d;
236
+ // Determine context from token information
237
+ const prevToken = (_b = (_a = context.previousToken) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.toLowerCase();
238
+ const currentToken = (_d = (_c = context.currentToken) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.toLowerCase();
239
+ // SELECT context - aggregate functions and keywords
240
+ if (prevToken === "select" || currentToken === "select") {
241
+ return [
242
+ { value: "DISTINCT", detail: "Remove duplicate rows" },
243
+ { value: "COUNT", detail: "Aggregate function" },
244
+ { value: "SUM", detail: "Aggregate function" },
245
+ { value: "AVG", detail: "Aggregate function" },
246
+ { value: "MAX", detail: "Aggregate function" },
247
+ { value: "MIN", detail: "Aggregate function" }
248
+ ];
249
+ }
250
+ // FROM context - JOIN options and clauses
251
+ if (prevToken === "from" || currentToken === "from") {
252
+ return [
253
+ { value: "JOIN", detail: "Inner join tables" },
254
+ { value: "LEFT JOIN", detail: "Left outer join" },
255
+ { value: "RIGHT JOIN", detail: "Right outer join" },
256
+ { value: "FULL JOIN", detail: "Full outer join" },
257
+ { value: "WHERE", detail: "Filter conditions" },
258
+ { value: "GROUP BY", detail: "Group results" },
259
+ { value: "ORDER BY", detail: "Sort results" }
260
+ ];
261
+ }
262
+ // WHERE/HAVING context - logical operators
263
+ if (["where", "having", "on"].includes(prevToken || "") || ["where", "having", "on"].includes(currentToken || "")) {
264
+ return [
265
+ { value: "AND", detail: "Logical AND operator" },
266
+ { value: "OR", detail: "Logical OR operator" },
267
+ { value: "NOT", detail: "Logical NOT operator" },
268
+ { value: "IN", detail: "Match any value in list" },
269
+ { value: "LIKE", detail: "Pattern matching" },
270
+ { value: "BETWEEN", detail: "Range comparison" }
271
+ ];
272
+ }
273
+ // Default context - general SQL keywords
274
+ return [
275
+ { value: "SELECT", detail: "Query data" },
276
+ { value: "FROM", detail: "Specify table" },
277
+ { value: "WHERE", detail: "Filter conditions" },
278
+ { value: "JOIN", detail: "Join tables" },
279
+ { value: "GROUP BY", detail: "Group results" },
280
+ { value: "ORDER BY", detail: "Sort results" },
281
+ { value: "LIMIT", detail: "Limit results" }
282
+ ];
283
+ }
284
+ //# sourceMappingURL=IntelliSenseApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IntelliSenseApi.js","sourceRoot":"","sources":["../../../../src/utils/IntelliSenseApi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Utility for caching keyword relationships for fast access
3
+ * Dynamically builds keyword relationships from existing joinkeywordParser
4
+ *
5
+ * SOURCE DICTIONARIES (single source of truth):
6
+ * - JOIN patterns: /src/tokenReaders/CommandTokenReader.ts (joinTrie, lines 10-29)
7
+ * - Command patterns: /src/tokenReaders/CommandTokenReader.ts (keywordTrie, lines 30-118)
8
+ *
9
+ * MIGRATION NOTE:
10
+ * If keywords are added/modified in CommandTokenReader.ts, update the
11
+ * extractCommandPatternsFromTrie() method to reflect those changes.
12
+ * JOIN patterns are automatically extracted via joinkeywordParser.
13
+ */
14
+ export declare class KeywordCache {
15
+ private static joinSuggestionCache;
16
+ private static commandSuggestionCache;
17
+ private static initialized;
18
+ /**
19
+ * Initialize JOIN-related keyword suggestions
20
+ * Dynamically generated based on information extracted from joinkeywordParser
21
+ */
22
+ private static initialize;
23
+ /**
24
+ * Get next suggestions for the specified keyword
25
+ * Example: "left" → ["join", "outer", "outer join"]
26
+ */
27
+ static getJoinSuggestions(keyword: string): string[];
28
+ /**
29
+ * Check if a keyword is a valid JOIN keyword
30
+ * Uses existing joinkeywordParser as the primary resource
31
+ */
32
+ static isValidJoinKeyword(keyword: string): boolean;
33
+ /**
34
+ * Generate suggestions based on partial keyword input
35
+ * Example: "le" → find keywords starting with "left"
36
+ */
37
+ static getPartialSuggestions(partialKeyword: string): string[];
38
+ /**
39
+ * Get all JOIN keywords
40
+ */
41
+ static getAllJoinKeywords(): string[];
42
+ /**
43
+ * Initialize command keyword patterns
44
+ * Dynamically extracted from commandKeywordTrie
45
+ */
46
+ private static initializeCommandKeywords;
47
+ /**
48
+ * Extract multi-word patterns from commandKeywordTrie
49
+ * Uses known patterns since direct extraction from trie structure is difficult
50
+ *
51
+ * SOURCE: /src/tokenReaders/CommandTokenReader.ts keywordTrie (lines 30-118)
52
+ * MIGRATION: When updating, copy multi-word patterns from the source trie
53
+ */
54
+ private static extractCommandPatternsFromTrie;
55
+ /**
56
+ * Get next command suggestions for the specified keyword
57
+ * Example: "group" → ["by"]
58
+ */
59
+ static getCommandSuggestions(keyword: string): string[];
60
+ /**
61
+ * Force cache re-initialization
62
+ * Used for testing or when keyword definitions have changed
63
+ */
64
+ static reset(): void;
65
+ }
@@ -0,0 +1,202 @@
1
+ import { joinkeywordParser } from "../tokenReaders/CommandTokenReader";
2
+ /**
3
+ * Utility for caching keyword relationships for fast access
4
+ * Dynamically builds keyword relationships from existing joinkeywordParser
5
+ *
6
+ * SOURCE DICTIONARIES (single source of truth):
7
+ * - JOIN patterns: /src/tokenReaders/CommandTokenReader.ts (joinTrie, lines 10-29)
8
+ * - Command patterns: /src/tokenReaders/CommandTokenReader.ts (keywordTrie, lines 30-118)
9
+ *
10
+ * MIGRATION NOTE:
11
+ * If keywords are added/modified in CommandTokenReader.ts, update the
12
+ * extractCommandPatternsFromTrie() method to reflect those changes.
13
+ * JOIN patterns are automatically extracted via joinkeywordParser.
14
+ */
15
+ export class KeywordCache {
16
+ /**
17
+ * Initialize JOIN-related keyword suggestions
18
+ * Dynamically generated based on information extracted from joinkeywordParser
19
+ */
20
+ static initialize() {
21
+ if (this.initialized)
22
+ return;
23
+ // SOURCE: /src/tokenReaders/CommandTokenReader.ts joinTrie (lines 10-33)
24
+ // Dynamically build keyword relationships from joinTrie
25
+ const joinPatterns = [
26
+ ["join"],
27
+ ["inner", "join"],
28
+ ["cross", "join"],
29
+ ["left", "join"],
30
+ ["left", "outer", "join"],
31
+ ["right", "join"],
32
+ ["right", "outer", "join"],
33
+ ["full", "join"],
34
+ ["full", "outer", "join"],
35
+ ["natural", "join"],
36
+ ["natural", "inner", "join"],
37
+ ["natural", "left", "join"],
38
+ ["natural", "left", "outer", "join"],
39
+ ["natural", "right", "join"],
40
+ ["natural", "right", "outer", "join"],
41
+ ["natural", "full", "join"],
42
+ ["natural", "full", "outer", "join"],
43
+ // LATERAL JOIN patterns
44
+ ["lateral", "join"],
45
+ ["lateral", "inner", "join"],
46
+ ["lateral", "left", "join"],
47
+ ["lateral", "left", "outer", "join"],
48
+ ];
49
+ // Build keyword suggestion relationships
50
+ const suggestionMap = new Map();
51
+ // Build complete phrase suggestions for better UX
52
+ const completePhrases = new Set();
53
+ joinPatterns.forEach(pattern => {
54
+ if (pattern.length > 1) {
55
+ completePhrases.add(pattern.slice(1).join(' ').toUpperCase());
56
+ }
57
+ });
58
+ // For each prefix, find all possible complete continuations
59
+ joinPatterns.forEach(pattern => {
60
+ for (let i = 0; i < pattern.length - 1; i++) {
61
+ const prefix = pattern[i];
62
+ if (!suggestionMap.has(prefix)) {
63
+ suggestionMap.set(prefix, new Set());
64
+ }
65
+ // Find all patterns that start with this prefix and add complete phrases
66
+ joinPatterns.forEach(candidatePattern => {
67
+ if (candidatePattern.length > i + 1 && candidatePattern[i] === prefix) {
68
+ const completePhrase = candidatePattern.slice(i + 1).join(' ').toUpperCase();
69
+ suggestionMap.get(prefix).add(completePhrase);
70
+ }
71
+ });
72
+ }
73
+ });
74
+ // Convert Set to array and save to cache
75
+ suggestionMap.forEach((suggestions, keyword) => {
76
+ this.joinSuggestionCache.set(keyword.toLowerCase(), Array.from(suggestions));
77
+ });
78
+ // Also process command keywords
79
+ this.initializeCommandKeywords();
80
+ this.initialized = true;
81
+ }
82
+ /**
83
+ * Get next suggestions for the specified keyword
84
+ * Example: "left" → ["join", "outer", "outer join"]
85
+ */
86
+ static getJoinSuggestions(keyword) {
87
+ this.initialize();
88
+ return this.joinSuggestionCache.get(keyword.toLowerCase()) || [];
89
+ }
90
+ /**
91
+ * Check if a keyword is a valid JOIN keyword
92
+ * Uses existing joinkeywordParser as the primary resource
93
+ */
94
+ static isValidJoinKeyword(keyword) {
95
+ const result = joinkeywordParser.parse(keyword, 0);
96
+ return result !== null;
97
+ }
98
+ /**
99
+ * Generate suggestions based on partial keyword input
100
+ * Example: "le" → find keywords starting with "left"
101
+ */
102
+ static getPartialSuggestions(partialKeyword) {
103
+ this.initialize();
104
+ const partial = partialKeyword.toLowerCase();
105
+ const suggestions = [];
106
+ this.joinSuggestionCache.forEach((values, key) => {
107
+ if (key.startsWith(partial)) {
108
+ suggestions.push(key);
109
+ // Include next suggestions for that keyword as well
110
+ values.forEach(value => {
111
+ if (!suggestions.includes(value)) {
112
+ suggestions.push(value);
113
+ }
114
+ });
115
+ }
116
+ });
117
+ return suggestions;
118
+ }
119
+ /**
120
+ * Get all JOIN keywords
121
+ */
122
+ static getAllJoinKeywords() {
123
+ this.initialize();
124
+ const allKeywords = new Set();
125
+ this.joinSuggestionCache.forEach((values, key) => {
126
+ allKeywords.add(key);
127
+ values.forEach(value => allKeywords.add(value));
128
+ });
129
+ return Array.from(allKeywords);
130
+ }
131
+ /**
132
+ * Initialize command keyword patterns
133
+ * Dynamically extracted from commandKeywordTrie
134
+ */
135
+ static initializeCommandKeywords() {
136
+ // Extract multi-word patterns from commandKeywordTrie
137
+ const commandPatterns = this.extractCommandPatternsFromTrie();
138
+ const suggestionMap = new Map();
139
+ commandPatterns.forEach(pattern => {
140
+ for (let i = 0; i < pattern.length - 1; i++) {
141
+ const prefix = pattern[i];
142
+ const nextWord = pattern[i + 1];
143
+ if (!suggestionMap.has(prefix)) {
144
+ suggestionMap.set(prefix, new Set());
145
+ }
146
+ suggestionMap.get(prefix).add(nextWord);
147
+ }
148
+ });
149
+ // Convert Set to array and save to cache
150
+ suggestionMap.forEach((suggestions, keyword) => {
151
+ this.commandSuggestionCache.set(keyword.toLowerCase(), Array.from(suggestions));
152
+ });
153
+ }
154
+ /**
155
+ * Extract multi-word patterns from commandKeywordTrie
156
+ * Uses known patterns since direct extraction from trie structure is difficult
157
+ *
158
+ * SOURCE: /src/tokenReaders/CommandTokenReader.ts keywordTrie (lines 30-118)
159
+ * MIGRATION: When updating, copy multi-word patterns from the source trie
160
+ */
161
+ static extractCommandPatternsFromTrie() {
162
+ // These are patterns defined in CommandTokenReader's keywordTrie
163
+ return [
164
+ ["group", "by"],
165
+ ["order", "by"],
166
+ ["distinct", "on"],
167
+ ["not", "materialized"],
168
+ ["row", "only"],
169
+ ["rows", "only"],
170
+ ["percent", "with", "ties"],
171
+ ["key", "share"],
172
+ ["no", "key", "update"],
173
+ ["union", "all"],
174
+ ["intersect", "all"],
175
+ ["except", "all"],
176
+ ["partition", "by"],
177
+ ["within", "group"],
178
+ ["with", "ordinality"]
179
+ ];
180
+ }
181
+ /**
182
+ * Get next command suggestions for the specified keyword
183
+ * Example: "group" → ["by"]
184
+ */
185
+ static getCommandSuggestions(keyword) {
186
+ this.initialize();
187
+ return this.commandSuggestionCache.get(keyword.toLowerCase()) || [];
188
+ }
189
+ /**
190
+ * Force cache re-initialization
191
+ * Used for testing or when keyword definitions have changed
192
+ */
193
+ static reset() {
194
+ this.joinSuggestionCache.clear();
195
+ this.commandSuggestionCache.clear();
196
+ this.initialized = false;
197
+ }
198
+ }
199
+ KeywordCache.joinSuggestionCache = new Map();
200
+ KeywordCache.commandSuggestionCache = new Map();
201
+ KeywordCache.initialized = false;
202
+ //# sourceMappingURL=KeywordCache.js.map