sqlparser-rs 0.60.3 → 0.60.4

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/dist/index.mjs CHANGED
@@ -1,7 +1,3 @@
1
- import { createRequire } from "node:module";
2
- import { fileURLToPath } from "node:url";
3
- import { dirname, join } from "node:path";
4
-
5
1
  //#region src/dialects.ts
6
2
  /**
7
3
  * Generic SQL dialect - accepts most SQL syntax
@@ -153,20 +149,7 @@ const DIALECT_MAP = {
153
149
  hive: HiveDialect,
154
150
  oracle: OracleDialect
155
151
  };
156
- /**
157
- * Create a dialect instance from a string name
158
- *
159
- * @param name - The name of the dialect (case-insensitive)
160
- * @returns A dialect instance, or undefined if the dialect is not recognized
161
- *
162
- * @example
163
- * ```typescript
164
- * const dialect = dialectFromString('postgresql');
165
- * if (dialect) {
166
- * const ast = Parser.parse('SELECT 1', dialect);
167
- * }
168
- * ```
169
- */
152
+ /** Create a dialect instance from a string name (case-insensitive) */
170
153
  function dialectFromString(name) {
171
154
  const normalized = name.toLowerCase();
172
155
  const DialectClass = DIALECT_MAP[{
@@ -217,64 +200,96 @@ var WasmInitError = class WasmInitError extends Error {
217
200
  };
218
201
 
219
202
  //#endregion
220
- //#region src/parser.ts
203
+ //#region src/wasm.ts
221
204
  let wasmModule = null;
205
+ let initPromise = null;
206
+ let initStarted = false;
207
+ const isBrowser = typeof window !== "undefined" && typeof process === "undefined";
208
+ function startInit() {
209
+ if (initStarted) return;
210
+ initStarted = true;
211
+ initPromise = initWasm().catch(() => {});
212
+ }
213
+ startInit();
214
+ /** Get initialized WASM module or throw */
222
215
  function getWasmModule() {
223
216
  if (wasmModule) return wasmModule;
217
+ throw new WasmInitError("WASM module not yet initialized. Use the async import or wait for module to load: import(\"sqlparser-rs\").then(({ parse }) => parse(sql))");
218
+ }
219
+ /**
220
+ * Wait for WASM module to be ready
221
+ */
222
+ async function ready() {
223
+ startInit();
224
+ await initPromise;
225
+ }
226
+ /**
227
+ * Initialize the WASM module explicitly.
228
+ * Usually not needed - the module auto-initializes on first use.
229
+ */
230
+ async function initWasm() {
231
+ if (wasmModule) return;
232
+ if (isBrowser) {
233
+ try {
234
+ const wasmJsUrl = new URL("../wasm/sqlparser_rs_wasm_web.js", import.meta.url);
235
+ const wasmBinaryUrl = new URL("../wasm/sqlparser_rs_wasm_web_bg.wasm", import.meta.url);
236
+ const wasm = await import(
237
+ /* @vite-ignore */
238
+ wasmJsUrl.href
239
+ );
240
+ if (typeof wasm.default === "function") await wasm.default({ module_or_path: wasmBinaryUrl });
241
+ wasmModule = wasm;
242
+ } catch (error) {
243
+ throw new WasmInitError(`Failed to load WASM module in browser: ${error instanceof Error ? error.message : String(error)}`);
244
+ }
245
+ return;
246
+ }
224
247
  try {
225
- const wasmPath = join(dirname(fileURLToPath(import.meta.url)), "../wasm/sqlparser_rs_wasm.js");
226
- wasmModule = createRequire(import.meta.url)(wasmPath);
227
- return wasmModule;
248
+ wasmModule = await import(
249
+ /* @vite-ignore */
250
+ new URL("../wasm/sqlparser_rs_wasm.js", import.meta.url).href
251
+ );
228
252
  } catch (error) {
229
253
  throw new WasmInitError(`Failed to load WASM module: ${error instanceof Error ? error.message : String(error)}`);
230
254
  }
231
255
  }
256
+
257
+ //#endregion
258
+ //#region src/parser.ts
259
+ function resolveDialect(dialect = "generic") {
260
+ if (typeof dialect === "string") {
261
+ const resolved = dialectFromString(dialect);
262
+ if (!resolved) throw new Error(`Unknown dialect: ${dialect}`);
263
+ return resolved;
264
+ }
265
+ return dialect;
266
+ }
232
267
  /**
233
- * SQL Parser
234
- *
235
- * Parses SQL statements into an Abstract Syntax Tree (AST).
268
+ * SQL Parser - parses SQL statements into AST
236
269
  *
237
270
  * @example
238
271
  * ```typescript
239
272
  * import { Parser, PostgreSqlDialect } from 'sqlparser-rs';
240
273
  *
241
- * // Simple parsing
242
- * const statements = Parser.parse('SELECT * FROM users', new PostgreSqlDialect());
274
+ * const statements = Parser.parse('SELECT * FROM users', 'postgresql');
243
275
  *
244
- * // With builder pattern
276
+ * // With options
245
277
  * const parser = new Parser(new PostgreSqlDialect())
246
- * .withRecursionLimit(50)
247
278
  * .withOptions({ trailingCommas: true });
248
- *
249
- * const ast = parser.parse('SELECT * FROM users');
279
+ * const ast = parser.parse('SELECT a, b, FROM users');
250
280
  * ```
251
281
  */
252
282
  var Parser = class Parser {
253
- /**
254
- * Create a new parser instance
255
- *
256
- * @param dialect - The SQL dialect to use (defaults to GenericDialect)
257
- */
258
283
  constructor(dialect = new GenericDialect()) {
259
284
  this.dialect = dialect;
260
285
  this.options = {};
261
286
  }
262
- /**
263
- * Set the recursion limit for parsing nested expressions
264
- *
265
- * @param limit - Maximum recursion depth
266
- * @returns This parser instance for chaining
267
- */
287
+ /** Set recursion limit for parsing nested expressions */
268
288
  withRecursionLimit(limit) {
269
289
  this.options.recursionLimit = limit;
270
290
  return this;
271
291
  }
272
- /**
273
- * Set parser options
274
- *
275
- * @param options - Parser options
276
- * @returns This parser instance for chaining
277
- */
292
+ /** Set parser options */
278
293
  withOptions(options) {
279
294
  this.options = {
280
295
  ...this.options,
@@ -282,103 +297,83 @@ var Parser = class Parser {
282
297
  };
283
298
  return this;
284
299
  }
285
- /**
286
- * Parse SQL statements
287
- *
288
- * @param sql - SQL string to parse
289
- * @returns Array of parsed statements
290
- */
300
+ /** Parse SQL statements */
291
301
  parse(sql) {
292
302
  const wasm = getWasmModule();
293
303
  try {
294
304
  if (Object.keys(this.options).length > 0) return wasm.parse_sql_with_options(this.dialect.name, sql, this.options);
295
- else return wasm.parse_sql(this.dialect.name, sql);
305
+ return wasm.parse_sql(this.dialect.name, sql);
296
306
  } catch (error) {
297
307
  throw ParserError.fromWasmError(error);
298
308
  }
299
309
  }
300
- /**
301
- * Parse SQL statements
302
- *
303
- * @param sql - SQL string to parse
304
- * @param dialect - SQL dialect to use
305
- * @returns Array of parsed statements
306
- *
307
- * @example
308
- * ```typescript
309
- * const statements = Parser.parse('SELECT 1', new GenericDialect());
310
- * ```
311
- */
312
- static parse(sql, dialect = new GenericDialect()) {
313
- return new Parser(dialect).parse(sql);
310
+ /** Parse SQL into AST */
311
+ static parse(sql, dialect = "generic") {
312
+ return new Parser(resolveDialect(dialect)).parse(sql);
314
313
  }
315
- /**
316
- * Parse SQL and return the AST as a JSON string
317
- *
318
- * @param sql - SQL string to parse
319
- * @param dialect - SQL dialect to use
320
- * @returns JSON string representation of the AST
321
- */
322
- static parseToJson(sql, dialect = new GenericDialect()) {
314
+ /** Parse SQL and return AST as JSON string */
315
+ static parseToJson(sql, dialect = "generic") {
323
316
  const wasm = getWasmModule();
324
317
  try {
325
- return wasm.parse_sql_to_json_string(dialect.name, sql);
318
+ return wasm.parse_sql_to_json_string(resolveDialect(dialect).name, sql);
326
319
  } catch (error) {
327
320
  throw ParserError.fromWasmError(error);
328
321
  }
329
322
  }
330
- /**
331
- * Parse SQL and return a formatted string representation
332
- *
333
- * @param sql - SQL string to parse
334
- * @param dialect - SQL dialect to use
335
- * @returns String representation of the parsed SQL
336
- */
337
- static parseToString(sql, dialect = new GenericDialect()) {
323
+ /** Parse SQL and return formatted string representation */
324
+ static parseToString(sql, dialect = "generic") {
338
325
  const wasm = getWasmModule();
339
326
  try {
340
- return wasm.parse_sql_to_string(dialect.name, sql);
327
+ return wasm.parse_sql_to_string(resolveDialect(dialect).name, sql);
341
328
  } catch (error) {
342
329
  throw ParserError.fromWasmError(error);
343
330
  }
344
331
  }
345
- /**
346
- * Format SQL by parsing and regenerating it (round-trip)
347
- *
348
- * @param sql - SQL string to format
349
- * @param dialect - SQL dialect to use
350
- * @returns Formatted SQL string
351
- */
352
- static format(sql, dialect = new GenericDialect()) {
332
+ /** Format SQL by parsing and regenerating it */
333
+ static format(sql, dialect = "generic") {
353
334
  const wasm = getWasmModule();
354
335
  try {
355
- return wasm.format_sql(dialect.name, sql);
336
+ return wasm.format_sql(resolveDialect(dialect).name, sql);
356
337
  } catch (error) {
357
338
  throw ParserError.fromWasmError(error);
358
339
  }
359
340
  }
360
341
  /**
361
- * Validate SQL syntax without returning the full AST
362
- *
363
- * @param sql - SQL string to validate
364
- * @param dialect - SQL dialect to use
365
- * @returns true if valid, throws ParserError if invalid
342
+ * Validate SQL syntax
343
+ * @throws ParserError if SQL is invalid
366
344
  */
367
- static validate(sql, dialect = new GenericDialect()) {
345
+ static validate(sql, dialect = "generic") {
368
346
  const wasm = getWasmModule();
369
347
  try {
370
- return wasm.validate_sql(dialect.name, sql);
348
+ return wasm.validate_sql(resolveDialect(dialect).name, sql);
371
349
  } catch (error) {
372
350
  throw ParserError.fromWasmError(error);
373
351
  }
374
352
  }
375
- /**
376
- * Get the list of supported dialect names
377
- */
353
+ /** Get list of supported dialect names */
378
354
  static getSupportedDialects() {
379
355
  return getWasmModule().get_supported_dialects();
380
356
  }
381
357
  };
358
+ /**
359
+ * Parse SQL into AST
360
+ */
361
+ function parse(sql, dialect = "generic") {
362
+ return Parser.parse(sql, dialect);
363
+ }
364
+ /**
365
+ * Validate SQL syntax
366
+ * @throws ParserError if SQL is invalid
367
+ */
368
+ function validate(sql, dialect = "generic") {
369
+ return Parser.validate(sql, dialect);
370
+ }
371
+ /**
372
+ * Format SQL by parsing and regenerating it
373
+ */
374
+ function format(sql, dialect = "generic") {
375
+ return Parser.format(sql, dialect);
376
+ }
382
377
 
383
378
  //#endregion
384
- export { AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, DuckDbDialect, GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, OracleDialect, Parser, ParserError, PostgreSqlDialect, RedshiftDialect, SQLiteDialect, SUPPORTED_DIALECTS, SnowflakeDialect, WasmInitError, dialectFromString };
379
+ export { AnsiDialect, BigQueryDialect, ClickHouseDialect, DatabricksDialect, DuckDbDialect, GenericDialect, HiveDialect, MsSqlDialect, MySqlDialect, OracleDialect, Parser, ParserError, PostgreSqlDialect, RedshiftDialect, SQLiteDialect, SUPPORTED_DIALECTS, SnowflakeDialect, WasmInitError, dialectFromString, format, initWasm, parse, ready, validate };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlparser-rs",
3
- "version": "0.60.3",
3
+ "version": "0.60.4",
4
4
  "type": "module",
5
5
  "description": "A SQL parser for JavaScript and TypeScript, powered by datafusion-sqlparser-rs via WASM",
6
6
  "main": "dist/index.cjs",
@@ -44,7 +44,7 @@
44
44
  "license": "Apache-2.0",
45
45
  "repository": {
46
46
  "type": "git",
47
- "url": "https://github.com/guan404ming/sqlparser-rs"
47
+ "url": "git+https://github.com/guan404ming/sqlparser-rs.git"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^25.0.10",
package/wasm/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/sqlparser-rs.svg)](https://www.npmjs.com/package/sqlparser-rs)
4
4
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
5
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
- [![Node.js](https://img.shields.io/badge/Node.js-16+-green.svg)](https://nodejs.org/)
7
5
  [![WebAssembly](https://img.shields.io/badge/WebAssembly-powered-blueviolet.svg)](https://webassembly.org/)
8
6
  [![sqlparser](https://img.shields.io/badge/sqlparser--rs-v0.60.0-orange.svg)](https://github.com/apache/datafusion-sqlparser-rs)
9
7
 
@@ -11,11 +9,11 @@ A SQL parser for JavaScript and TypeScript, powered by [datafusion-sqlparser-rs]
11
9
 
12
10
  ## Features
13
11
 
14
- - Parse SQL into a detailed Abstract Syntax Tree (AST)
15
- - Support for 13+ SQL dialects (PostgreSQL, MySQL, SQLite, BigQuery, etc.)
16
- - Full TypeScript type definitions
17
- - Fast and accurate parsing using the battle-tested Rust implementation
18
- - Zero native dependencies
12
+ - Parse SQL into a detailed AST with full TypeScript types
13
+ - Support 14 SQL dialects (PostgreSQL, MySQL, SQLite, BigQuery, and more)
14
+ - Run in Node.js and browsers
15
+ - Stay small (~600KB gzipped) and fast (Rust + WebAssembly)
16
+ - Ship zero native dependencies
19
17
 
20
18
  ## Installation
21
19
 
@@ -23,187 +21,59 @@ A SQL parser for JavaScript and TypeScript, powered by [datafusion-sqlparser-rs]
23
21
  npm install sqlparser-rs
24
22
  ```
25
23
 
26
- ## Quick Start
24
+ ## Usage
27
25
 
28
26
  ```typescript
29
- import { Parser, GenericDialect, PostgreSqlDialect } from 'sqlparser-rs';
27
+ import { parse, format, validate } from 'sqlparser-rs';
30
28
 
31
- // Simple parsing
32
- const statements = Parser.parse('SELECT * FROM users', new GenericDialect());
33
- console.log(statements);
29
+ // Parse SQL into AST
30
+ const ast = parse('SELECT * FROM users');
34
31
 
35
32
  // With specific dialect
36
- const pgStatements = Parser.parse(
37
- 'SELECT * FROM users WHERE id = $1',
38
- new PostgreSqlDialect()
39
- );
33
+ const ast = parse('SELECT * FROM users WHERE id = $1', 'postgresql');
40
34
 
41
35
  // Format SQL
42
- const formatted = Parser.format('select * from users', new GenericDialect());
43
- console.log(formatted); // "SELECT * FROM users"
36
+ const sql = format('select * from users');
37
+ // "SELECT * FROM users"
44
38
 
45
- // Validate SQL
46
- try {
47
- Parser.validate('SELEC * FROM users', new GenericDialect());
48
- } catch (error) {
49
- console.log('Invalid SQL:', error.message);
50
- }
39
+ // Validate SQL (throws on invalid)
40
+ validate('SELECT * FROM users'); // ok
51
41
  ```
52
42
 
53
- ## API
54
-
55
- ### Parser
56
-
57
- The main class for parsing SQL.
58
-
59
- #### Static Methods
43
+ ### Working with AST
60
44
 
61
45
  ```typescript
62
- // Parse SQL into statements
63
- const statements = Parser.parse(sql: string, dialect: Dialect): Statement[];
64
-
65
- // Parse and return JSON string
66
- const json = Parser.parseToJson(sql: string, dialect: Dialect): string;
67
-
68
- // Parse and return formatted SQL string
69
- const formatted = Parser.parseToString(sql: string, dialect: Dialect): string;
70
-
71
- // Format SQL (round-trip through parser)
72
- const formatted = Parser.format(sql: string, dialect: Dialect): string;
73
-
74
- // Validate SQL syntax
75
- const isValid = Parser.validate(sql: string, dialect: Dialect): boolean;
76
-
77
- // Get list of supported dialects
78
- const dialects = Parser.getSupportedDialects(): string[];
79
- ```
80
-
81
- #### Instance Methods (Builder Pattern)
82
-
83
- ```typescript
84
- import { Parser, PostgreSqlDialect } from 'sqlparser-rs';
85
-
86
- const parser = new Parser(new PostgreSqlDialect())
87
- .withRecursionLimit(50) // Set max recursion depth
88
- .withOptions({ // Set parser options
89
- trailingCommas: true
90
- });
91
-
92
- const statements = parser.parse('SELECT * FROM users');
93
- ```
94
-
95
- ### Dialects
96
-
97
- All dialects from the upstream Rust crate are supported:
98
-
99
- ```typescript
100
- import {
101
- GenericDialect, // Permissive, accepts most SQL syntax
102
- AnsiDialect, // ANSI SQL standard
103
- MySqlDialect, // MySQL
104
- PostgreSqlDialect, // PostgreSQL
105
- SQLiteDialect, // SQLite
106
- SnowflakeDialect, // Snowflake
107
- RedshiftDialect, // Amazon Redshift
108
- MsSqlDialect, // Microsoft SQL Server
109
- ClickHouseDialect, // ClickHouse
110
- BigQueryDialect, // Google BigQuery
111
- DuckDbDialect, // DuckDB
112
- DatabricksDialect, // Databricks
113
- HiveDialect, // Apache Hive
114
- } from 'sqlparser-rs';
115
-
116
- // Create dialect from string
117
- import { dialectFromString } from 'sqlparser-rs';
118
- const dialect = dialectFromString('postgresql'); // Returns PostgreSqlDialect instance
46
+ // Parse and inspect
47
+ const ast = parse('SELECT id, name FROM users WHERE active = true');
48
+ console.log(JSON.stringify(ast, null, 2));
49
+
50
+ // Multiple statements
51
+ const statements = parse(`
52
+ SELECT * FROM users;
53
+ SELECT * FROM orders;
54
+ `);
55
+ console.log(statements.length); // 2
56
+
57
+ // Modify AST and convert back to SQL
58
+ const ast = parse('SELECT * FROM users')[0];
59
+ // ... modify ast ...
60
+ const sql = format(JSON.stringify([ast]));
119
61
  ```
120
62
 
121
63
  ### Error Handling
122
64
 
123
65
  ```typescript
124
- import { Parser, GenericDialect, ParserError } from 'sqlparser-rs';
125
-
126
66
  try {
127
- Parser.parse('SELEC * FROM users', new GenericDialect());
128
- } catch (error) {
129
- if (error instanceof ParserError) {
130
- console.log('Parse error:', error.message);
131
- if (error.location) {
132
- console.log(`At line ${error.location.line}, column ${error.location.column}`);
133
- }
134
- }
135
- }
136
- ```
137
-
138
- ### AST Types
139
-
140
- Full TypeScript types are provided for the AST:
141
-
142
- ```typescript
143
- import type { Statement, Query, Expr, Ident, ObjectName } from 'sqlparser-rs';
144
-
145
- const statements: Statement[] = Parser.parse('SELECT 1', new GenericDialect());
146
-
147
- // Statement is a discriminated union type
148
- for (const stmt of statements) {
149
- if ('Query' in stmt) {
150
- const query: Query = stmt.Query;
151
- console.log('Found SELECT query');
152
- } else if ('Insert' in stmt) {
153
- console.log('Found INSERT statement');
154
- }
67
+ parse('SELEC * FORM users');
68
+ } catch (e) {
69
+ console.error(e.message); // Parse error details
155
70
  }
156
71
  ```
157
72
 
158
- ## Development
159
-
160
- ### Prerequisites
73
+ ## Supported Dialects
161
74
 
162
- - Rust toolchain (1.70+)
163
- - wasm-pack (`cargo install wasm-pack`)
164
- - Node.js (16+)
165
-
166
- ### Build
167
-
168
- ```bash
169
- # Build everything
170
- ./scripts/build.sh
171
-
172
- # Or step by step:
173
- # 1. Build WASM
174
- wasm-pack build --target nodejs --out-dir ts/wasm
175
-
176
- # 2. Build TypeScript
177
- cd ts
178
- npm install
179
- npm run build
180
- ```
181
-
182
- ### Tests
183
-
184
- ```bash
185
- cd ts
186
- npm test
187
- ```
188
-
189
- ## Versioning
190
-
191
- This package follows the upstream [sqlparser-rs](https://github.com/apache/datafusion-sqlparser-rs) version:
192
-
193
- - **Major.Minor** matches the upstream Rust crate version
194
- - **Patch** is for TypeScript binding fixes (e.g., `0.60.3` = upstream `0.60.0` + binding fix)
195
-
196
- | This package | sqlparser-rs |
197
- |--------------|--------------|
198
- | 0.60.x | 0.60.0 |
199
-
200
- This approach is similar to [esbuild-wasm](https://github.com/evanw/esbuild) and [duckdb-wasm](https://github.com/duckdb/duckdb-wasm).
75
+ `generic`, `ansi`, `mysql`, `postgresql`, `sqlite`, `snowflake`, `redshift`, `mssql`, `clickhouse`, `bigquery`, `duckdb`, `databricks`, `hive`, `oracle`
201
76
 
202
77
  ## License
203
78
 
204
79
  Apache-2.0
205
-
206
- ## Related Projects
207
-
208
- - [datafusion-sqlparser-rs](https://github.com/apache/datafusion-sqlparser-rs) - The Rust SQL parser this package wraps
209
- - [Apache DataFusion](https://github.com/apache/datafusion) - Query execution framework using sqlparser-rs
package/wasm/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sqlparser-rs-wasm",
3
3
  "description": "WebAssembly bindings for sqlparser-rs SQL parser",
4
- "version": "0.60.3",
4
+ "version": "0.60.4",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
Binary file