@exabugs/dynamodb-client 0.2.2 → 0.3.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/CHANGELOG.md +39 -0
- package/README.md +92 -28
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server/handler.cjs +137 -178
- package/dist/server/handler.cjs.map +4 -4
- package/dist/server/handler.d.ts.map +1 -1
- package/dist/server/handler.js +2 -15
- package/dist/server/handler.js.map +1 -1
- package/dist/server/operations/find.d.ts.map +1 -1
- package/dist/server/operations/find.js +5 -12
- package/dist/server/operations/find.js.map +1 -1
- package/dist/server/operations/findManyReference.d.ts.map +1 -1
- package/dist/server/operations/findManyReference.js +3 -10
- package/dist/server/operations/findManyReference.js.map +1 -1
- package/dist/server/operations/insertMany.d.ts.map +1 -1
- package/dist/server/operations/insertMany.js +3 -8
- package/dist/server/operations/insertMany.js.map +1 -1
- package/dist/server/operations/insertOne.d.ts.map +1 -1
- package/dist/server/operations/insertOne.js +3 -8
- package/dist/server/operations/insertOne.js.map +1 -1
- package/dist/server/operations/updateMany.d.ts.map +1 -1
- package/dist/server/operations/updateMany.js +3 -4
- package/dist/server/operations/updateMany.js.map +1 -1
- package/dist/server/operations/updateOne.d.ts.map +1 -1
- package/dist/server/operations/updateOne.js +3 -4
- package/dist/server/operations/updateOne.js.map +1 -1
- package/dist/server/shadow/config.d.ts +18 -112
- package/dist/server/shadow/config.d.ts.map +1 -1
- package/dist/server/shadow/config.js +33 -131
- package/dist/server/shadow/config.js.map +1 -1
- package/dist/server/shadow/generator.d.ts +92 -43
- package/dist/server/shadow/generator.d.ts.map +1 -1
- package/dist/server/shadow/generator.js +175 -56
- package/dist/server/shadow/generator.js.map +1 -1
- package/dist/server/shadow/index.d.ts +4 -3
- package/dist/server/shadow/index.d.ts.map +1 -1
- package/dist/server/shadow/index.js +4 -2
- package/dist/server/shadow/index.js.map +1 -1
- package/dist/server/shadow/typeInference.d.ts +61 -0
- package/dist/server/shadow/typeInference.d.ts.map +1 -0
- package/dist/server/shadow/typeInference.js +94 -0
- package/dist/server/shadow/typeInference.js.map +1 -0
- package/dist/server/shadow/types.d.ts +1 -1
- package/dist/server/shadow/types.d.ts.map +1 -1
- package/dist/server/utils/timestamps.d.ts.map +1 -1
- package/dist/server/utils/timestamps.js +3 -26
- package/dist/server/utils/timestamps.js.map +1 -1
- package/dist/server/utils/ttl.d.ts.map +1 -1
- package/dist/server/utils/ttl.js +11 -9
- package/dist/server/utils/ttl.js.map +1 -1
- package/dist/server/utils/validation.d.ts +14 -8
- package/dist/server/utils/validation.d.ts.map +1 -1
- package/dist/server/utils/validation.js +19 -26
- package/dist/server/utils/validation.js.map +1 -1
- package/package.json +1 -1
- package/terraform/README.md +3 -3
- package/terraform/main.tf +6 -2
- package/terraform/variables.tf +32 -2
- package/dist/scripts/generate-shadow-config.d.ts +0 -3
- package/dist/scripts/generate-shadow-config.d.ts.map +0 -1
- package/dist/scripts/generate-shadow-config.js +0 -159
- package/dist/scripts/generate-shadow-config.js.map +0 -1
package/dist/server/handler.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// @exabugs/dynamodb-client v0.
|
|
2
|
-
// Built: 2025-12-
|
|
1
|
+
// @exabugs/dynamodb-client v0.3.2
|
|
2
|
+
// Built: 2025-12-02T04:04:42.041Z
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -27446,14 +27446,6 @@ var ConfigError = class extends AppError {
|
|
|
27446
27446
|
super("CONFIG_ERROR" /* CONFIG_ERROR */, message, 500, details);
|
|
27447
27447
|
}
|
|
27448
27448
|
};
|
|
27449
|
-
var InvalidFilterError = class extends AppError {
|
|
27450
|
-
static {
|
|
27451
|
-
__name(this, "InvalidFilterError");
|
|
27452
|
-
}
|
|
27453
|
-
constructor(message, details) {
|
|
27454
|
-
super("INVALID_FILTER" /* INVALID_FILTER */, message, 400, details);
|
|
27455
|
-
}
|
|
27456
|
-
};
|
|
27457
27449
|
var InvalidTokenError = class extends AppError {
|
|
27458
27450
|
static {
|
|
27459
27451
|
__name(this, "InvalidTokenError");
|
|
@@ -27668,22 +27660,86 @@ function ulid2() {
|
|
|
27668
27660
|
}
|
|
27669
27661
|
__name(ulid2, "ulid");
|
|
27670
27662
|
|
|
27663
|
+
// src/server/shadow/typeInference.ts
|
|
27664
|
+
function inferFieldType(value) {
|
|
27665
|
+
if (value === null || value === void 0) {
|
|
27666
|
+
return null;
|
|
27667
|
+
}
|
|
27668
|
+
if (typeof value === "string") {
|
|
27669
|
+
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
|
|
27670
|
+
return "datetime";
|
|
27671
|
+
}
|
|
27672
|
+
return "string";
|
|
27673
|
+
}
|
|
27674
|
+
if (typeof value === "number") {
|
|
27675
|
+
return "number";
|
|
27676
|
+
}
|
|
27677
|
+
if (typeof value === "boolean") {
|
|
27678
|
+
return "boolean";
|
|
27679
|
+
}
|
|
27680
|
+
if (Array.isArray(value)) {
|
|
27681
|
+
return "array";
|
|
27682
|
+
}
|
|
27683
|
+
if (typeof value === "object") {
|
|
27684
|
+
return "object";
|
|
27685
|
+
}
|
|
27686
|
+
return null;
|
|
27687
|
+
}
|
|
27688
|
+
__name(inferFieldType, "inferFieldType");
|
|
27689
|
+
|
|
27671
27690
|
// src/server/shadow/generator.ts
|
|
27691
|
+
function normalizeJson(value) {
|
|
27692
|
+
if (value === null || value === void 0)
|
|
27693
|
+
return value;
|
|
27694
|
+
if (Array.isArray(value))
|
|
27695
|
+
return value.map((item) => normalizeJson(item));
|
|
27696
|
+
if (typeof value === "object") {
|
|
27697
|
+
const obj = value;
|
|
27698
|
+
const sorted = {};
|
|
27699
|
+
if ("id" in obj)
|
|
27700
|
+
sorted.id = normalizeJson(obj.id);
|
|
27701
|
+
const otherKeys = Object.keys(obj).filter((key) => key !== "id" && key !== "createdAt" && key !== "updatedAt").sort();
|
|
27702
|
+
for (const key of otherKeys) {
|
|
27703
|
+
sorted[key] = normalizeJson(obj[key]);
|
|
27704
|
+
}
|
|
27705
|
+
if ("createdAt" in obj)
|
|
27706
|
+
sorted.createdAt = normalizeJson(obj.createdAt);
|
|
27707
|
+
if ("updatedAt" in obj)
|
|
27708
|
+
sorted.updatedAt = normalizeJson(obj.updatedAt);
|
|
27709
|
+
return sorted;
|
|
27710
|
+
}
|
|
27711
|
+
return value;
|
|
27712
|
+
}
|
|
27713
|
+
__name(normalizeJson, "normalizeJson");
|
|
27714
|
+
function truncateString(value, maxBytes) {
|
|
27715
|
+
const encoder = new TextEncoder();
|
|
27716
|
+
const bytes = encoder.encode(value);
|
|
27717
|
+
if (bytes.length <= maxBytes) {
|
|
27718
|
+
return value;
|
|
27719
|
+
}
|
|
27720
|
+
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
27721
|
+
let truncated = decoder.decode(bytes.slice(0, maxBytes));
|
|
27722
|
+
truncated = truncated.replace(/[\uFFFD]$/, "");
|
|
27723
|
+
return truncated;
|
|
27724
|
+
}
|
|
27725
|
+
__name(truncateString, "truncateString");
|
|
27672
27726
|
function escapeString(value) {
|
|
27673
27727
|
return value.replace(/#/g, "##").replace(/ /g, "#");
|
|
27674
27728
|
}
|
|
27675
27729
|
__name(escapeString, "escapeString");
|
|
27676
|
-
function
|
|
27677
|
-
if (value === null || value === void 0) {
|
|
27678
|
-
return "";
|
|
27679
|
-
}
|
|
27730
|
+
function formatNumberWithOffset(value, padding) {
|
|
27680
27731
|
if (!Number.isFinite(value)) {
|
|
27681
27732
|
throw new Error(`Invalid number value: ${value}`);
|
|
27682
27733
|
}
|
|
27683
|
-
const
|
|
27684
|
-
|
|
27734
|
+
const maxValue = Math.pow(10, padding);
|
|
27735
|
+
if (value < -maxValue || value >= maxValue) {
|
|
27736
|
+
throw new Error(`Number ${value} is out of range (-10^${padding} to 10^${padding})`);
|
|
27737
|
+
}
|
|
27738
|
+
const offset = maxValue;
|
|
27739
|
+
const adjusted = Math.floor(value) + offset;
|
|
27740
|
+
return adjusted.toString().padStart(padding + 1, "0");
|
|
27685
27741
|
}
|
|
27686
|
-
__name(
|
|
27742
|
+
__name(formatNumberWithOffset, "formatNumberWithOffset");
|
|
27687
27743
|
function formatDatetime(value) {
|
|
27688
27744
|
if (value === null || value === void 0) {
|
|
27689
27745
|
return "";
|
|
@@ -27702,19 +27758,30 @@ function formatBoolean(value) {
|
|
|
27702
27758
|
return value ? "1" : "0";
|
|
27703
27759
|
}
|
|
27704
27760
|
__name(formatBoolean, "formatBoolean");
|
|
27705
|
-
function formatFieldValue(type, value) {
|
|
27761
|
+
function formatFieldValue(type, value, config) {
|
|
27706
27762
|
switch (type) {
|
|
27707
|
-
case "string":
|
|
27763
|
+
case "string": {
|
|
27708
27764
|
if (value === null || value === void 0) {
|
|
27709
27765
|
return "";
|
|
27710
27766
|
}
|
|
27711
|
-
|
|
27767
|
+
const str = String(value);
|
|
27768
|
+
const truncated = truncateString(str, config.stringMaxBytes);
|
|
27769
|
+
return escapeString(truncated);
|
|
27770
|
+
}
|
|
27712
27771
|
case "number":
|
|
27713
|
-
return
|
|
27772
|
+
return formatNumberWithOffset(value, config.numberPadding);
|
|
27714
27773
|
case "datetime":
|
|
27715
27774
|
return formatDatetime(value);
|
|
27716
27775
|
case "boolean":
|
|
27717
27776
|
return formatBoolean(value);
|
|
27777
|
+
case "array":
|
|
27778
|
+
case "object": {
|
|
27779
|
+
const normalized = normalizeJson(value);
|
|
27780
|
+
const jsonStr = JSON.stringify(normalized);
|
|
27781
|
+
const maxBytes = config.stringMaxBytes * 2;
|
|
27782
|
+
const truncated = truncateString(jsonStr, maxBytes);
|
|
27783
|
+
return escapeString(truncated);
|
|
27784
|
+
}
|
|
27718
27785
|
default:
|
|
27719
27786
|
throw new Error(`Unknown shadow field type: ${type}`);
|
|
27720
27787
|
}
|
|
@@ -27724,14 +27791,23 @@ function generateMainRecordSK(recordId) {
|
|
|
27724
27791
|
return `id#${recordId}`;
|
|
27725
27792
|
}
|
|
27726
27793
|
__name(generateMainRecordSK, "generateMainRecordSK");
|
|
27727
|
-
function generateShadowRecords(record,
|
|
27794
|
+
function generateShadowRecords(record, resourceName, config) {
|
|
27728
27795
|
const shadows = [];
|
|
27729
|
-
for (const [fieldName,
|
|
27730
|
-
|
|
27731
|
-
|
|
27732
|
-
|
|
27796
|
+
for (const [fieldName, value] of Object.entries(record)) {
|
|
27797
|
+
if (fieldName.startsWith("__")) {
|
|
27798
|
+
continue;
|
|
27799
|
+
}
|
|
27800
|
+
if (value === null || value === void 0) {
|
|
27801
|
+
continue;
|
|
27802
|
+
}
|
|
27803
|
+
const type = inferFieldType(value);
|
|
27804
|
+
if (!type) {
|
|
27805
|
+
continue;
|
|
27806
|
+
}
|
|
27807
|
+
const formattedValue = formatFieldValue(type, value, config);
|
|
27808
|
+
const sk = `${fieldName}#${formattedValue}#id#${record.id}`;
|
|
27733
27809
|
shadows.push({
|
|
27734
|
-
PK:
|
|
27810
|
+
PK: resourceName,
|
|
27735
27811
|
SK: sk,
|
|
27736
27812
|
data: { id: record.id }
|
|
27737
27813
|
});
|
|
@@ -27761,81 +27837,22 @@ __name(isDiffEmpty, "isDiffEmpty");
|
|
|
27761
27837
|
var cachedShadowConfig = null;
|
|
27762
27838
|
function getShadowConfig() {
|
|
27763
27839
|
if (!cachedShadowConfig) {
|
|
27764
|
-
|
|
27765
|
-
|
|
27766
|
-
|
|
27840
|
+
cachedShadowConfig = {
|
|
27841
|
+
createdAtField: process.env.SHADOW_CREATED_AT_FIELD || "createdAt",
|
|
27842
|
+
updatedAtField: process.env.SHADOW_UPDATED_AT_FIELD || "updatedAt",
|
|
27843
|
+
stringMaxBytes: parseInt(process.env.SHADOW_STRING_MAX_BYTES || "100", 10),
|
|
27844
|
+
numberPadding: parseInt(process.env.SHADOW_NUMBER_PADDING || "15", 10)
|
|
27845
|
+
};
|
|
27846
|
+
if (cachedShadowConfig.stringMaxBytes <= 0) {
|
|
27847
|
+
throw new Error("SHADOW_STRING_MAX_BYTES must be positive");
|
|
27767
27848
|
}
|
|
27768
|
-
|
|
27769
|
-
|
|
27770
|
-
cachedShadowConfig = JSON.parse(configJson);
|
|
27771
|
-
if (!cachedShadowConfig.$schemaVersion) {
|
|
27772
|
-
throw new Error("Missing $schemaVersion in shadow config");
|
|
27773
|
-
}
|
|
27774
|
-
if (!cachedShadowConfig.resources || typeof cachedShadowConfig.resources !== "object") {
|
|
27775
|
-
throw new Error("Missing or invalid resources in shadow config");
|
|
27776
|
-
}
|
|
27777
|
-
} catch (error2) {
|
|
27778
|
-
if (error2 instanceof SyntaxError) {
|
|
27779
|
-
throw new Error(`Invalid JSON in SHADOW_CONFIG environment variable: ${error2.message}`);
|
|
27780
|
-
}
|
|
27781
|
-
throw error2;
|
|
27849
|
+
if (cachedShadowConfig.numberPadding <= 0 || cachedShadowConfig.numberPadding > 15) {
|
|
27850
|
+
throw new Error("SHADOW_NUMBER_PADDING must be between 1 and 15");
|
|
27782
27851
|
}
|
|
27783
27852
|
}
|
|
27784
27853
|
return cachedShadowConfig;
|
|
27785
27854
|
}
|
|
27786
27855
|
__name(getShadowConfig, "getShadowConfig");
|
|
27787
|
-
function getResourceSchema(config, resourceName) {
|
|
27788
|
-
const resourceConfig = config.resources[resourceName];
|
|
27789
|
-
if (!resourceConfig) {
|
|
27790
|
-
throw new Error(`Resource '${resourceName}' not found in shadow config`);
|
|
27791
|
-
}
|
|
27792
|
-
return {
|
|
27793
|
-
resource: resourceName,
|
|
27794
|
-
sortableFields: resourceConfig.shadows
|
|
27795
|
-
};
|
|
27796
|
-
}
|
|
27797
|
-
__name(getResourceSchema, "getResourceSchema");
|
|
27798
|
-
function getShadowConfigHash() {
|
|
27799
|
-
getShadowConfig();
|
|
27800
|
-
const configBase64 = process.env.SHADOW_CONFIG;
|
|
27801
|
-
if (!configBase64) {
|
|
27802
|
-
throw new Error("SHADOW_CONFIG environment variable is not set");
|
|
27803
|
-
}
|
|
27804
|
-
const crypto3 = require("crypto");
|
|
27805
|
-
const hash = crypto3.createHash("sha256").update(configBase64).digest("hex");
|
|
27806
|
-
return hash;
|
|
27807
|
-
}
|
|
27808
|
-
__name(getShadowConfigHash, "getShadowConfigHash");
|
|
27809
|
-
function getSchemaVersion() {
|
|
27810
|
-
const config = getShadowConfig();
|
|
27811
|
-
return config.$schemaVersion;
|
|
27812
|
-
}
|
|
27813
|
-
__name(getSchemaVersion, "getSchemaVersion");
|
|
27814
|
-
function getAllShadowFields(config, resourceName) {
|
|
27815
|
-
const resourceConfig = config.resources[resourceName];
|
|
27816
|
-
if (!resourceConfig) {
|
|
27817
|
-
throw new Error(`Resource '${resourceName}' not found in shadow config`);
|
|
27818
|
-
}
|
|
27819
|
-
return resourceConfig.shadows;
|
|
27820
|
-
}
|
|
27821
|
-
__name(getAllShadowFields, "getAllShadowFields");
|
|
27822
|
-
function isValidShadowField(config, resourceName, fieldName) {
|
|
27823
|
-
try {
|
|
27824
|
-
const allFields = getAllShadowFields(config, resourceName);
|
|
27825
|
-
return fieldName in allFields;
|
|
27826
|
-
} catch {
|
|
27827
|
-
return false;
|
|
27828
|
-
}
|
|
27829
|
-
}
|
|
27830
|
-
__name(isValidShadowField, "isValidShadowField");
|
|
27831
|
-
function getDefaultSort(config, resourceName) {
|
|
27832
|
-
const resourceConfig = config.resources[resourceName];
|
|
27833
|
-
if (!resourceConfig) {
|
|
27834
|
-
throw new Error(`Resource '${resourceName}' not found in shadow config`);
|
|
27835
|
-
}
|
|
27836
|
-
return resourceConfig.sortDefaults;
|
|
27837
|
-
}
|
|
27838
|
-
__name(getDefaultSort, "getDefaultSort");
|
|
27839
27856
|
|
|
27840
27857
|
// src/server/utils/bulkOperations.ts
|
|
27841
27858
|
var logger2 = createLogger({ service: "records-lambda" });
|
|
@@ -28513,17 +28530,8 @@ function decodeNextToken(token) {
|
|
|
28513
28530
|
__name(decodeNextToken, "decodeNextToken");
|
|
28514
28531
|
|
|
28515
28532
|
// src/server/utils/validation.ts
|
|
28516
|
-
function validateSortField(
|
|
28517
|
-
|
|
28518
|
-
return;
|
|
28519
|
-
}
|
|
28520
|
-
const { field } = sort;
|
|
28521
|
-
if (field === "id") {
|
|
28522
|
-
return;
|
|
28523
|
-
}
|
|
28524
|
-
if (!isValidShadowField(config, resource, field)) {
|
|
28525
|
-
throw new InvalidFilterError(`Invalid sort field: ${field}`, { field, resource });
|
|
28526
|
-
}
|
|
28533
|
+
function validateSortField(_config, _resource, _sort) {
|
|
28534
|
+
return;
|
|
28527
28535
|
}
|
|
28528
28536
|
__name(validateSortField, "validateSortField");
|
|
28529
28537
|
function normalizePagination(pagination) {
|
|
@@ -28532,11 +28540,14 @@ function normalizePagination(pagination) {
|
|
|
28532
28540
|
return { perPage, nextToken };
|
|
28533
28541
|
}
|
|
28534
28542
|
__name(normalizePagination, "normalizePagination");
|
|
28535
|
-
function normalizeSort(config,
|
|
28543
|
+
function normalizeSort(config, _resource, sort) {
|
|
28536
28544
|
if (sort) {
|
|
28537
28545
|
return sort;
|
|
28538
28546
|
}
|
|
28539
|
-
return
|
|
28547
|
+
return {
|
|
28548
|
+
field: config.updatedAtField,
|
|
28549
|
+
order: "DESC"
|
|
28550
|
+
};
|
|
28540
28551
|
}
|
|
28541
28552
|
__name(normalizeSort, "normalizeSort");
|
|
28542
28553
|
|
|
@@ -28552,8 +28563,8 @@ async function handleFind(resource, params, requestId) {
|
|
|
28552
28563
|
logger7.debug("Shadow config loaded", {
|
|
28553
28564
|
requestId,
|
|
28554
28565
|
resource,
|
|
28555
|
-
|
|
28556
|
-
|
|
28566
|
+
createdAtField: shadowConfig.createdAtField,
|
|
28567
|
+
updatedAtField: shadowConfig.updatedAtField
|
|
28557
28568
|
});
|
|
28558
28569
|
logger7.debug("Normalizing sort", {
|
|
28559
28570
|
requestId,
|
|
@@ -28683,14 +28694,6 @@ async function handleFind(resource, params, requestId) {
|
|
|
28683
28694
|
...nextTokenValue2 && { nextToken: nextTokenValue2 }
|
|
28684
28695
|
};
|
|
28685
28696
|
}
|
|
28686
|
-
const shadowSchema = getResourceSchema(shadowConfig, resource);
|
|
28687
|
-
const sortFieldType = shadowSchema.sortableFields[sort.field]?.type;
|
|
28688
|
-
if (!sortFieldType) {
|
|
28689
|
-
throw new ConfigError(`Sort field type not found: ${sort.field}`, {
|
|
28690
|
-
field: sort.field,
|
|
28691
|
-
resource
|
|
28692
|
-
});
|
|
28693
|
-
}
|
|
28694
28697
|
const optimizableFilter = findOptimizableFilter(sort.field, parsedFilters);
|
|
28695
28698
|
const skPrefix = `${sort.field}#`;
|
|
28696
28699
|
let exclusiveStartKey;
|
|
@@ -28916,14 +28919,6 @@ async function handleFindManyReference(resource, params, requestId) {
|
|
|
28916
28919
|
const { perPage, nextToken } = normalizePagination(pagination);
|
|
28917
28920
|
const dbClient2 = getDBClient();
|
|
28918
28921
|
const tableName = getTableName();
|
|
28919
|
-
const shadowSchema = getResourceSchema(shadowConfig, resource);
|
|
28920
|
-
const sortFieldType = shadowSchema.sortableFields[sort.field]?.type;
|
|
28921
|
-
if (!sortFieldType) {
|
|
28922
|
-
throw new ConfigError(`Sort field type not found: ${sort.field}`, {
|
|
28923
|
-
field: sort.field,
|
|
28924
|
-
resource
|
|
28925
|
-
});
|
|
28926
|
-
}
|
|
28927
28922
|
const skPrefix = `${sort.field}#`;
|
|
28928
28923
|
let exclusiveStartKey;
|
|
28929
28924
|
if (nextToken) {
|
|
@@ -29066,28 +29061,9 @@ var import_lib_dynamodb8 = __toESM(require_dist_cjs58(), 1);
|
|
|
29066
29061
|
// src/server/utils/timestamps.ts
|
|
29067
29062
|
function getTimestampFields() {
|
|
29068
29063
|
const shadowConfig = getShadowConfig();
|
|
29069
|
-
if (!shadowConfig.database) {
|
|
29070
|
-
return {
|
|
29071
|
-
createdAt: "createdAt",
|
|
29072
|
-
updatedAt: "updatedAt"
|
|
29073
|
-
};
|
|
29074
|
-
}
|
|
29075
|
-
const { timestamps } = shadowConfig.database;
|
|
29076
|
-
if (!timestamps) {
|
|
29077
|
-
return {
|
|
29078
|
-
createdAt: "createdAt",
|
|
29079
|
-
updatedAt: "updatedAt"
|
|
29080
|
-
};
|
|
29081
|
-
}
|
|
29082
|
-
if (typeof timestamps === "object") {
|
|
29083
|
-
return {
|
|
29084
|
-
createdAt: timestamps.createdAt,
|
|
29085
|
-
updatedAt: timestamps.updatedAt
|
|
29086
|
-
};
|
|
29087
|
-
}
|
|
29088
29064
|
return {
|
|
29089
|
-
createdAt:
|
|
29090
|
-
updatedAt:
|
|
29065
|
+
createdAt: shadowConfig.createdAtField,
|
|
29066
|
+
updatedAt: shadowConfig.updatedAtField
|
|
29091
29067
|
};
|
|
29092
29068
|
}
|
|
29093
29069
|
__name(getTimestampFields, "getTimestampFields");
|
|
@@ -29120,14 +29096,16 @@ __name(addUpdateTimestamp, "addUpdateTimestamp");
|
|
|
29120
29096
|
// src/server/utils/ttl.ts
|
|
29121
29097
|
var logger11 = createLogger({ service: "records-lambda" });
|
|
29122
29098
|
function calculateTTL(resource, createdAt) {
|
|
29123
|
-
const
|
|
29124
|
-
const
|
|
29125
|
-
if (!
|
|
29099
|
+
const envKey = `${resource.toUpperCase()}_TTL_DAYS`;
|
|
29100
|
+
const ttlDaysStr = process.env[envKey];
|
|
29101
|
+
if (!ttlDaysStr) {
|
|
29102
|
+
return void 0;
|
|
29103
|
+
}
|
|
29104
|
+
const ttlDays = parseInt(ttlDaysStr, 10);
|
|
29105
|
+
if (isNaN(ttlDays) || ttlDays <= 0) {
|
|
29106
|
+
logger11.warn("Invalid TTL_DAYS value", { resource, envKey, value: ttlDaysStr });
|
|
29126
29107
|
return void 0;
|
|
29127
29108
|
}
|
|
29128
|
-
const defaultDays = resourceConfig.ttl.days;
|
|
29129
|
-
const envKey = `${resource.toUpperCase()}_TTL_DAYS`;
|
|
29130
|
-
const ttlDays = parseInt(process.env[envKey] || String(defaultDays), 10);
|
|
29131
29109
|
const createdAtMs = new Date(createdAt).getTime();
|
|
29132
29110
|
const ttlMs = createdAtMs + ttlDays * 24 * 60 * 60 * 1e3;
|
|
29133
29111
|
const ttl = Math.floor(ttlMs / 1e3);
|
|
@@ -29180,7 +29158,6 @@ async function handleInsertMany(resource, params, requestId) {
|
|
|
29180
29158
|
const dbClient2 = getDBClient();
|
|
29181
29159
|
const tableName = getTableName();
|
|
29182
29160
|
const shadowConfig = getShadowConfig();
|
|
29183
|
-
const shadowSchema = getResourceSchema(shadowConfig, resource);
|
|
29184
29161
|
const preparedRecords = [];
|
|
29185
29162
|
const preparationFailedIds = [];
|
|
29186
29163
|
const preparationErrors = [];
|
|
@@ -29193,9 +29170,7 @@ async function handleInsertMany(resource, params, requestId) {
|
|
|
29193
29170
|
id
|
|
29194
29171
|
});
|
|
29195
29172
|
fullRecordData = addTTL(resource, fullRecordData);
|
|
29196
|
-
|
|
29197
|
-
fullRecordData.__configHash = getShadowConfigHash();
|
|
29198
|
-
const shadowRecords = generateShadowRecords(fullRecordData, shadowSchema);
|
|
29173
|
+
const shadowRecords = generateShadowRecords(fullRecordData, resource, shadowConfig);
|
|
29199
29174
|
const shadowKeys = shadowRecords.map((shadow) => shadow.SK);
|
|
29200
29175
|
const mainSK = generateMainRecordSK(id);
|
|
29201
29176
|
preparedRecords.push({
|
|
@@ -29383,11 +29358,8 @@ async function handleInsertOne(resource, params, requestId) {
|
|
|
29383
29358
|
id
|
|
29384
29359
|
});
|
|
29385
29360
|
recordData = addTTL(resource, recordData);
|
|
29386
|
-
recordData.__configVersion = getSchemaVersion();
|
|
29387
|
-
recordData.__configHash = getShadowConfigHash();
|
|
29388
29361
|
const shadowConfig = getShadowConfig();
|
|
29389
|
-
const
|
|
29390
|
-
const shadowRecords = generateShadowRecords(recordData, shadowSchema);
|
|
29362
|
+
const shadowRecords = generateShadowRecords(recordData, resource, shadowConfig);
|
|
29391
29363
|
const shadowKeys = shadowRecords.map((shadow) => shadow.SK);
|
|
29392
29364
|
const mainSK = generateMainRecordSK(id);
|
|
29393
29365
|
await executeDynamoDBOperation(
|
|
@@ -29492,7 +29464,6 @@ async function handleUpdateMany(resource, params, requestId) {
|
|
|
29492
29464
|
);
|
|
29493
29465
|
const notFoundIds = ids.filter((id) => !existingIds.has(id));
|
|
29494
29466
|
const shadowConfig = getShadowConfig();
|
|
29495
|
-
const shadowSchema = getResourceSchema(shadowConfig, resource);
|
|
29496
29467
|
const preparedRecords = [];
|
|
29497
29468
|
const preparationFailedIds = [];
|
|
29498
29469
|
const preparationErrors = [];
|
|
@@ -29506,7 +29477,7 @@ async function handleUpdateMany(resource, params, requestId) {
|
|
|
29506
29477
|
...mergedData,
|
|
29507
29478
|
id
|
|
29508
29479
|
});
|
|
29509
|
-
const newShadowRecords = generateShadowRecords(updatedData,
|
|
29480
|
+
const newShadowRecords = generateShadowRecords(updatedData, resource, shadowConfig);
|
|
29510
29481
|
const newShadowKeys = newShadowRecords.map((shadow) => shadow.SK);
|
|
29511
29482
|
const mainSK = generateMainRecordSK(id);
|
|
29512
29483
|
preparedRecords.push({
|
|
@@ -29759,8 +29730,7 @@ async function handleUpdateOne(resource, params, requestId) {
|
|
|
29759
29730
|
// IDは変更不可
|
|
29760
29731
|
});
|
|
29761
29732
|
const shadowConfig = getShadowConfig();
|
|
29762
|
-
const
|
|
29763
|
-
const newShadowRecords = generateShadowRecords(updatedData, shadowSchema);
|
|
29733
|
+
const newShadowRecords = generateShadowRecords(updatedData, resource, shadowConfig);
|
|
29764
29734
|
const newShadowKeys = newShadowRecords.map((shadow) => shadow.SK);
|
|
29765
29735
|
const shadowDiff = calculateShadowDiff(oldShadowKeys, newShadowKeys);
|
|
29766
29736
|
const transactItems = [];
|
|
@@ -31056,18 +31026,7 @@ var logger17 = createLogger({
|
|
|
31056
31026
|
service: "records-lambda",
|
|
31057
31027
|
level: process.env.LOG_LEVEL || "info"
|
|
31058
31028
|
});
|
|
31059
|
-
|
|
31060
|
-
const schemaVersion = getSchemaVersion();
|
|
31061
|
-
const configHash = getShadowConfigHash();
|
|
31062
|
-
logger17.info("Records Lambda started", {
|
|
31063
|
-
schemaVersion,
|
|
31064
|
-
configHash
|
|
31065
|
-
});
|
|
31066
|
-
} catch (error2) {
|
|
31067
|
-
logger17.warn("Failed to load shadow config at startup", {
|
|
31068
|
-
error: error2 instanceof Error ? error2.message : String(error2)
|
|
31069
|
-
});
|
|
31070
|
-
}
|
|
31029
|
+
logger17.info("Records Lambda started with automatic shadow field detection");
|
|
31071
31030
|
var CORS_HEADERS = {};
|
|
31072
31031
|
async function handler(event) {
|
|
31073
31032
|
const requestId = event.requestContext.requestId;
|