@guanmingchiu/sqlparser-ts 0.60.0-rc3

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/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # sqlparser-ts
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@guanmingchiu/sqlparser-ts.svg)](https://www.npmjs.com/package/@guanmingchiu/sqlparser-ts)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@guanmingchiu/sqlparser-ts.svg)](https://www.npmjs.com/package/@guanmingchiu/sqlparser-ts)
5
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
6
+ [![WebAssembly](https://img.shields.io/badge/WebAssembly-powered-blueviolet.svg)](https://webassembly.org/)
7
+ [![sqlparser](https://img.shields.io/badge/sqlparser--rs-v0.60.0-orange.svg)](https://github.com/apache/datafusion-sqlparser-rs)
8
+
9
+ SQL parser for JavaScript and TypeScript, powered by [datafusion-sqlparser-rs](https://github.com/apache/datafusion-sqlparser-rs) via WebAssembly.
10
+
11
+ ## Features
12
+
13
+ - Parse SQL into a detailed AST with full TypeScript types
14
+ - Support 14 SQL dialects (PostgreSQL, MySQL, SQLite, BigQuery, and more)
15
+ - Run in Node.js and browsers
16
+ - Stay small (~600KB gzipped) and fast (Rust + WebAssembly)
17
+ - Ship zero native dependencies
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @guanmingchiu/sqlparser-ts
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```typescript
28
+ import { parse, format, validate } from '@guanmingchiu/sqlparser-ts';
29
+
30
+ // Parse SQL into AST
31
+ const ast = parse('SELECT * FROM users');
32
+
33
+ // With specific dialect
34
+ const ast = parse('SELECT * FROM users WHERE id = $1', 'postgresql');
35
+
36
+ // Format SQL
37
+ const sql = format('select * from users');
38
+ // "SELECT * FROM users"
39
+
40
+ // Validate SQL (throws on invalid)
41
+ validate('SELECT * FROM users'); // ok
42
+ ```
43
+
44
+ ### Working with AST
45
+
46
+ ```typescript
47
+ // Parse and inspect
48
+ const ast = parse('SELECT id, name FROM users WHERE active = true');
49
+ console.log(JSON.stringify(ast, null, 2));
50
+
51
+ // Multiple statements
52
+ const statements = parse(`
53
+ SELECT * FROM users;
54
+ SELECT * FROM orders;
55
+ `);
56
+ console.log(statements.length); // 2
57
+
58
+ // Modify AST and convert back to SQL
59
+ const ast = parse('SELECT * FROM users')[0];
60
+ // ... modify ast ...
61
+ const sql = format(JSON.stringify([ast]));
62
+ ```
63
+
64
+ ### Error Handling
65
+
66
+ ```typescript
67
+ try {
68
+ parse('SELEC * FORM users');
69
+ } catch (e) {
70
+ console.error(e.message); // Parse error details
71
+ }
72
+ ```
73
+
74
+ ## Supported Dialects
75
+
76
+ `generic`, `ansi`, `mysql`, `postgresql`, `sqlite`, `snowflake`, `redshift`, `mssql`, `clickhouse`, `bigquery`, `duckdb`, `databricks`, `hive`, `oracle`
77
+
78
+ ## Versioning
79
+
80
+ Follows [Semantic Versioning](https://semver.org/) with upstream tracking:
81
+
82
+ - MAJOR.MINOR: Tracks upstream [datafusion-sqlparser-rs](https://github.com/apache/datafusion-sqlparser-rs)
83
+ - PATCH: sqlparser-ts specific releases
84
+
85
+ Example: `0.60.4` = upstream 0.60 + 4 sqlparser-ts releases
86
+
87
+ ## License
88
+
89
+ Apache-2.0
package/dist/index.cjs ADDED
@@ -0,0 +1,403 @@
1
+
2
+ //#region src/dialects.ts
3
+ /**
4
+ * Generic SQL dialect - accepts most SQL syntax
5
+ */
6
+ var GenericDialect = class {
7
+ constructor() {
8
+ this.name = "generic";
9
+ }
10
+ };
11
+ /**
12
+ * ANSI SQL standard dialect
13
+ */
14
+ var AnsiDialect = class {
15
+ constructor() {
16
+ this.name = "ansi";
17
+ }
18
+ };
19
+ /**
20
+ * MySQL dialect
21
+ */
22
+ var MySqlDialect = class {
23
+ constructor() {
24
+ this.name = "mysql";
25
+ }
26
+ };
27
+ /**
28
+ * PostgreSQL dialect
29
+ */
30
+ var PostgreSqlDialect = class {
31
+ constructor() {
32
+ this.name = "postgresql";
33
+ }
34
+ };
35
+ /**
36
+ * SQLite dialect
37
+ */
38
+ var SQLiteDialect = class {
39
+ constructor() {
40
+ this.name = "sqlite";
41
+ }
42
+ };
43
+ /**
44
+ * Snowflake dialect
45
+ */
46
+ var SnowflakeDialect = class {
47
+ constructor() {
48
+ this.name = "snowflake";
49
+ }
50
+ };
51
+ /**
52
+ * Amazon Redshift dialect
53
+ */
54
+ var RedshiftDialect = class {
55
+ constructor() {
56
+ this.name = "redshift";
57
+ }
58
+ };
59
+ /**
60
+ * Microsoft SQL Server dialect
61
+ */
62
+ var MsSqlDialect = class {
63
+ constructor() {
64
+ this.name = "mssql";
65
+ }
66
+ };
67
+ /**
68
+ * ClickHouse dialect
69
+ */
70
+ var ClickHouseDialect = class {
71
+ constructor() {
72
+ this.name = "clickhouse";
73
+ }
74
+ };
75
+ /**
76
+ * Google BigQuery dialect
77
+ */
78
+ var BigQueryDialect = class {
79
+ constructor() {
80
+ this.name = "bigquery";
81
+ }
82
+ };
83
+ /**
84
+ * DuckDB dialect
85
+ */
86
+ var DuckDbDialect = class {
87
+ constructor() {
88
+ this.name = "duckdb";
89
+ }
90
+ };
91
+ /**
92
+ * Databricks dialect
93
+ */
94
+ var DatabricksDialect = class {
95
+ constructor() {
96
+ this.name = "databricks";
97
+ }
98
+ };
99
+ /**
100
+ * Apache Hive dialect
101
+ */
102
+ var HiveDialect = class {
103
+ constructor() {
104
+ this.name = "hive";
105
+ }
106
+ };
107
+ /**
108
+ * Oracle dialect
109
+ */
110
+ var OracleDialect = class {
111
+ constructor() {
112
+ this.name = "oracle";
113
+ }
114
+ };
115
+ /**
116
+ * All supported dialect names
117
+ */
118
+ const SUPPORTED_DIALECTS = [
119
+ "generic",
120
+ "ansi",
121
+ "mysql",
122
+ "postgresql",
123
+ "sqlite",
124
+ "snowflake",
125
+ "redshift",
126
+ "mssql",
127
+ "clickhouse",
128
+ "bigquery",
129
+ "duckdb",
130
+ "databricks",
131
+ "hive",
132
+ "oracle"
133
+ ];
134
+ /**
135
+ * Map of dialect names to dialect classes
136
+ */
137
+ const DIALECT_MAP = {
138
+ generic: GenericDialect,
139
+ ansi: AnsiDialect,
140
+ mysql: MySqlDialect,
141
+ postgresql: PostgreSqlDialect,
142
+ sqlite: SQLiteDialect,
143
+ snowflake: SnowflakeDialect,
144
+ redshift: RedshiftDialect,
145
+ mssql: MsSqlDialect,
146
+ clickhouse: ClickHouseDialect,
147
+ bigquery: BigQueryDialect,
148
+ duckdb: DuckDbDialect,
149
+ databricks: DatabricksDialect,
150
+ hive: HiveDialect,
151
+ oracle: OracleDialect
152
+ };
153
+ /** Create a dialect instance from a string name (case-insensitive) */
154
+ function dialectFromString(name) {
155
+ const normalized = name.toLowerCase();
156
+ const DialectClass = DIALECT_MAP[{
157
+ postgres: "postgresql",
158
+ pg: "postgresql",
159
+ sqlserver: "mssql",
160
+ duck: "duckdb"
161
+ }[normalized] ?? normalized];
162
+ return DialectClass ? new DialectClass() : void 0;
163
+ }
164
+
165
+ //#endregion
166
+ //#region src/types/errors.ts
167
+ /**
168
+ * Error thrown when SQL parsing fails
169
+ */
170
+ var ParserError = class ParserError extends Error {
171
+ constructor(message, location) {
172
+ super(message);
173
+ this.name = "ParserError";
174
+ this.location = location;
175
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ParserError);
176
+ }
177
+ /**
178
+ * Create a ParserError from a WASM error object
179
+ */
180
+ static fromWasmError(error) {
181
+ if (typeof error === "string") return new ParserError(error);
182
+ if (error && typeof error === "object") {
183
+ const err = error;
184
+ return new ParserError(typeof err.message === "string" ? err.message : String(error), typeof err.line === "number" && typeof err.column === "number" ? {
185
+ line: err.line,
186
+ column: err.column
187
+ } : void 0);
188
+ }
189
+ return new ParserError(String(error));
190
+ }
191
+ };
192
+ /**
193
+ * Error thrown when WASM module fails to initialize
194
+ */
195
+ var WasmInitError = class WasmInitError extends Error {
196
+ constructor(message) {
197
+ super(message);
198
+ this.name = "WasmInitError";
199
+ if (Error.captureStackTrace) Error.captureStackTrace(this, WasmInitError);
200
+ }
201
+ };
202
+
203
+ //#endregion
204
+ //#region src/wasm.ts
205
+ let wasmModule = null;
206
+ let initPromise = null;
207
+ let initStarted = false;
208
+ const isBrowser = typeof window !== "undefined" && typeof process === "undefined";
209
+ function startInit() {
210
+ if (initStarted) return;
211
+ initStarted = true;
212
+ initPromise = initWasm().catch(() => {});
213
+ }
214
+ startInit();
215
+ /** Get initialized WASM module or throw */
216
+ function getWasmModule() {
217
+ if (wasmModule) return wasmModule;
218
+ throw new WasmInitError("WASM module not yet initialized. Use the async import or wait for module to load: import(\"@guanmingchiu/sqlparser-ts\").then(({ parse }) => parse(sql))");
219
+ }
220
+ /**
221
+ * Wait for WASM module to be ready
222
+ */
223
+ async function ready() {
224
+ startInit();
225
+ await initPromise;
226
+ }
227
+ /**
228
+ * Initialize the WASM module explicitly.
229
+ * Usually not needed - the module auto-initializes on first use.
230
+ */
231
+ async function initWasm() {
232
+ if (wasmModule) return;
233
+ if (isBrowser) {
234
+ try {
235
+ const wasmJsUrl = new URL("../wasm/sqlparser_rs_wasm_web.js", require("url").pathToFileURL(__filename).href);
236
+ const wasmBinaryUrl = new URL("../wasm/sqlparser_rs_wasm_web_bg.wasm", require("url").pathToFileURL(__filename).href);
237
+ const wasm = await import(
238
+ /* @vite-ignore */
239
+ wasmJsUrl.href
240
+ );
241
+ if (typeof wasm.default === "function") await wasm.default({ module_or_path: wasmBinaryUrl });
242
+ wasmModule = wasm;
243
+ } catch (error) {
244
+ throw new WasmInitError(`Failed to load WASM module in browser: ${error instanceof Error ? error.message : String(error)}`);
245
+ }
246
+ return;
247
+ }
248
+ try {
249
+ wasmModule = await import(
250
+ /* @vite-ignore */
251
+ new URL("../wasm/sqlparser_rs_wasm.js", require("url").pathToFileURL(__filename).href).href
252
+ );
253
+ } catch (error) {
254
+ throw new WasmInitError(`Failed to load WASM module: ${error instanceof Error ? error.message : String(error)}`);
255
+ }
256
+ }
257
+
258
+ //#endregion
259
+ //#region src/parser.ts
260
+ function resolveDialect(dialect = "generic") {
261
+ if (typeof dialect === "string") {
262
+ const resolved = dialectFromString(dialect);
263
+ if (!resolved) throw new Error(`Unknown dialect: ${dialect}`);
264
+ return resolved;
265
+ }
266
+ return dialect;
267
+ }
268
+ /**
269
+ * SQL Parser - parses SQL statements into AST
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * import { Parser, PostgreSqlDialect } from '@guanmingchiu/sqlparser-ts';
274
+ *
275
+ * const statements = Parser.parse('SELECT * FROM users', 'postgresql');
276
+ *
277
+ * // With options
278
+ * const parser = new Parser(new PostgreSqlDialect())
279
+ * .withOptions({ trailingCommas: true });
280
+ * const ast = parser.parse('SELECT a, b, FROM users');
281
+ * ```
282
+ */
283
+ var Parser = class Parser {
284
+ constructor(dialect = new GenericDialect()) {
285
+ this.dialect = dialect;
286
+ this.options = {};
287
+ }
288
+ /** Set recursion limit for parsing nested expressions */
289
+ withRecursionLimit(limit) {
290
+ this.options.recursionLimit = limit;
291
+ return this;
292
+ }
293
+ /** Set parser options */
294
+ withOptions(options) {
295
+ this.options = {
296
+ ...this.options,
297
+ ...options
298
+ };
299
+ return this;
300
+ }
301
+ /** Parse SQL statements */
302
+ parse(sql) {
303
+ const wasm = getWasmModule();
304
+ try {
305
+ if (Object.keys(this.options).length > 0) return wasm.parse_sql_with_options(this.dialect.name, sql, this.options);
306
+ return wasm.parse_sql(this.dialect.name, sql);
307
+ } catch (error) {
308
+ throw ParserError.fromWasmError(error);
309
+ }
310
+ }
311
+ /** Parse SQL into AST */
312
+ static parse(sql, dialect = "generic") {
313
+ return new Parser(resolveDialect(dialect)).parse(sql);
314
+ }
315
+ /** Parse SQL and return AST as JSON string */
316
+ static parseToJson(sql, dialect = "generic") {
317
+ const wasm = getWasmModule();
318
+ try {
319
+ return wasm.parse_sql_to_json_string(resolveDialect(dialect).name, sql);
320
+ } catch (error) {
321
+ throw ParserError.fromWasmError(error);
322
+ }
323
+ }
324
+ /** Parse SQL and return formatted string representation */
325
+ static parseToString(sql, dialect = "generic") {
326
+ const wasm = getWasmModule();
327
+ try {
328
+ return wasm.parse_sql_to_string(resolveDialect(dialect).name, sql);
329
+ } catch (error) {
330
+ throw ParserError.fromWasmError(error);
331
+ }
332
+ }
333
+ /** Format SQL by parsing and regenerating it */
334
+ static format(sql, dialect = "generic") {
335
+ const wasm = getWasmModule();
336
+ try {
337
+ return wasm.format_sql(resolveDialect(dialect).name, sql);
338
+ } catch (error) {
339
+ throw ParserError.fromWasmError(error);
340
+ }
341
+ }
342
+ /**
343
+ * Validate SQL syntax
344
+ * @throws ParserError if SQL is invalid
345
+ */
346
+ static validate(sql, dialect = "generic") {
347
+ const wasm = getWasmModule();
348
+ try {
349
+ return wasm.validate_sql(resolveDialect(dialect).name, sql);
350
+ } catch (error) {
351
+ throw ParserError.fromWasmError(error);
352
+ }
353
+ }
354
+ /** Get list of supported dialect names */
355
+ static getSupportedDialects() {
356
+ return getWasmModule().get_supported_dialects();
357
+ }
358
+ };
359
+ /**
360
+ * Parse SQL into AST
361
+ */
362
+ function parse(sql, dialect = "generic") {
363
+ return Parser.parse(sql, dialect);
364
+ }
365
+ /**
366
+ * Validate SQL syntax
367
+ * @throws ParserError if SQL is invalid
368
+ */
369
+ function validate(sql, dialect = "generic") {
370
+ return Parser.validate(sql, dialect);
371
+ }
372
+ /**
373
+ * Format SQL by parsing and regenerating it
374
+ */
375
+ function format(sql, dialect = "generic") {
376
+ return Parser.format(sql, dialect);
377
+ }
378
+
379
+ //#endregion
380
+ exports.AnsiDialect = AnsiDialect;
381
+ exports.BigQueryDialect = BigQueryDialect;
382
+ exports.ClickHouseDialect = ClickHouseDialect;
383
+ exports.DatabricksDialect = DatabricksDialect;
384
+ exports.DuckDbDialect = DuckDbDialect;
385
+ exports.GenericDialect = GenericDialect;
386
+ exports.HiveDialect = HiveDialect;
387
+ exports.MsSqlDialect = MsSqlDialect;
388
+ exports.MySqlDialect = MySqlDialect;
389
+ exports.OracleDialect = OracleDialect;
390
+ exports.Parser = Parser;
391
+ exports.ParserError = ParserError;
392
+ exports.PostgreSqlDialect = PostgreSqlDialect;
393
+ exports.RedshiftDialect = RedshiftDialect;
394
+ exports.SQLiteDialect = SQLiteDialect;
395
+ exports.SUPPORTED_DIALECTS = SUPPORTED_DIALECTS;
396
+ exports.SnowflakeDialect = SnowflakeDialect;
397
+ exports.WasmInitError = WasmInitError;
398
+ exports.dialectFromString = dialectFromString;
399
+ exports.format = format;
400
+ exports.initWasm = initWasm;
401
+ exports.parse = parse;
402
+ exports.ready = ready;
403
+ exports.validate = validate;