@electric-sql/client 1.2.1 → 1.2.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/dist/cjs/index.cjs +22 -5
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.legacy-esm.js +22 -5
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +22 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +26 -3
- package/src/column-mapper.ts +25 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electric-sql/client",
|
|
3
3
|
"description": "Postgres everywhere - your data, in sync, wherever you need it.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"author": "ElectricSQL team and contributors.",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/electric-sql/electric/issues"
|
package/src/client.ts
CHANGED
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
SnapshotMetadata,
|
|
10
10
|
} from './types'
|
|
11
11
|
import { MessageParser, Parser, TransformFunction } from './parser'
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
ColumnMapper,
|
|
14
|
+
encodeWhereClause,
|
|
15
|
+
quoteIdentifier,
|
|
16
|
+
} from './column-mapper'
|
|
13
17
|
import { getOffset, isUpToDateMessage, isChangeMessage } from './helpers'
|
|
14
18
|
import {
|
|
15
19
|
FetchError,
|
|
@@ -855,8 +859,27 @@ export class ShapeStream<T extends Row<unknown> = Row>
|
|
|
855
859
|
)
|
|
856
860
|
setQueryParam(fetchUrl, WHERE_QUERY_PARAM, encodedWhere)
|
|
857
861
|
}
|
|
858
|
-
if (params.columns)
|
|
859
|
-
|
|
862
|
+
if (params.columns) {
|
|
863
|
+
// Get original columns array from options (before toInternalParams converted to string)
|
|
864
|
+
const originalColumns = await resolveValue(this.options.params?.columns)
|
|
865
|
+
if (Array.isArray(originalColumns)) {
|
|
866
|
+
// Apply columnMapper encoding if present
|
|
867
|
+
let encodedColumns = originalColumns.map(String)
|
|
868
|
+
if (this.options.columnMapper) {
|
|
869
|
+
encodedColumns = encodedColumns.map(
|
|
870
|
+
this.options.columnMapper.encode
|
|
871
|
+
)
|
|
872
|
+
}
|
|
873
|
+
// Quote each column name to handle special characters (commas, etc.)
|
|
874
|
+
const serializedColumns = encodedColumns
|
|
875
|
+
.map(quoteIdentifier)
|
|
876
|
+
.join(`,`)
|
|
877
|
+
setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, serializedColumns)
|
|
878
|
+
} else {
|
|
879
|
+
// Fallback: columns was already a string
|
|
880
|
+
setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, params.columns)
|
|
881
|
+
}
|
|
882
|
+
}
|
|
860
883
|
if (params.replica) setQueryParam(fetchUrl, REPLICA_PARAM, params.replica)
|
|
861
884
|
if (params.params)
|
|
862
885
|
setQueryParam(fetchUrl, WHERE_PARAMS_PARAM, params.params)
|
package/src/column-mapper.ts
CHANGED
|
@@ -3,6 +3,31 @@ import { Schema } from './types'
|
|
|
3
3
|
type DbColumnName = string
|
|
4
4
|
type AppColumnName = string
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Quote a PostgreSQL identifier for safe use in query parameters.
|
|
8
|
+
*
|
|
9
|
+
* Wraps the identifier in double quotes and escapes any internal
|
|
10
|
+
* double quotes by doubling them. This ensures identifiers with
|
|
11
|
+
* special characters (commas, spaces, etc.) are handled correctly.
|
|
12
|
+
*
|
|
13
|
+
* @param identifier - The identifier to quote
|
|
14
|
+
* @returns The quoted identifier
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* quoteIdentifier('user_id') // '"user_id"'
|
|
19
|
+
* quoteIdentifier('foo,bar') // '"foo,bar"'
|
|
20
|
+
* quoteIdentifier('has"quote') // '"has""quote"'
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export function quoteIdentifier(identifier: string): string {
|
|
26
|
+
// Escape internal double quotes by doubling them
|
|
27
|
+
const escaped = identifier.replace(/"/g, `""`)
|
|
28
|
+
return `"${escaped}"`
|
|
29
|
+
}
|
|
30
|
+
|
|
6
31
|
/**
|
|
7
32
|
* A bidirectional column mapper that handles transforming column **names**
|
|
8
33
|
* between database format (e.g., snake_case) and application format (e.g., camelCase).
|