postgrest-parser 0.1.0 → 0.1.2
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/package.json +4 -5
- package/pkg/LICENSE +21 -0
- package/pkg/README.md +1082 -0
- package/pkg/client.d.ts +226 -0
- package/pkg/client.js +378 -0
- package/pkg/client.ts +528 -0
- package/pkg/package.json +31 -0
- package/pkg/postgrest_parser.d.ts +294 -0
- package/pkg/postgrest_parser.js +1151 -0
- package/pkg/postgrest_parser_bg.wasm +0 -0
- package/pkg/postgrest_parser_bg.wasm.d.ts +27 -0
- package/pkg/tsconfig.json +33 -0
- package/pkg/types.d.ts +174 -0
- package/pkg/types.js +16 -0
- package/pkg/types.ts +203 -0
package/pkg/client.d.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe TypeScript wrapper for PostgREST Parser
|
|
3
|
+
*
|
|
4
|
+
* This module provides a type-safe, idiomatic TypeScript API on top of
|
|
5
|
+
* the auto-generated WASM bindings, improving developer experience.
|
|
6
|
+
*/
|
|
7
|
+
import type { HttpMethod, QueryResult, RequestHeaders, SelectOptions, InsertOptions, UpdateOptions, DeleteOptions, RpcOptions } from "./types.js";
|
|
8
|
+
export { default as init, initSchemaFromDb } from "./postgrest_parser.js";
|
|
9
|
+
/**
|
|
10
|
+
* Type-safe PostgREST Parser client
|
|
11
|
+
*
|
|
12
|
+
* Provides strongly-typed methods for generating PostgREST-compatible SQL queries.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const client = new PostgRESTParser();
|
|
17
|
+
*
|
|
18
|
+
* // SELECT query
|
|
19
|
+
* const getUsers = client.select("users", {
|
|
20
|
+
* filters: { "age": "gte.18", "status": "eq.active" },
|
|
21
|
+
* order: ["created_at.desc"],
|
|
22
|
+
* limit: 10
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // INSERT query
|
|
26
|
+
* const createUser = client.insert("users", {
|
|
27
|
+
* name: "Alice",
|
|
28
|
+
* email: "alice@example.com"
|
|
29
|
+
* }, {
|
|
30
|
+
* returning: "*",
|
|
31
|
+
* prefer: { return: "representation" }
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Execute with your database client
|
|
35
|
+
* const rows = await db.query(getUsers.query, getUsers.params);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class PostgRESTParser {
|
|
39
|
+
/**
|
|
40
|
+
* Parse a complete HTTP request and generate appropriate SQL
|
|
41
|
+
*
|
|
42
|
+
* This is the universal routing method that handles all HTTP methods.
|
|
43
|
+
*
|
|
44
|
+
* @param method - HTTP method: "GET", "POST", "PUT", "PATCH", "DELETE"
|
|
45
|
+
* @param path - Resource path (table name or "rpc/function_name")
|
|
46
|
+
* @param queryString - URL query string
|
|
47
|
+
* @param body - Request body (object or null)
|
|
48
|
+
* @param headers - Request headers (object or null)
|
|
49
|
+
* @returns Query result with SQL, params, and tables
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const result = client.parseRequest("GET", "users", "age=gte.18", null, null);
|
|
54
|
+
* const rows = await db.query(result.query, result.params);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
parseRequest(method: HttpMethod, path: string, queryString: string, body?: Record<string, unknown> | Record<string, unknown>[] | null, headers?: RequestHeaders | null): QueryResult;
|
|
58
|
+
/**
|
|
59
|
+
* Generate a SELECT query
|
|
60
|
+
*
|
|
61
|
+
* @param table - Table name to query
|
|
62
|
+
* @param options - Query options (filters, ordering, pagination)
|
|
63
|
+
* @returns Query result with SQL, params, and tables
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const result = client.select("users", {
|
|
68
|
+
* filters: { "age": "gte.18", "status": "eq.active" },
|
|
69
|
+
* order: ["created_at.desc"],
|
|
70
|
+
* limit: 10,
|
|
71
|
+
* offset: 0
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
select(table: string, options?: SelectOptions): QueryResult;
|
|
76
|
+
/**
|
|
77
|
+
* Generate an INSERT query
|
|
78
|
+
*
|
|
79
|
+
* @param table - Table name
|
|
80
|
+
* @param data - Data to insert (single object or array of objects)
|
|
81
|
+
* @param options - Insert options (returning, onConflict, prefer)
|
|
82
|
+
* @returns Query result with SQL, params, and tables
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const result = client.insert("users", {
|
|
87
|
+
* name: "Alice",
|
|
88
|
+
* email: "alice@example.com"
|
|
89
|
+
* }, {
|
|
90
|
+
* returning: "*",
|
|
91
|
+
* prefer: { return: "representation" }
|
|
92
|
+
* });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
insert(table: string, data: Record<string, unknown> | Record<string, unknown>[], options?: InsertOptions): QueryResult;
|
|
96
|
+
/**
|
|
97
|
+
* Generate an UPSERT query (INSERT with ON CONFLICT)
|
|
98
|
+
*
|
|
99
|
+
* PUT method auto-generates ON CONFLICT from filter columns.
|
|
100
|
+
*
|
|
101
|
+
* @param table - Table name
|
|
102
|
+
* @param data - Data to upsert
|
|
103
|
+
* @param conflictColumns - Columns to use for conflict detection
|
|
104
|
+
* @param options - Upsert options (returning, prefer)
|
|
105
|
+
* @returns Query result with SQL, params, and tables
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const result = client.upsert("users", {
|
|
110
|
+
* email: "alice@example.com",
|
|
111
|
+
* name: "Alice Updated"
|
|
112
|
+
* }, ["email"], {
|
|
113
|
+
* returning: "*"
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
upsert(table: string, data: Record<string, unknown>, conflictColumns: string[], options?: InsertOptions): QueryResult;
|
|
118
|
+
/**
|
|
119
|
+
* Generate an UPDATE query
|
|
120
|
+
*
|
|
121
|
+
* @param table - Table name
|
|
122
|
+
* @param data - Data to update
|
|
123
|
+
* @param filters - Filter conditions to match rows
|
|
124
|
+
* @param options - Update options (returning, prefer)
|
|
125
|
+
* @returns Query result with SQL, params, and tables
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const result = client.update("users", {
|
|
130
|
+
* status: "active"
|
|
131
|
+
* }, {
|
|
132
|
+
* "id": "eq.123"
|
|
133
|
+
* }, {
|
|
134
|
+
* returning: "id,status"
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
update(table: string, data: Record<string, unknown>, filters: Record<string, string>, options?: UpdateOptions): QueryResult;
|
|
139
|
+
/**
|
|
140
|
+
* Generate a DELETE query
|
|
141
|
+
*
|
|
142
|
+
* @param table - Table name
|
|
143
|
+
* @param filters - Filter conditions to match rows to delete
|
|
144
|
+
* @param options - Delete options (returning, prefer)
|
|
145
|
+
* @returns Query result with SQL, params, and tables
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const result = client.delete("users", {
|
|
150
|
+
* "status": "eq.inactive",
|
|
151
|
+
* "last_login": "lt.2023-01-01"
|
|
152
|
+
* }, {
|
|
153
|
+
* returning: "id"
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
delete(table: string, filters: Record<string, string>, options?: DeleteOptions): QueryResult;
|
|
158
|
+
/**
|
|
159
|
+
* Generate an RPC (stored procedure/function) call
|
|
160
|
+
*
|
|
161
|
+
* @param functionName - Function name (can include schema)
|
|
162
|
+
* @param args - Function arguments as object
|
|
163
|
+
* @param options - RPC options (select, filters, ordering)
|
|
164
|
+
* @returns Query result with SQL, params, and tables
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const result = client.rpc("calculate_total", {
|
|
169
|
+
* order_id: 123,
|
|
170
|
+
* tax_rate: 0.08
|
|
171
|
+
* }, {
|
|
172
|
+
* select: ["total", "tax"],
|
|
173
|
+
* limit: 1
|
|
174
|
+
* });
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
rpc(functionName: string, args?: Record<string, unknown>, options?: RpcOptions): QueryResult;
|
|
178
|
+
/**
|
|
179
|
+
* Parse a query string without generating SQL
|
|
180
|
+
*
|
|
181
|
+
* Useful for inspecting the parsed structure before generating SQL.
|
|
182
|
+
*
|
|
183
|
+
* @param queryString - PostgREST query string
|
|
184
|
+
* @returns Parsed query parameters as object
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const parsed = client.parseOnly("age=gte.18&status=eq.active&order=created_at.desc");
|
|
189
|
+
* console.log(parsed); // { filters: [...], order: [...] }
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
parseOnly(queryString: string): unknown;
|
|
193
|
+
/**
|
|
194
|
+
* Build a WHERE clause from filter conditions
|
|
195
|
+
*
|
|
196
|
+
* @param filters - Filter conditions as object
|
|
197
|
+
* @returns Object with clause (SQL string) and params (array of values)
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const filters = [
|
|
202
|
+
* { column: "age", operator: "gte", value: "18" },
|
|
203
|
+
* { column: "status", operator: "eq", value: "active" }
|
|
204
|
+
* ];
|
|
205
|
+
* const result = client.buildFilterClause(filters);
|
|
206
|
+
* console.log(result.clause); // "age >= $1 AND status = $2"
|
|
207
|
+
* console.log(result.params); // ["18", "active"]
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
buildFilterClause(filters: unknown): unknown;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create a new PostgREST Parser client instance
|
|
214
|
+
*
|
|
215
|
+
* @returns New PostgRESTParser instance
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* import { createClient } from './pkg/client.js';
|
|
220
|
+
*
|
|
221
|
+
* const client = createClient();
|
|
222
|
+
* const result = client.select("users", { limit: 10 });
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export declare function createClient(): PostgRESTParser;
|
|
226
|
+
export type { HttpMethod, QueryResult, RequestHeaders, SelectOptions, InsertOptions, UpdateOptions, DeleteOptions, RpcOptions, PreferOptions, PostgRESTParserError, } from "./types.js";
|
package/pkg/client.js
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe TypeScript wrapper for PostgREST Parser
|
|
3
|
+
*
|
|
4
|
+
* This module provides a type-safe, idiomatic TypeScript API on top of
|
|
5
|
+
* the auto-generated WASM bindings, improving developer experience.
|
|
6
|
+
*/
|
|
7
|
+
import { parseRequest as wasmParseRequest, parseInsert as wasmParseInsert, parseUpdate as wasmParseUpdate, parseDelete as wasmParseDelete, parseRpc as wasmParseRpc, parseOnly as wasmParseOnly, buildFilterClause as wasmBuildFilterClause, } from "./postgrest_parser.js";
|
|
8
|
+
// Re-export WASM initialization functions
|
|
9
|
+
export { default as init, initSchemaFromDb } from "./postgrest_parser.js";
|
|
10
|
+
/**
|
|
11
|
+
* Convert WASM result to typed QueryResult
|
|
12
|
+
*/
|
|
13
|
+
function toQueryResult(wasmResult) {
|
|
14
|
+
return {
|
|
15
|
+
query: wasmResult.query,
|
|
16
|
+
params: wasmResult.params,
|
|
17
|
+
tables: wasmResult.tables,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert headers object to JSON string
|
|
22
|
+
*/
|
|
23
|
+
function headersToJson(headers) {
|
|
24
|
+
return headers ? JSON.stringify(headers) : undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Convert PreferOptions to Prefer header value
|
|
28
|
+
*/
|
|
29
|
+
function preferToHeader(prefer) {
|
|
30
|
+
if (!prefer)
|
|
31
|
+
return undefined;
|
|
32
|
+
const parts = [];
|
|
33
|
+
if (prefer.return)
|
|
34
|
+
parts.push(`return=${prefer.return}`);
|
|
35
|
+
if (prefer.resolution)
|
|
36
|
+
parts.push(`resolution=${prefer.resolution}`);
|
|
37
|
+
if (prefer.missing)
|
|
38
|
+
parts.push(`missing=${prefer.missing}`);
|
|
39
|
+
if (prefer.count)
|
|
40
|
+
parts.push(`count=${prefer.count}`);
|
|
41
|
+
return parts.length > 0 ? parts.join(",") : undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build query string from filters and options
|
|
45
|
+
*/
|
|
46
|
+
function buildQueryString(filters, options) {
|
|
47
|
+
const parts = [];
|
|
48
|
+
// Add filters
|
|
49
|
+
if (filters) {
|
|
50
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
51
|
+
parts.push(`${key}=${value}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Add select
|
|
55
|
+
if (options?.select) {
|
|
56
|
+
const select = Array.isArray(options.select)
|
|
57
|
+
? options.select.join(",")
|
|
58
|
+
: options.select;
|
|
59
|
+
parts.push(`select=${select}`);
|
|
60
|
+
}
|
|
61
|
+
// Add order
|
|
62
|
+
if (options?.order) {
|
|
63
|
+
const order = Array.isArray(options.order)
|
|
64
|
+
? options.order.join(",")
|
|
65
|
+
: options.order;
|
|
66
|
+
parts.push(`order=${order}`);
|
|
67
|
+
}
|
|
68
|
+
// Add limit
|
|
69
|
+
if (options?.limit !== undefined) {
|
|
70
|
+
parts.push(`limit=${options.limit}`);
|
|
71
|
+
}
|
|
72
|
+
// Add offset
|
|
73
|
+
if (options?.offset !== undefined) {
|
|
74
|
+
parts.push(`offset=${options.offset}`);
|
|
75
|
+
}
|
|
76
|
+
// Add on_conflict
|
|
77
|
+
if (options?.onConflict) {
|
|
78
|
+
const onConflict = Array.isArray(options.onConflict)
|
|
79
|
+
? options.onConflict.join(",")
|
|
80
|
+
: options.onConflict;
|
|
81
|
+
parts.push(`on_conflict=${onConflict}`);
|
|
82
|
+
}
|
|
83
|
+
// Add returning
|
|
84
|
+
if (options?.returning) {
|
|
85
|
+
const returning = Array.isArray(options.returning)
|
|
86
|
+
? options.returning.join(",")
|
|
87
|
+
: options.returning;
|
|
88
|
+
parts.push(`returning=${returning}`);
|
|
89
|
+
}
|
|
90
|
+
return parts.join("&");
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Type-safe PostgREST Parser client
|
|
94
|
+
*
|
|
95
|
+
* Provides strongly-typed methods for generating PostgREST-compatible SQL queries.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const client = new PostgRESTParser();
|
|
100
|
+
*
|
|
101
|
+
* // SELECT query
|
|
102
|
+
* const getUsers = client.select("users", {
|
|
103
|
+
* filters: { "age": "gte.18", "status": "eq.active" },
|
|
104
|
+
* order: ["created_at.desc"],
|
|
105
|
+
* limit: 10
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* // INSERT query
|
|
109
|
+
* const createUser = client.insert("users", {
|
|
110
|
+
* name: "Alice",
|
|
111
|
+
* email: "alice@example.com"
|
|
112
|
+
* }, {
|
|
113
|
+
* returning: "*",
|
|
114
|
+
* prefer: { return: "representation" }
|
|
115
|
+
* });
|
|
116
|
+
*
|
|
117
|
+
* // Execute with your database client
|
|
118
|
+
* const rows = await db.query(getUsers.query, getUsers.params);
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export class PostgRESTParser {
|
|
122
|
+
/**
|
|
123
|
+
* Parse a complete HTTP request and generate appropriate SQL
|
|
124
|
+
*
|
|
125
|
+
* This is the universal routing method that handles all HTTP methods.
|
|
126
|
+
*
|
|
127
|
+
* @param method - HTTP method: "GET", "POST", "PUT", "PATCH", "DELETE"
|
|
128
|
+
* @param path - Resource path (table name or "rpc/function_name")
|
|
129
|
+
* @param queryString - URL query string
|
|
130
|
+
* @param body - Request body (object or null)
|
|
131
|
+
* @param headers - Request headers (object or null)
|
|
132
|
+
* @returns Query result with SQL, params, and tables
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const result = client.parseRequest("GET", "users", "age=gte.18", null, null);
|
|
137
|
+
* const rows = await db.query(result.query, result.params);
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
parseRequest(method, path, queryString, body, headers) {
|
|
141
|
+
const bodyJson = body ? JSON.stringify(body) : undefined;
|
|
142
|
+
const headersJson = headers ? headersToJson(headers) : undefined;
|
|
143
|
+
const result = wasmParseRequest(method, path, queryString, bodyJson, headersJson);
|
|
144
|
+
return toQueryResult(result);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Generate a SELECT query
|
|
148
|
+
*
|
|
149
|
+
* @param table - Table name to query
|
|
150
|
+
* @param options - Query options (filters, ordering, pagination)
|
|
151
|
+
* @returns Query result with SQL, params, and tables
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const result = client.select("users", {
|
|
156
|
+
* filters: { "age": "gte.18", "status": "eq.active" },
|
|
157
|
+
* order: ["created_at.desc"],
|
|
158
|
+
* limit: 10,
|
|
159
|
+
* offset: 0
|
|
160
|
+
* });
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
select(table, options = {}) {
|
|
164
|
+
const queryString = buildQueryString(options.filters, options);
|
|
165
|
+
const headers = options.count
|
|
166
|
+
? { Prefer: `count=${options.count}` }
|
|
167
|
+
: undefined;
|
|
168
|
+
const result = wasmParseRequest("GET", table, queryString, undefined, headersToJson(headers));
|
|
169
|
+
return toQueryResult(result);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Generate an INSERT query
|
|
173
|
+
*
|
|
174
|
+
* @param table - Table name
|
|
175
|
+
* @param data - Data to insert (single object or array of objects)
|
|
176
|
+
* @param options - Insert options (returning, onConflict, prefer)
|
|
177
|
+
* @returns Query result with SQL, params, and tables
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const result = client.insert("users", {
|
|
182
|
+
* name: "Alice",
|
|
183
|
+
* email: "alice@example.com"
|
|
184
|
+
* }, {
|
|
185
|
+
* returning: "*",
|
|
186
|
+
* prefer: { return: "representation" }
|
|
187
|
+
* });
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
insert(table, data, options = {}) {
|
|
191
|
+
const queryString = buildQueryString(undefined, {
|
|
192
|
+
onConflict: options.onConflict,
|
|
193
|
+
returning: options.returning,
|
|
194
|
+
});
|
|
195
|
+
const preferHeader = preferToHeader(options.prefer);
|
|
196
|
+
const headers = preferHeader
|
|
197
|
+
? { Prefer: preferHeader }
|
|
198
|
+
: undefined;
|
|
199
|
+
const result = wasmParseInsert(table, JSON.stringify(data), queryString || undefined, headersToJson(headers));
|
|
200
|
+
return toQueryResult(result);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Generate an UPSERT query (INSERT with ON CONFLICT)
|
|
204
|
+
*
|
|
205
|
+
* PUT method auto-generates ON CONFLICT from filter columns.
|
|
206
|
+
*
|
|
207
|
+
* @param table - Table name
|
|
208
|
+
* @param data - Data to upsert
|
|
209
|
+
* @param conflictColumns - Columns to use for conflict detection
|
|
210
|
+
* @param options - Upsert options (returning, prefer)
|
|
211
|
+
* @returns Query result with SQL, params, and tables
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const result = client.upsert("users", {
|
|
216
|
+
* email: "alice@example.com",
|
|
217
|
+
* name: "Alice Updated"
|
|
218
|
+
* }, ["email"], {
|
|
219
|
+
* returning: "*"
|
|
220
|
+
* });
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
upsert(table, data, conflictColumns, options = {}) {
|
|
224
|
+
// Build filters from conflict columns for PUT auto-conflict
|
|
225
|
+
const filters = {};
|
|
226
|
+
for (const col of conflictColumns) {
|
|
227
|
+
if (col in data) {
|
|
228
|
+
filters[col] = `eq.${data[col]}`;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const queryString = buildQueryString(filters, {
|
|
232
|
+
returning: options.returning,
|
|
233
|
+
});
|
|
234
|
+
const preferHeader = preferToHeader(options.prefer);
|
|
235
|
+
const headers = preferHeader
|
|
236
|
+
? { Prefer: preferHeader }
|
|
237
|
+
: undefined;
|
|
238
|
+
const result = wasmParseRequest("PUT", table, queryString, JSON.stringify(data), headersToJson(headers));
|
|
239
|
+
return toQueryResult(result);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Generate an UPDATE query
|
|
243
|
+
*
|
|
244
|
+
* @param table - Table name
|
|
245
|
+
* @param data - Data to update
|
|
246
|
+
* @param filters - Filter conditions to match rows
|
|
247
|
+
* @param options - Update options (returning, prefer)
|
|
248
|
+
* @returns Query result with SQL, params, and tables
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```typescript
|
|
252
|
+
* const result = client.update("users", {
|
|
253
|
+
* status: "active"
|
|
254
|
+
* }, {
|
|
255
|
+
* "id": "eq.123"
|
|
256
|
+
* }, {
|
|
257
|
+
* returning: "id,status"
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
update(table, data, filters, options = {}) {
|
|
262
|
+
const queryString = buildQueryString(filters, {
|
|
263
|
+
returning: options.returning,
|
|
264
|
+
});
|
|
265
|
+
const preferHeader = preferToHeader(options.prefer);
|
|
266
|
+
const headers = preferHeader
|
|
267
|
+
? { Prefer: preferHeader }
|
|
268
|
+
: undefined;
|
|
269
|
+
const result = wasmParseUpdate(table, JSON.stringify(data), queryString, headersToJson(headers));
|
|
270
|
+
return toQueryResult(result);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Generate a DELETE query
|
|
274
|
+
*
|
|
275
|
+
* @param table - Table name
|
|
276
|
+
* @param filters - Filter conditions to match rows to delete
|
|
277
|
+
* @param options - Delete options (returning, prefer)
|
|
278
|
+
* @returns Query result with SQL, params, and tables
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```typescript
|
|
282
|
+
* const result = client.delete("users", {
|
|
283
|
+
* "status": "eq.inactive",
|
|
284
|
+
* "last_login": "lt.2023-01-01"
|
|
285
|
+
* }, {
|
|
286
|
+
* returning: "id"
|
|
287
|
+
* });
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
delete(table, filters, options = {}) {
|
|
291
|
+
const queryString = buildQueryString(filters, {
|
|
292
|
+
returning: options.returning,
|
|
293
|
+
});
|
|
294
|
+
const preferHeader = preferToHeader(options.prefer);
|
|
295
|
+
const headers = preferHeader
|
|
296
|
+
? { Prefer: preferHeader }
|
|
297
|
+
: undefined;
|
|
298
|
+
const result = wasmParseDelete(table, queryString, headersToJson(headers));
|
|
299
|
+
return toQueryResult(result);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Generate an RPC (stored procedure/function) call
|
|
303
|
+
*
|
|
304
|
+
* @param functionName - Function name (can include schema)
|
|
305
|
+
* @param args - Function arguments as object
|
|
306
|
+
* @param options - RPC options (select, filters, ordering)
|
|
307
|
+
* @returns Query result with SQL, params, and tables
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* const result = client.rpc("calculate_total", {
|
|
312
|
+
* order_id: 123,
|
|
313
|
+
* tax_rate: 0.08
|
|
314
|
+
* }, {
|
|
315
|
+
* select: ["total", "tax"],
|
|
316
|
+
* limit: 1
|
|
317
|
+
* });
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
rpc(functionName, args = {}, options = {}) {
|
|
321
|
+
const queryString = buildQueryString(options.filters, options);
|
|
322
|
+
const result = wasmParseRpc(functionName, JSON.stringify(args), queryString || undefined, undefined);
|
|
323
|
+
return toQueryResult(result);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Parse a query string without generating SQL
|
|
327
|
+
*
|
|
328
|
+
* Useful for inspecting the parsed structure before generating SQL.
|
|
329
|
+
*
|
|
330
|
+
* @param queryString - PostgREST query string
|
|
331
|
+
* @returns Parsed query parameters as object
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* ```typescript
|
|
335
|
+
* const parsed = client.parseOnly("age=gte.18&status=eq.active&order=created_at.desc");
|
|
336
|
+
* console.log(parsed); // { filters: [...], order: [...] }
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
parseOnly(queryString) {
|
|
340
|
+
return wasmParseOnly(queryString);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Build a WHERE clause from filter conditions
|
|
344
|
+
*
|
|
345
|
+
* @param filters - Filter conditions as object
|
|
346
|
+
* @returns Object with clause (SQL string) and params (array of values)
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const filters = [
|
|
351
|
+
* { column: "age", operator: "gte", value: "18" },
|
|
352
|
+
* { column: "status", operator: "eq", value: "active" }
|
|
353
|
+
* ];
|
|
354
|
+
* const result = client.buildFilterClause(filters);
|
|
355
|
+
* console.log(result.clause); // "age >= $1 AND status = $2"
|
|
356
|
+
* console.log(result.params); // ["18", "active"]
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
buildFilterClause(filters) {
|
|
360
|
+
return wasmBuildFilterClause(filters);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Create a new PostgREST Parser client instance
|
|
365
|
+
*
|
|
366
|
+
* @returns New PostgRESTParser instance
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* import { createClient } from './pkg/client.js';
|
|
371
|
+
*
|
|
372
|
+
* const client = createClient();
|
|
373
|
+
* const result = client.select("users", { limit: 10 });
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
export function createClient() {
|
|
377
|
+
return new PostgRESTParser();
|
|
378
|
+
}
|