@exabugs/dynamodb-client 1.3.20 → 1.3.22
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 +46 -0
- package/dist/server/handler.cjs +29 -20
- package/dist/server/handler.cjs.map +2 -2
- package/dist/server/operations/updateMany.d.ts.map +1 -1
- package/dist/server/operations/updateMany.js +6 -2
- package/dist/server/operations/updateMany.js.map +1 -1
- package/dist/server/operations/updateOne.js +24 -12
- package/dist/server/operations/updateOne.js.map +1 -1
- package/dist/server/shadow/generator.d.ts.map +1 -1
- package/dist/server/shadow/generator.js +17 -11
- package/dist/server/shadow/generator.js.map +1 -1
- package/dist/server/shadow/typeInference.d.ts.map +1 -1
- package/dist/server/shadow/typeInference.js +3 -2
- package/dist/server/shadow/typeInference.js.map +1 -1
- package/dist/shared/types/index.d.ts +2 -0
- package/dist/shared/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,52 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.22] - 2026-01-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **$setOnInsert オペレータ**: MongoDB互換のupsert専用フィールド設定機能
|
|
15
|
+
- upsert時のinsert専用フィールドを指定可能(`$setOnInsert`)
|
|
16
|
+
- update時は`$setOnInsert`が無視され、`$set`のみが適用される
|
|
17
|
+
- `$set`と`$setOnInsert`で同じフィールドを指定した場合、`$set`が優先
|
|
18
|
+
- タイムスタンプ管理(`createdAt`は初回のみ、`updatedAt`は常に更新)が明確に
|
|
19
|
+
- MongoDB公式ドキュメントと完全互換
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **UpdateOperators型**: `$setOnInsert?: Partial<T>` フィールドを追加
|
|
24
|
+
- **handleUpsertCreate**: `$set`と`$setOnInsert`をマージして新規作成(`$set`が優先)
|
|
25
|
+
- **handleUpsertUpdate**: `$setOnInsert`を無視して`$set`のみを適用
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
|
|
29
|
+
- **API.md**: `$setOnInsert`オペレータの詳細な説明を追加
|
|
30
|
+
- 動作仕様(insert時/update時の挙動)
|
|
31
|
+
- 使用例とコードスニペット
|
|
32
|
+
- MongoDB互換性の説明
|
|
33
|
+
- ユースケース(タイムスタンプ管理、デフォルト値設定、初期ステータス)
|
|
34
|
+
|
|
35
|
+
### Technical
|
|
36
|
+
|
|
37
|
+
- **テスト**: 包括的なテストカバレッジ(単体テスト・統合テスト)
|
|
38
|
+
- insert時に`$set`と`$setOnInsert`の両方を適用するテスト
|
|
39
|
+
- update時に`$setOnInsert`を無視するテスト
|
|
40
|
+
- `$set`が`$setOnInsert`より優先されるテスト
|
|
41
|
+
- `createdAt`の保持テスト
|
|
42
|
+
- シャドウレコード生成の確認
|
|
43
|
+
- 後方互換性テスト(従来のパッチ形式)
|
|
44
|
+
|
|
45
|
+
## [1.3.21] - 2026-01-04
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- **Shadow仕様変更**: オブジェクト型はシャドウを作成しない仕様に変更
|
|
50
|
+
- `inferFieldType`: オブジェクト型に対して`null`を返すように変更
|
|
51
|
+
- `generateShadowRecords`: オブジェクト型を明示的にスキップ
|
|
52
|
+
- `formatFieldValue`: `object`型のケースを削除
|
|
53
|
+
- 理由: オブジェクトは構造が複雑で、シャドウキーとして適切でない
|
|
54
|
+
- 例外: GeoCoordinates型(`{latitude, longitude}`)は地理空間検索用にGeoHashシャドウを生成
|
|
55
|
+
|
|
10
56
|
## [1.3.20] - 2026-01-03
|
|
11
57
|
|
|
12
58
|
### Added
|
package/dist/server/handler.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// @exabugs/dynamodb-client v1.3.
|
|
2
|
-
// Built: 2026-01-
|
|
1
|
+
// @exabugs/dynamodb-client v1.3.22
|
|
2
|
+
// Built: 2026-01-05T00:55:07.904Z
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -29373,7 +29373,7 @@ function inferFieldType(value) {
|
|
|
29373
29373
|
return "array";
|
|
29374
29374
|
}
|
|
29375
29375
|
if (typeof value === "object") {
|
|
29376
|
-
return
|
|
29376
|
+
return null;
|
|
29377
29377
|
}
|
|
29378
29378
|
return null;
|
|
29379
29379
|
}
|
|
@@ -29451,8 +29451,7 @@ function formatFieldValue2(type, value, config) {
|
|
|
29451
29451
|
return formatDatetime2(value);
|
|
29452
29452
|
case "boolean":
|
|
29453
29453
|
return formatBoolean2(value);
|
|
29454
|
-
case "array":
|
|
29455
|
-
case "object": {
|
|
29454
|
+
case "array": {
|
|
29456
29455
|
const normalized = normalizeJson(value);
|
|
29457
29456
|
const jsonStr = JSON.stringify(normalized);
|
|
29458
29457
|
const maxBytes = config.stringMaxBytes * 2;
|
|
@@ -29480,17 +29479,19 @@ function generateShadowRecords(record, resourceName, config) {
|
|
|
29480
29479
|
if (value === null || value === void 0) {
|
|
29481
29480
|
continue;
|
|
29482
29481
|
}
|
|
29483
|
-
if (
|
|
29484
|
-
|
|
29485
|
-
|
|
29486
|
-
|
|
29487
|
-
|
|
29488
|
-
|
|
29489
|
-
|
|
29490
|
-
|
|
29491
|
-
|
|
29492
|
-
|
|
29493
|
-
|
|
29482
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
29483
|
+
if (isGeoCoordinates(value)) {
|
|
29484
|
+
const geohash = encodeGeoHash(
|
|
29485
|
+
value.latitude,
|
|
29486
|
+
value.longitude,
|
|
29487
|
+
DEFAULT_GEOHASH_CONFIG.shadowPrecision
|
|
29488
|
+
);
|
|
29489
|
+
const sk2 = `${fieldName}#${geohash}#id#${record.id}`;
|
|
29490
|
+
shadows.push({
|
|
29491
|
+
PK: resourceName,
|
|
29492
|
+
SK: sk2
|
|
29493
|
+
});
|
|
29494
|
+
}
|
|
29494
29495
|
continue;
|
|
29495
29496
|
}
|
|
29496
29497
|
const type = inferFieldType(value);
|
|
@@ -31503,7 +31504,8 @@ async function handleUpdateMany(resource, params, requestId) {
|
|
|
31503
31504
|
const existingData = item.data;
|
|
31504
31505
|
const id = existingData.id;
|
|
31505
31506
|
const oldShadowKeys = existingData.__shadowKeys || [];
|
|
31506
|
-
const
|
|
31507
|
+
const actualPatchData = patchData.$set ? patchData.$set : patchData;
|
|
31508
|
+
const mergedData = applyJsonMergePatch(removeShadowKeys(existingData), actualPatchData);
|
|
31507
31509
|
const updatedData = addUpdateTimestamp({
|
|
31508
31510
|
...mergedData,
|
|
31509
31511
|
id
|
|
@@ -31761,7 +31763,13 @@ async function handleUpdateOne(resource, params, requestId) {
|
|
|
31761
31763
|
}
|
|
31762
31764
|
__name(handleUpdateOne, "handleUpdateOne");
|
|
31763
31765
|
async function handleUpsertCreate(resource, id, data2, requestId) {
|
|
31764
|
-
const
|
|
31766
|
+
const $set = data2.$set || {};
|
|
31767
|
+
const $setOnInsert = data2.$setOnInsert || {};
|
|
31768
|
+
const mergedData = {
|
|
31769
|
+
...$setOnInsert,
|
|
31770
|
+
...$set
|
|
31771
|
+
};
|
|
31772
|
+
const recordData = addCreateTimestamps({ ...mergedData, id });
|
|
31765
31773
|
const shadowConfig = getShadowConfig();
|
|
31766
31774
|
const shadowRecords = generateShadowRecords(recordData, resource, shadowConfig);
|
|
31767
31775
|
const shadowKeys = shadowRecords.map((shadow) => shadow.SK);
|
|
@@ -31810,7 +31818,8 @@ __name(handleUpsertCreate, "handleUpsertCreate");
|
|
|
31810
31818
|
async function handleUpsertUpdate(resource, id, existingItem, patchData, requestId) {
|
|
31811
31819
|
const existingData = existingItem.data;
|
|
31812
31820
|
const oldShadowKeys = existingData.__shadowKeys || [];
|
|
31813
|
-
const
|
|
31821
|
+
const actualPatchData = patchData.$set ? patchData.$set : patchData;
|
|
31822
|
+
const mergedData = applyJsonMergePatch2(removeShadowKeys(existingData), actualPatchData);
|
|
31814
31823
|
const updatedData = addUpdateTimestamp({
|
|
31815
31824
|
...mergedData,
|
|
31816
31825
|
id
|
|
@@ -33458,7 +33467,7 @@ async function handler(event) {
|
|
|
33458
33467
|
return createCorsResponse(HTTP_STATUS.OK);
|
|
33459
33468
|
}
|
|
33460
33469
|
if (event.requestContext.http.method === "GET" && event.requestContext.http.path === "/version") {
|
|
33461
|
-
const version = "1.3.
|
|
33470
|
+
const version = "1.3.22";
|
|
33462
33471
|
return createSuccessResponse({ version, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, requestId);
|
|
33463
33472
|
}
|
|
33464
33473
|
if (event.requestContext.http.method !== "POST") {
|