squirreling 0.4.8 → 0.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.
package/src/errors.js DELETED
@@ -1,230 +0,0 @@
1
- // ============================================================================
2
- // PARSE ERRORS - Issues during SQL tokenization and parsing
3
- // ============================================================================
4
-
5
- /**
6
- * General syntax error for unexpected tokens.
7
- *
8
- * @param {Object} options
9
- * @param {string} options.expected - Description of what was expected
10
- * @param {string} options.received - What was actually found
11
- * @param {number} options.position - Character position in query
12
- * @param {string} [options.after] - What token came before (for context)
13
- * @returns {Error}
14
- */
15
- export function syntaxError({ expected, received, position, after }) {
16
- const afterClause = after ? ` after "${after}"` : ''
17
- return new Error(`Expected ${expected}${afterClause} but found ${received} at position ${position}`)
18
- }
19
-
20
- /**
21
- * Error for unterminated literals (strings, identifiers).
22
- *
23
- * @param {'string' | 'identifier'} type - Type of unterminated literal
24
- * @param {number} position - Starting position
25
- * @returns {Error}
26
- */
27
- export function unterminatedError(type, position) {
28
- const name = type === 'string' ? 'string literal' : 'identifier'
29
- return new Error(`Unterminated ${name} starting at position ${position}`)
30
- }
31
-
32
- /**
33
- * Error for invalid literals (numbers, intervals, etc).
34
- *
35
- * @param {Object} options
36
- * @param {string} options.type - Type of invalid literal (e.g., 'number', 'interval value', 'interval unit')
37
- * @param {string} options.value - The invalid value
38
- * @param {number} options.position - Position in query
39
- * @param {string} [options.validValues] - List of valid values (for enums like interval units)
40
- * @returns {Error}
41
- */
42
- export function invalidLiteralError({ type, value, position, validValues }) {
43
- const suffix = validValues ? `. Valid values: ${validValues}` : ''
44
- return new Error(`Invalid ${type} ${value} at position ${position}${suffix}`)
45
- }
46
-
47
- /**
48
- * Error for unexpected characters during tokenization.
49
- *
50
- * @param {string} char - The unexpected character
51
- * @param {number} position - Position in query
52
- * @param {boolean} [expectsSelect=false] - Whether SELECT was expected (first token)
53
- * @returns {Error}
54
- */
55
- export function unexpectedCharError(char, position, expectsSelect = false) {
56
- if (expectsSelect) {
57
- return new Error(`Expected SELECT but found "${char}" at position ${position}. Queries must start with SELECT.`)
58
- }
59
- return new Error(`Unexpected character "${char}" at position ${position}`)
60
- }
61
-
62
- /**
63
- * Error for unknown/unsupported functions.
64
- *
65
- * @param {string} funcName - The unknown function name
66
- * @param {number} [position] - Position in query (for parse errors)
67
- * @param {string} [validFunctions] - List of valid functions
68
- * @returns {Error}
69
- */
70
- export function unknownFunctionError(funcName, position, validFunctions) {
71
- const supported = validFunctions ||
72
- 'COUNT, SUM, AVG, MIN, MAX, UPPER, LOWER, CONCAT, LENGTH, SUBSTRING, TRIM, REPLACE, JSON_OBJECT, JSON_VALUE, JSON_QUERY, JSON_ARRAYAGG'
73
-
74
- if (position !== undefined) {
75
- return new Error(`Unknown function "${funcName}" at position ${position}. Supported: ${supported}`)
76
- }
77
- return new Error(`Unsupported function: ${funcName}. Supported: ${supported}`)
78
- }
79
-
80
- /**
81
- * Error for missing required clause or structure.
82
- *
83
- * @param {Object} options
84
- * @param {string} options.missing - What is missing (e.g., 'WHEN clause', 'FROM clause', 'ON condition')
85
- * @param {string} options.context - Where it's missing from (e.g., 'CASE expression', 'SELECT statement', 'JOIN')
86
- * @returns {Error}
87
- */
88
- export function missingClauseError({ missing, context }) {
89
- return new Error(`${context} requires ${missing}`)
90
- }
91
-
92
- // ============================================================================
93
- // EXECUTION ERRORS - Issues during query execution
94
- // ============================================================================
95
-
96
- /**
97
- * Error for missing table.
98
- *
99
- * @param {string} tableName - The missing table name
100
- * @returns {Error}
101
- */
102
- export function tableNotFoundError(tableName) {
103
- return new Error(`Table "${tableName}" not found. Check spelling or add it to the tables parameter.`)
104
- }
105
-
106
- /**
107
- * Error for invalid context (e.g., INTERVAL without date arithmetic).
108
- *
109
- * @param {Object} options
110
- * @param {string} options.item - What was used incorrectly
111
- * @param {string} options.validContext - Where it can be used
112
- * @returns {Error}
113
- */
114
- export function invalidContextError({ item, validContext }) {
115
- return new Error(`${item} can only be used with ${validContext}`)
116
- }
117
-
118
- /**
119
- * Error for unsupported operation combinations.
120
- *
121
- * @param {string} operation - The unsupported operation
122
- * @param {string} [hint] - How to fix it
123
- * @returns {Error}
124
- */
125
- export function unsupportedOperationError(operation, hint) {
126
- const suffix = hint ? `. ${hint}` : ''
127
- return new Error(`${operation}${suffix}`)
128
- }
129
-
130
- // ============================================================================
131
- // VALIDATION ERRORS - Function argument and type validation
132
- // ============================================================================
133
-
134
- /**
135
- * Function signatures for helpful error messages.
136
- * Maps function name to its parameter signature.
137
- * @type {Record<string, string>}
138
- */
139
- const FUNCTION_SIGNATURES = {
140
- // String functions
141
- UPPER: 'string',
142
- LOWER: 'string',
143
- LENGTH: 'string',
144
- TRIM: 'string',
145
- REPLACE: 'string, search, replacement',
146
- SUBSTRING: 'string, start[, length]',
147
- SUBSTR: 'string, start[, length]',
148
- CONCAT: 'value1, value2[, ...]',
149
-
150
- // Date/time functions
151
- RANDOM: '',
152
- RAND: '',
153
- CURRENT_DATE: '',
154
- CURRENT_TIME: '',
155
- CURRENT_TIMESTAMP: '',
156
-
157
- // JSON functions
158
- JSON_VALUE: 'expression, path',
159
- JSON_QUERY: 'expression, path',
160
- JSON_OBJECT: 'key1, value1[, ...]',
161
- JSON_ARRAYAGG: 'expression',
162
-
163
- // Aggregate functions
164
- COUNT: 'expression',
165
- SUM: 'expression',
166
- AVG: 'expression',
167
- MIN: 'expression',
168
- MAX: 'expression',
169
- }
170
-
171
- /**
172
- * Error for wrong number of function arguments.
173
- *
174
- * @param {string} funcName - The function name
175
- * @param {number | string} expected - Expected count (number or range like "2 or 3")
176
- * @param {number} received - Actual argument count
177
- * @returns {Error}
178
- */
179
- export function argCountError(funcName, expected, received) {
180
- const signature = FUNCTION_SIGNATURES[funcName] ?? ''
181
- let expectedStr = `${expected} arguments`
182
- if (expected === 0) expectedStr = 'no arguments'
183
- if (expected === 1) expectedStr = '1 argument'
184
- if (typeof expected === 'string' && expected.endsWith(' 1')) {
185
- expectedStr = `${expected} argument`
186
- }
187
-
188
- return new Error(`${funcName}(${signature}) function requires ${expectedStr}, got ${received}`)
189
- }
190
-
191
- /**
192
- * Error for invalid argument type or value.
193
- *
194
- * @param {Object} options
195
- * @param {string} options.funcName - The function name
196
- * @param {string} options.message - Specific error message
197
- * @param {string} [options.hint] - Recovery hint
198
- * @returns {Error}
199
- */
200
- export function argValueError({ funcName, message, hint }) {
201
- const signature = FUNCTION_SIGNATURES[funcName] ?? ''
202
- const suffix = hint ? `. ${hint}` : ''
203
- return new Error(`${funcName}(${signature}): ${message}${suffix}`)
204
- }
205
-
206
- /**
207
- * Error for aggregate function misuse (e.g., SUM(*)).
208
- *
209
- * @param {string} funcName - The aggregate function
210
- * @param {string} issue - What's wrong (e.g., "(*) is not supported")
211
- * @returns {Error}
212
- */
213
- export function aggregateError(funcName, issue) {
214
- return new Error(`${funcName}${issue}. Only COUNT supports *. Use a column name for ${funcName}.`)
215
- }
216
-
217
- /**
218
- * Error for unsupported CAST type.
219
- *
220
- * @param {string} toType - The unsupported target type
221
- * @param {string} [fromType] - The source type (optional)
222
- * @returns {Error}
223
- */
224
- export function castError(toType, fromType) {
225
- const message = fromType
226
- ? `Cannot CAST ${fromType} to ${toType}`
227
- : `Unsupported CAST to type ${toType}`
228
-
229
- return new Error(`${message}. Supported types: TEXT, VARCHAR, INTEGER, INT, BIGINT, FLOAT, REAL, DOUBLE, BOOLEAN`)
230
- }