supalite 0.5.6 → 0.5.7
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/CHANGELOG.md +4 -1
- package/README.md +1 -1
- package/dist/query-builder.d.ts +3 -1
- package/dist/query-builder.js +40 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.5.
|
|
3
|
+
## [0.5.7] - 2026-01-14
|
|
4
|
+
|
|
5
|
+
### ✨ Added
|
|
6
|
+
- `upsert()`에 `onConflict` 다중 컬럼 지정 지원을 추가했습니다. 이제 콤마 구분 문자열 또는 문자열 배열을 사용할 수 있습니다. (예: `'set_id, name'`, `['set_id', 'name']`)
|
|
4
7
|
|
|
5
8
|
### 🐞 Fixed
|
|
6
9
|
- `select()`의 PostgREST-style embed(`related_table(*)`)가 **양방향 FK**를 지원하도록 개선했습니다. 이제 1:N 관계는 배열(`[]` 기본값), N:1 관계는 객체(또는 `null`)로 반환합니다. (See [docs/changelog/2025-12-17-embed-many-to-one.md](docs/changelog/2025-12-17-embed-many-to-one.md))
|
package/README.md
CHANGED
|
@@ -285,7 +285,7 @@ const { data, error } = await client
|
|
|
285
285
|
- `insert(data: T['Tables'][K]['Insert'] | T['Tables'][K]['Insert'][])`: 단일 또는 다중 레코드 삽입
|
|
286
286
|
- `update(data: T['Tables'][K]['Update'])`: 레코드 업데이트
|
|
287
287
|
- `delete()`: 레코드 삭제
|
|
288
|
-
- `upsert(data: T['Tables'][K]['Insert'], options?: { onConflict: string })`: 삽입 또는 업데이트
|
|
288
|
+
- `upsert(data: T['Tables'][K]['Insert'], options?: { onConflict: string | string[] })`: 삽입 또는 업데이트
|
|
289
289
|
|
|
290
290
|
### 필터 메소드
|
|
291
291
|
|
package/dist/query-builder.d.ts
CHANGED
|
@@ -57,8 +57,10 @@ export declare class QueryBuilder<T extends DatabaseSchema, S extends SchemaName
|
|
|
57
57
|
returns<NewS extends SchemaName<T>, NewK extends TableName<T, NewS>>(): QueryBuilder<T, NewS, NewK>;
|
|
58
58
|
range(from: number, to: number): this;
|
|
59
59
|
upsert(values: InsertRow<T, S, K>, options?: {
|
|
60
|
-
onConflict: string;
|
|
60
|
+
onConflict: string | string[];
|
|
61
61
|
}): this;
|
|
62
|
+
private formatConflictTarget;
|
|
63
|
+
private quoteConflictTargetColumn;
|
|
62
64
|
private shouldReturnData;
|
|
63
65
|
private buildWhereClause;
|
|
64
66
|
private buildQuery;
|
package/dist/query-builder.js
CHANGED
|
@@ -234,6 +234,39 @@ class QueryBuilder {
|
|
|
234
234
|
this.conflictTarget = options?.onConflict;
|
|
235
235
|
return this;
|
|
236
236
|
}
|
|
237
|
+
formatConflictTarget(target) {
|
|
238
|
+
if (Array.isArray(target)) {
|
|
239
|
+
return target
|
|
240
|
+
.map((column) => this.quoteConflictTargetColumn(column))
|
|
241
|
+
.filter(Boolean)
|
|
242
|
+
.join(', ');
|
|
243
|
+
}
|
|
244
|
+
const trimmedTarget = target.trim();
|
|
245
|
+
if (!trimmedTarget) {
|
|
246
|
+
return trimmedTarget;
|
|
247
|
+
}
|
|
248
|
+
if (trimmedTarget.includes('"') || trimmedTarget.includes('(') || trimmedTarget.includes(')')) {
|
|
249
|
+
return trimmedTarget;
|
|
250
|
+
}
|
|
251
|
+
if (trimmedTarget.includes(',')) {
|
|
252
|
+
return trimmedTarget
|
|
253
|
+
.split(',')
|
|
254
|
+
.map((column) => this.quoteConflictTargetColumn(column))
|
|
255
|
+
.filter(Boolean)
|
|
256
|
+
.join(', ');
|
|
257
|
+
}
|
|
258
|
+
return this.quoteConflictTargetColumn(trimmedTarget);
|
|
259
|
+
}
|
|
260
|
+
quoteConflictTargetColumn(column) {
|
|
261
|
+
const trimmedColumn = column.trim();
|
|
262
|
+
if (!trimmedColumn) {
|
|
263
|
+
return trimmedColumn;
|
|
264
|
+
}
|
|
265
|
+
if (trimmedColumn.startsWith('"') && trimmedColumn.endsWith('"')) {
|
|
266
|
+
return trimmedColumn;
|
|
267
|
+
}
|
|
268
|
+
return `"${trimmedColumn}"`;
|
|
269
|
+
}
|
|
237
270
|
shouldReturnData() {
|
|
238
271
|
return this.selectColumns !== null;
|
|
239
272
|
}
|
|
@@ -367,14 +400,13 @@ class QueryBuilder {
|
|
|
367
400
|
query = `INSERT INTO ${schemaTable} ("${insertColumns.join('","')}") VALUES (${insertPlaceholders})`;
|
|
368
401
|
}
|
|
369
402
|
if (this.queryType === 'UPSERT' && this.conflictTarget) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
.join(', ');
|
|
403
|
+
const conflictTargetSQL = this.formatConflictTarget(this.conflictTarget);
|
|
404
|
+
if (conflictTargetSQL) {
|
|
405
|
+
query += ` ON CONFLICT (${conflictTargetSQL}) DO UPDATE SET `;
|
|
406
|
+
query += insertColumns
|
|
407
|
+
.map((col) => `"${col}" = EXCLUDED."${col}"`)
|
|
408
|
+
.join(', ');
|
|
409
|
+
}
|
|
378
410
|
}
|
|
379
411
|
query += returning;
|
|
380
412
|
break;
|