@exabugs/dynamodb-client 1.24.1 → 1.25.0

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/server/handler.cjs +400 -188
  3. package/dist/server/handler.cjs.map +4 -4
  4. package/dist/server/media-handler.cjs +17 -12
  5. package/dist/server/media-handler.cjs.map +3 -3
  6. package/dist/server/media-process-handler-dlq.cjs +17 -12
  7. package/dist/server/media-process-handler-dlq.cjs.map +3 -3
  8. package/dist/server/media-process-handler.cjs +17 -12
  9. package/dist/server/media-process-handler.cjs.map +3 -3
  10. package/dist/server/operations/deleteMany.d.ts.map +1 -1
  11. package/dist/server/operations/deleteMany.js +26 -2
  12. package/dist/server/operations/deleteMany.js.map +1 -1
  13. package/dist/server/operations/find/shadowQuery.d.ts.map +1 -1
  14. package/dist/server/operations/find/shadowQuery.js +59 -50
  15. package/dist/server/operations/find/shadowQuery.js.map +1 -1
  16. package/dist/server/operations/find/utils.d.ts.map +1 -1
  17. package/dist/server/operations/find/utils.js +19 -2
  18. package/dist/server/operations/find/utils.js.map +1 -1
  19. package/dist/server/operations/insertMany.d.ts.map +1 -1
  20. package/dist/server/operations/insertMany.js +36 -2
  21. package/dist/server/operations/insertMany.js.map +1 -1
  22. package/dist/server/operations/updateMany.d.ts.map +1 -1
  23. package/dist/server/operations/updateMany.js +134 -133
  24. package/dist/server/operations/updateMany.js.map +1 -1
  25. package/dist/server/utils/revision.d.ts +49 -0
  26. package/dist/server/utils/revision.d.ts.map +1 -0
  27. package/dist/server/utils/revision.js +92 -0
  28. package/dist/server/utils/revision.js.map +1 -0
  29. package/dist/server/utils/updateOperators.d.ts +25 -0
  30. package/dist/server/utils/updateOperators.d.ts.map +1 -0
  31. package/dist/server/utils/updateOperators.js +76 -0
  32. package/dist/server/utils/updateOperators.js.map +1 -0
  33. package/dist/sharp-layer.zip +0 -0
  34. package/package.json +1 -1
@@ -0,0 +1,76 @@
1
+ /**
2
+ * 更新演算子($set / $setOnInsert / $unset)の解釈
3
+ *
4
+ * 対応していない演算子($inc など)を黙って無視しない。無視すると、呼び出し側は更新できたと
5
+ * 思い込む($unset が無視され、項目を空にする操作が保存されない不具合が実際に起きた)。
6
+ */
7
+ import { AppError, ErrorCode } from '../../shared/index.js';
8
+ const SUPPORTED_OPERATORS = ['$set', '$setOnInsert', '$unset'];
9
+ function invalid(message) {
10
+ return new AppError(ErrorCode.VALIDATION_ERROR, message, 400);
11
+ }
12
+ function asObject(value, operator) {
13
+ if (value === undefined)
14
+ return {};
15
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
16
+ throw invalid(`${operator} must be an object`);
17
+ }
18
+ return value;
19
+ }
20
+ /** $unset は、項目名の配列(`['a', 'b.c']`)と、MongoDB の形(`{ a: '' }`)の両方を受ける */
21
+ function unsetFields(value) {
22
+ if (value === undefined)
23
+ return [];
24
+ if (Array.isArray(value)) {
25
+ if (!value.every((f) => typeof f === 'string')) {
26
+ throw invalid('$unset must be an array of field names or an object');
27
+ }
28
+ return value;
29
+ }
30
+ return Object.keys(asObject(value, '$unset'));
31
+ }
32
+ /**
33
+ * 更新のデータを解釈する
34
+ *
35
+ * - 演算子(`$` で始まるキー)が無ければ、全体を JSON Merge Patch として扱う
36
+ * - 演算子があれば、$set / $setOnInsert / $unset だけを受け付ける(ほかは 400)
37
+ *
38
+ * @throws AppError VALIDATION_ERROR(400)
39
+ */
40
+ export function resolveUpdateOperators(data) {
41
+ const operators = Object.keys(data).filter((key) => key.startsWith('$'));
42
+ if (operators.length === 0) {
43
+ return { patch: data, setOnInsert: {}, returned: data };
44
+ }
45
+ const unsupported = operators.filter((op) => !SUPPORTED_OPERATORS.includes(op));
46
+ if (unsupported.length > 0) {
47
+ throw invalid(`Unsupported update operator: ${unsupported.join(', ')} (supported: ${SUPPORTED_OPERATORS.join(', ')})`);
48
+ }
49
+ const set = asObject(data.$set, '$set');
50
+ const patch = { ...set };
51
+ for (const field of unsetFields(data.$unset)) {
52
+ if (field in set) {
53
+ throw invalid(`Field "${field}" is in both $set and $unset`);
54
+ }
55
+ patch[field] = null;
56
+ }
57
+ return { patch, setOnInsert: asObject(data.$setOnInsert, '$setOnInsert'), returned: set };
58
+ }
59
+ /**
60
+ * フィルタから、新規作成(upsert)のレコードに入れる値を取り出す
61
+ *
62
+ * 等値の条件(`{ field: 値 }`)だけを使う。演算子つき(`{ field: { $gte: … } }`、`'field:$in'`)は、
63
+ * 値として保存できないので使わない。
64
+ */
65
+ export function equalityFieldsOf(filter) {
66
+ const fields = {};
67
+ for (const [key, value] of Object.entries(filter)) {
68
+ if (key.includes(':') || key.startsWith('$'))
69
+ continue;
70
+ if (typeof value === 'object' && value !== null)
71
+ continue;
72
+ fields[key] = value;
73
+ }
74
+ return fields;
75
+ }
76
+ //# sourceMappingURL=updateOperators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateOperators.js","sourceRoot":"","sources":["../../../src/server/utils/updateOperators.ts"],"names":[],"mappings":"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"}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exabugs/dynamodb-client",
3
- "version": "1.24.1",
3
+ "version": "1.25.0",
4
4
  "description": "DynamoDB Single-Table Client SDK with MongoDB-like API, Shadow Records, and Lambda implementation for serverless applications",
5
5
  "author": "exabugs",
6
6
  "license": "MIT",